Class: GSuper::SuperWindow

Inherits:
Gtk::Window
  • Object
show all
Includes:
Color
Defined in:
lib/gsuper/super_window.rb

Overview

字幕ウィンドウを表わすクラス。

Constant Summary collapse

BACKGROUND_COLOR =
Color::gdk_color([0.0, 1.0, 0.0])
BACKGROUND_ALPHA =
0.5

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Color

gdk_alpha, gdk_color, pango_quadruple, pango_triple

Constructor Details

#initializeSuperWindow

Returns a new instance of SuperWindow.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/gsuper/super_window.rb', line 13

def initialize
  super()

  @font_name = 'Sans Bold 24'
  @text_color = Color::gdk_color([1.0, 0.5, 0.0])
  @shadow_color = Color::gdk_color([0.0, 0.0, 1.0])
  @text = ""

  @interactive = true

  self.app_paintable = true

  signal_connect('expose-event') do
    if @interactive
      exposed_interactive
    else
      exposed_noninteractive
    end
  end

  self.events = Gdk::Event::BUTTON_PRESS_MASK |
                Gdk::Event::BUTTON_RELEASE_MASK |
                Gdk::Event::POINTER_MOTION_MASK

  signal_connect('screen-changed') do 
    screen_changed
  end

  signal_connect('configure-event') do
    # p :configure
    invalidate
    set_responsive(interactive?)
    # exposeを誘発するためにfalseを返す
    false
  end

  button_pressed = false
  press_point = nil
  move = nil
  signal_connect('button-press-event') do |_, ev_button|
    button_pressed = true
    w, h = size
    if ev_button.x.between?(w - 30, w - 1) &&
       ev_button.y.between?(h - 30, h - 1)
      move = false
      press_point = [(w - ev_button.x), (h - ev_button.y)]
    else
      move = true
      press_point = [ev_button.x, ev_button.y]
    end
    # p :press
  end

  signal_connect('button-release-event') do
    button_pressed = false
    press_point = nil
    move = nil
    # p :release
  end

  signal_connect('motion-notify-event') do |_, ev_motion|
    if interactive? && button_pressed
      if move
        move(ev_motion.x_root - press_point[0], ev_motion.y_root - press_point[1])
      else
        w = ev_motion.x + press_point[0]
        h = ev_motion.y + press_point[1]
        resize([w, 100].max, [h, 100].max)
        # invalidate
        # set_responsive(true)
      end
    end
    # p :pointer_motion
  end

  # self.decorated = false

  self.set_default_size(640,480)

  @alpha_supported = false
  screen_changed

  # GDK window を作る。
  realize

  window.override_redirect = true
  set_responsive(true)
end

Instance Attribute Details

#font_nameObject

Returns the value of attribute font_name.



11
12
13
# File 'lib/gsuper/super_window.rb', line 11

def font_name
  @font_name
end

#shadow_colorObject

Returns the value of attribute shadow_color.



11
12
13
# File 'lib/gsuper/super_window.rb', line 11

def shadow_color
  @shadow_color
end

#textObject

Returns the value of attribute text.



11
12
13
# File 'lib/gsuper/super_window.rb', line 11

def text
  @text
end

#text_colorObject

Returns the value of attribute text_color.



11
12
13
# File 'lib/gsuper/super_window.rb', line 11

def text_color
  @text_color
end

Instance Method Details

#draw_text(cr) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/gsuper/super_window.rb', line 169

def draw_text(cr)
  # p [:draw_text, font_name]
  desc = Pango::FontDescription.new(font_name)

  layout = create_pango_layout
  layout.width = size[0] * Pango::SCALE
  layout.font_description = desc
  layout.text = text

  offset = shadow_offset(desc)

  cr.move_to(offset, offset)
  cr.set_source_rgba(*pango_triple(@shadow_color), 1.0)
  cr.show_pango_layout(layout)

  cr.move_to(0, 0)
  cr.set_source_rgba(*pango_triple(@text_color), 1.0)
  cr.show_pango_layout(layout)
end

#exposed_interactiveObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/gsuper/super_window.rb', line 124

def exposed_interactive
  cr = window.create_cairo_context 

  if @alpha_supported
    cr.set_source_rgba(*pango_triple(BACKGROUND_COLOR), BACKGROUND_ALPHA)
  else
    cr.set_source_rgb(*pango_triple(BACKGROUND_COLOR))
  end

  cr.set_operator(Cairo::OPERATOR_SOURCE)
  cr.paint

  draw_text(cr)

  cr.set_source_rgb(0.5, 0.5, 0.5)
  w, h = size
  cr.fill do
    cr.rectangle(w - 30, h - 3, w, h)
    cr.rectangle(w - 3, h - 30, w, h)
  end

  cr.destroy

  return false
end

#exposed_noninteractiveObject



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/gsuper/super_window.rb', line 150

def exposed_noninteractive
  cr = window.create_cairo_context 

  if @alpha_supported
    cr.set_source_rgba(0.0, 0.0, 0.0, 0.0)
  else
    cr.set_source_rgb(0.0, 0.0, 0.0)
  end

  cr.set_operator(Cairo::OPERATOR_SOURCE)
  cr.paint

  draw_text(cr)

  cr.destroy

  return false
end

#interactive=(flag) ⇒ Object



207
208
209
210
211
# File 'lib/gsuper/super_window.rb', line 207

def interactive=(flag)
  @interactive = flag
  set_responsive(flag)
  invalidate
end

#interactive?Boolean

Returns:

  • (Boolean)


203
204
205
# File 'lib/gsuper/super_window.rb', line 203

def interactive?
  @interactive
end

#invalidateObject



223
224
225
226
# File 'lib/gsuper/super_window.rb', line 223

def invalidate
  window.invalidate(window.clip_region, true)
  window.process_updates(true)
end

#pt_to_px(point, dpi) ⇒ Object



199
200
201
# File 'lib/gsuper/super_window.rb', line 199

def pt_to_px(point, dpi)
  point / 72.0 * dpi
end

#screen_changedObject



228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/gsuper/super_window.rb', line 228

def screen_changed
  colormap = self.screen.rgba_colormap
  if colormap
    # puts 'alpha channel supported'
    @alpha_supported = true
    self.colormap = colormap
  else
    STDERR.puts 'Warning: alpha channel NOT supported'
    @alpha_supported = false
    self.colormap = self.screen.rgb_colormap
  end
end

#set_responsive(responsive) ⇒ Object



213
214
215
216
217
218
219
220
221
# File 'lib/gsuper/super_window.rb', line 213

def set_responsive(responsive)
  if responsive
    width, height = size
    region = Gdk::Region.new(Gdk::Rectangle.new(0, 0, width, height))
  else
    region = Gdk::Region.new(Gdk::Rectangle.new(0, 0, 0, 0))
  end
  window.input_shape_combine_region(region, 0, 0)
end

#shadow_offset(desc) ⇒ Object

右下に二度打ちで「影」を落とす。そのオフセットは線の太さの半分にし たいとする。

Raises:

  • (TypeError)


191
192
193
194
195
196
197
# File 'lib/gsuper/super_window.rb', line 191

def shadow_offset(desc)
  raise TypeError unless desc.is_a? Pango::FontDescription
  dpi = window.screen.resolution

  font_px = pt_to_px(desc.size.fdiv(Pango::SCALE), dpi)
  return ( font_px * (1/12.0) * (desc.weight.to_i / 400.0) * (1/3.0) ).round
end