Class: Glimmer::Tk::ToplevelProxy

Inherits:
WidgetProxy show all
Defined in:
lib/glimmer/tk/toplevel_proxy.rb

Overview

Proxy for TkToplevel

Follows the Proxy Design Pattern

Direct Known Subclasses

RootProxy

Constant Summary collapse

REGEX_GEOMETRY =
/[x+-]/
DEFAULT_WIDTH =
190
DEFAULT_HEIGHT =
0

Constants inherited from WidgetProxy

WidgetProxy::FONTS_PREDEFINED, WidgetProxy::HEXADECIMAL_CHARACTERS

Instance Attribute Summary collapse

Attributes inherited from WidgetProxy

#args, #bind_ids, #children, #destroyed, #keyword, #parent_proxy

Attributes included from DraggableAndDroppable

#on_drag_motion_block

Instance Method Summary collapse

Methods inherited from WidgetProxy

#add_observer, #ancestor_proxies, #apply_style, #attribute_argument_normalizers, #attribute_setter, #clear_children, #content, create, #destroy, #disabled, #disabled=, #enabled, #enabled=, #event_generate, #font=, #grid, #has_attributes_attribute?, #has_state?, #hidden, #hidden=, #image_argument, #initialize, #inspect, #method_missing, #normalize_attribute_arguments, #on, #post_initialize_child, #respond_to?, #root_parent_proxy, #style=, tk_widget_class_for, #tk_widget_has_attribute_getter_setter?, #tk_widget_has_attribute_setter?, #toplevel_parent_proxy, #unbind_all, #visible, #visible=, #widget_attribute_listener_installers, #widget_custom_attribute_mapping, widget_exists?, widget_proxy_class

Methods included from DraggableAndDroppable

#drag_source=, #drop_target=, #make_draggable, #make_droppable, #make_non_draggable, #make_non_droppable, #on_drag_start_block=, #on_drop_block=, #textvariable_defined?

Constructor Details

This class inherits a constructor from Glimmer::Tk::WidgetProxy

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Glimmer::Tk::WidgetProxy

Instance Attribute Details

#centeredObject Also known as: centered?

Returns the value of attribute centered.



35
36
37
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 35

def centered
  @centered
end

#escapableObject Also known as: escapable?

Returns the value of attribute escapable.



35
36
37
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 35

def escapable
  @escapable
end

Returns the value of attribute modal.



35
36
37
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 35

def modal
  @modal
end

#tkObject (readonly)

Returns the value of attribute tk.



34
35
36
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 34

def tk
  @tk
end

Instance Method Details

#center_within_root(margin: 0) ⇒ Object



193
194
195
196
197
198
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 193

def center_within_root(margin: 0)
  self.x = root_parent_proxy.x + margin
  self.y = root_parent_proxy.y + margin
  self.width = root_parent_proxy.width - 2 * margin
  self.height = root_parent_proxy.height - 2 * margin
end

#center_within_screenObject



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 157

def center_within_screen
  monitor_width, monitor_height = wm_maxsize
  update :idletasks
  current_width = width
  current_height = height

  if RbConfig::CONFIG['host_os'] == 'linux'
    begin
      # example output: HDMI-A-0 connected primary 2560x1080+1024+100 (normal left inverted right x axis y axis) 798mm x 334mm
      # TODO: is xrandr output same on all systems?
      sizes = `xrandr`
                .split("\n")
                .find { |line| line.include?(' connected primary ') }
                &.match(/([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)/)
      raise "`xrandr` returned unexpected results. Try to run `xrandr`, verify it's output and possibly update this code." unless sizes

      self.x = (sizes[1].to_i - width) / 2 + sizes[3].to_i
      self.y = (sizes[2].to_i - height) / 2 + sizes[4].to_i

    rescue StandardError => e
      Glimmer::Config.logger.debug {"Unable to detect primary screen on Linux with xrandr"}
      Glimmer::Config.logger.debug {e.full_message}

      self.x = (winfo_screenwidth - width) / 2
      self.y = (winfo_screenheight - height) / 2
    end

  else
    self.x = (winfo_screenwidth - width) / 2
    self.y = (winfo_screenheight - height) / 2
  end

  self.width = width
  self.height = height
end

#closest_windowObject



214
215
216
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 214

def closest_window
  self
end

#get_attribute(attribute) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 98

def get_attribute(attribute)
  case attribute.to_s
  when 'icon_photo'
    super('iconphoto')
  else
    super
  end
end

#handle_listener(listener_name, &listener) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 147

def handle_listener(listener_name, &listener)
  case listener_name.to_s.upcase
  when 'WM_DELETE_WINDOW', 'DELETE_WINDOW'
    listener_name = 'WM_DELETE_WINDOW'
    @tk.protocol(listener_name, &listener)
  else
    super
  end
end

#has_attribute?(attribute, *args) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 78

def has_attribute?(attribute, *args)
  %w[width height x y icon_photo].include?(attribute.to_s) || super
end

#heightObject



115
116
117
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 115

def height
  geometry.split(REGEX_GEOMETRY)[1].to_i
end

#height=(value) ⇒ Object



132
133
134
135
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 132

def height=(value)
  @height = value.to_i
  self.geometry = "#{@width || DEFAULT_WIDTH}x#{value.to_i}#{x_sign}#{abs_x}#{y_sign}#{abs_y}"
end

#icon_photoObject



107
108
109
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 107

def icon_photo
  iconphoto
end

#post_add_contentObject



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
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 40

def post_add_content
  if escapable?
     on('KeyPress') do |event|
      if event.state == 0 && event.keysym == 'Escape'
        tk.grab_release
        destroy
      end
    end
  end

  if modal?
    unless is_a?(Glimmer::Tk::ToplevelProxy)
      raise 'Modal windows must be top level windows. Root cannot be modal.'
    end

    center_within_root unless @x || @y
    root_parent_proxy.withdraw
    tk.grab_set
    on('WM_DELETE_WINDOW') do
      tk.grab_release
      root_parent_proxy.deiconify
      destroy
      true
    end
    on('destroy') do
      tk.grab_release
      root_parent_proxy.deiconify
      true
    end
  else
    center_within_screen unless @x || @y
  end

  if is_a?(Glimmer::Tk::ToplevelProxy) && @tk.iconphoto.nil? && root_parent_proxy.iconphoto
    @tk.iconphoto = root_parent_proxy.iconphoto
  end
end

#set_attribute(attribute, *args) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 82

def set_attribute(attribute, *args)
  case attribute.to_s
  when 'iconphoto', 'icon_photo'
    args[0..-1] = [image_argument(args)]
    super('iconphoto', *args)
  when 'resizable'
    if args.size == 1 && !args.first.is_a?(Array)
      self.resizable = [args.first]*2
    else
      super
    end
  else
    super
  end
end

#widthObject



111
112
113
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 111

def width
  geometry.split(REGEX_GEOMETRY)[0].to_i
end

#width=(value) ⇒ Object



127
128
129
130
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 127

def width=(value)
  @width = value.to_i
  self.geometry = "#{value.to_i}x#{@height || DEFAULT_HEIGHT}#{x_sign}#{abs_x}#{y_sign}#{abs_y}"
end

#window?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 200

def window?
  true
end

#xObject



119
120
121
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 119

def x
  sign_number(x_sign, geometry.split(REGEX_GEOMETRY)[2].to_i)
end

#x=(value) ⇒ Object



137
138
139
140
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 137

def x=(value)
  @x = value
  self.geometry = "#{@width || DEFAULT_WIDTH}x#{@height || DEFAULT_HEIGHT}#{value.to_i > 0 ? '+' : '-'}#{value.to_i.abs}#{y_sign}#{abs_y}"
end

#yObject



123
124
125
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 123

def y
  sign_number(y_sign, geometry.split(REGEX_GEOMETRY)[3].to_i)
end

#y=(value) ⇒ Object



142
143
144
145
# File 'lib/glimmer/tk/toplevel_proxy.rb', line 142

def y=(value)
  @y = value
  self.geometry = "#{@width || DEFAULT_WIDTH}x#{@height || DEFAULT_HEIGHT}#{x_sign}#{abs_x}#{value.to_i > 0 ? '+' : '-'}#{value.to_i.abs}"
end