Skip to content

Instantly share code, notes, and snippets.

@seinosuke
Last active March 19, 2016 06:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seinosuke/9e615852063807427dab to your computer and use it in GitHub Desktop.
Save seinosuke/9e615852063807427dab to your computer and use it in GitHub Desktop.
Ruby GTK 警告ウィンドウ
require 'gtk2'
include Math
WIDTH = 1280 # 画面の幅
HEIGHT = 800 # 画面の高さ
MAX = 30 # 表示するウィンドウの数
# 使用する色
COLOR_DICT = {
:yellow => Gdk::Color.new(65535, 65535, 0),
:black => Gdk::Color.new(0, 0, 0),
}
colormap = Gdk::Colormap.system
COLOR_DICT.each do |_, color|
colormap.alloc_color(color, false, true)
end
# 生成される警告ウィンドウ
class WarningWindow < Gtk::Window
def initialize
super(Gtk::Window::POPUP)
@width = 300 # ウィンドウの幅
@height = 150 # ウィンドウの高さ
m = [WIDTH/2 - @width/2, HEIGHT/2 - @height/2]
s = [WIDTH/8, HEIGHT/8]
@x, @y = box_muller(m, s)
@x_adder = [-2, -1, 1, 2].sample
@y_adder = [-2, -1, 1, 2].sample
self.move(@x, @y)
self.set_size_request(@width, @height)
self.set_app_paintable(true)
self.set_title("WARNING!!")
self.realize
@drawable = self.window
@gc = Gdk::GC.new(@drawable)
@gc.set_line_attributes(20, Gdk::GC::LINE_SOLID, Gdk::GC::CAP_ROUND, Gdk::GC::JOIN_BEVEL)
# 画像を表示
source = ["./msg_warning.png", "./msg_danger.png"].sample
@image = Gtk::Image.new(source)
self.add(@image)
# 縞模様用のカウンタ
@counters = (-1..5).map do |i|
->(init, max) do
n = init
-> { n == max - 1 ? n = -50 : n += 1 }
end[i*50, @width]
end
end
# 縞模様を流すアニメーション
def add_task
Gtk.timeout_add(20) do
@x += @x_adder
@y += @y_adder
@x_adder *= -1 if @x < 0 || @x > WIDTH - @width
@y_adder *= -1 if @y < 0 || @y > HEIGHT - @height
self.move(@x, @y)
clear
draw
end
end
# 黒い斜め線を描画
def draw
@gc.set_foreground(COLOR_DICT[:black])
@counters.each do |counter|
from = [counter[], 0]
to = [from[0] + 50 ,@height]
@drawable.draw_line(@gc, *from, *to)
end
end
# 背景を黄色で描画
def clear
@gc.set_foreground(COLOR_DICT[:yellow])
@drawable.draw_rectangle(@gc, true, 0, 0, @width, @height)
end
private
# ウィンドウの出現位置を散らすため
def box_muller(m = [0, 0], s = [1, 1])
r1 = rand
r2 = rand
x = sqrt(-2 * log(r1)) * cos(2*PI * r2)
y = sqrt(-2 * log(r1)) * sin(2*PI * r2)
[s[0] * x + m[0], s[1] * y + m[1]]
end
end
wins = []
Gtk.timeout_add(100) do
wins << WarningWindow.new
wins.last.show_all
# たまにどれか消える
if rand < 0.3
win = wins.sample
win.destroy
wins.delete(win)
end
# MAXを越えたらこれ以上ウィンドウは増えない
if wins.size > MAX
sleep 1
wins.each(&:add_task)
true
end.!
end
begin
Gtk.main
rescue Interrupt
Gtk.main_quit
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment