Class: WxExtensions::RootPanel

Inherits:
Wx::Panel
  • Object
show all
Defined in:
lib/reactive-wx/wx_ext/semi_modal.rb

Overview

This class acts like a Wx::Panel but will be the root for semi-modal windows (or dialogs) When any children of this RootPanel invokes semi-modal, all the children of this panel will be disabled, and only the semi-modal window will be active.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_root_panel(current) ⇒ Object

Look for the topmost RootPanel in the ancestors

Raises:

  • (StandardError)


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/reactive-wx/wx_ext/semi_modal.rb', line 8

def self.find_root_panel(current)
  # If current is already a top level, look for a RootPanel in his parent
  current = current.get_parent if current.is_a? Wx::TopLevelWindow
  
  root_panel = nil
  begin
    case current
      when nil
        break
      when RootPanel
        root_panel = current
      when Wx::TopLevelWindow
        break
    end
    current = current.get_parent
  end while current
  
  raise StandardError.new("There are no RootPanel in the ancestors!") if root_panel.nil?
  root_panel
end

Instance Method Details

#disable_childrenObject



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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/reactive-wx/wx_ext/semi_modal.rb', line 29

def disable_children
  @screener = Wx::Frame.new(self, :style => #Wx::FRAME_TOOL_WINDOW |
                                     Wx::FRAME_FLOAT_ON_PARENT |
                                     Wx::FRAME_NO_TASKBAR |
                                     #Wx::NO_BORDER |
                                     0,
                                     :size => self.size, :pos => self.get_screen_position)
  @screener.set_background_colour(Wx::SystemSettings.get_colour(Wx::SYS_COLOUR_ACTIVECAPTION))
  @screener.set_transparent(128)
  @screener.show
  
  top_level = find_top_level

  # Hooks to handle moving and resizing
  resize_block = proc do |event|
    update_screener
    @user_resize_block.call if @user_resize_block
    event.skip
  end
  top_level.evt_moving() {|event| update_screener; event.skip}
  top_level.evt_move() {|event| update_screener; event.skip}
  evt_sizing(&resize_block)
  evt_size(&resize_block)
  
  # Hooks for handling showing/hiding
  @screener.evt_activate() do |event|
    @user_visible_block.call(true) if @user_visible_block && event.get_active
    event.skip
  end
  evt_set_focus() do |event|
    @user_visible_block.call(true) if @user_visible_block
    event.skip      # TODO: Not sure if this is wanted... to be checked on the different platforms
  end
  @timer = Wx::Timer.every(100) do
    # TODO: This timer may tick after window deletion (when the app exits) and thus crash on the *is_shown* method. DONE with evt_window_destroy
    if (shown = is_shown) != @shown
      @shown = shown
      # handle screener
      if @screener
        update_screener if shown
        @screener.show(shown)
      end
      # handler user window
      @user_resize_block.call if @user_resize_block && shown
      @user_visible_block.call(shown) if @user_visible_block
    end
  end
  evt_window_destroy() do |event|
    @timer.stop if @timer
    event.skip
  end

  # Hook to handle client closing
  # TODO: BUG: event handler used to be on the top_level window, now on the root panel. Test it. This change moves wxruby to be unstable
  evt_close() do |event|
    veto = nil
    veto = @user_close_block.call(event) if @user_close_block
    veto ? event.veto : event.skip
  end

=begin only when the patched version of wxAui will be commited in wxWidgets trunk
  # Is the TopLevelWindow of this root panel managed by Aui?
  handler = top_level.get_event_handler
  begin
#        puts "PROCESSING handler #{handler}"
    aui_manager = case handler
      when Wx::AuiManager
        handler
      when Wx::AuiFloatingFrame
        handler.get_owner_manager
      else
        nil
    end
    if aui_manager
#          puts "MANAGED by #{aui_manager}"
      pi = aui_manager.get_pane(self)
#          puts "WITH PI #{pi}"
      if pi
        @aui_manager = aui_manager
        @pi_floatable = pi.is_floatable
        @pi_dockable = pi.is_dockable
        pi.set_floatable(false).set_dockable(false)
        #@aui_manager.update
      end
      break
    end
  end while handler = handler.get_next_handler
=end
end

#enable_childrenObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/reactive-wx/wx_ext/semi_modal.rb', line 119

def enable_children
  if @aui_manager
    if pi = @aui_manager.get_pane(self)
      pi.set_floatable(@pi_floatable).set_dockable(@pi_dockable)
    end
  end
  
  top_level = find_top_level
  top_level.disconnect(Wx::ID_ANY, Wx::ID_ANY, :evt_moving)
  top_level.disconnect(Wx::ID_ANY, Wx::ID_ANY, :evt_move)
  disconnect(Wx::ID_ANY, Wx::ID_ANY, :evt_close)
  disconnect(Wx::ID_ANY, Wx::ID_ANY, :evt_sizing)
  disconnect(Wx::ID_ANY, Wx::ID_ANY, :evt_size)
  
  @timer.stop if @timer
  @user_resize_block = nil
  @user_visible_block = nil
  
  @screener.destroy
  @screener = nil
end

#on_close(&block) ⇒ Object

The passed block will be called when the TopLevel window of this RootPanel is requested to close. The return code of the block is a boolean value indicating if the close should be vetoed. (Thus the normal block is: { not close }



156
157
158
# File 'lib/reactive-wx/wx_ext/semi_modal.rb', line 156

def on_close(&block)
  @user_close_block = block
end

#on_resize(&block) ⇒ Object

The passed block will be called when the RootPanel is resized.



142
143
144
# File 'lib/reactive-wx/wx_ext/semi_modal.rb', line 142

def on_resize(&block)
  @user_resize_block = block
end

#on_visible(&block) ⇒ Object

The passed block will be called when the RootPanel is activated or gains focus. The block should receive one argument which will be a boolean indicating if it should be made visible. Note that setting your window visible may not be enough, #raise should put it in front.



149
150
151
# File 'lib/reactive-wx/wx_ext/semi_modal.rb', line 149

def on_visible(&block)
  @user_visible_block = block
end