Class: Canis::Container
- Defined in:
- lib/canis/core/widgets/rcontainer.rb
Overview
This is an attempt at having a container which can contain multiple widgets without being a form itself. Having forms within forms complicates code too much, esp cursor positioning. e.g. tabbedpane
Instance Attribute Summary collapse
-
#current_component ⇒ Object
readonly
Returns the value of attribute current_component.
Attributes inherited from Widget
#_object_created, #col_offset, #config, #curpos, #focussed, #form, #handler, #id, #key_label, #parent_component, #row_offset, #state
Instance Method Summary collapse
-
#add(*items) ⇒ Object
(also: #add_widget)
NOTE: since we are handling the traversal, we delink the object from any form’s widgets array that might have been added.
-
#attach_form(c) ⇒ Object
When we get a form, we silently attach it to this object, without the form knowing.
- #check_component(c) ⇒ Object
-
#correct_component(c) ⇒ Object
correct coordinates of comp esp if App has stacked them after this container It is best to use the simple stack feature.
-
#goto_component(comp) ⇒ Object
set focus on given component Sometimes you have the handle to component, and you want to move focus to it.
- #goto_next_component ⇒ Object
- #goto_prev_component ⇒ Object
-
#handle_key(ch) ⇒ Object
called by parent or form, otherwise its private.
- #init_vars ⇒ Object
-
#initialize(form = nil, config = {}, &block) ⇒ Container
constructor
A new instance of Container.
-
#leave_current_component ⇒ Object
leave the component we are on.
-
#on_enter ⇒ Object
Actually we should only go to current component if it accepted a key stroke.
-
#on_first_component? ⇒ Boolean
is focus on first component FIXME check for focusable.
-
#on_last_component? ⇒ Boolean
is focus on last component FIXME check for focusable.
-
#on_leave ⇒ Object
we cannot be sure that this will be called especially if this is embedded inside some other component.
-
#repaint ⇒ Object
repaint object called by Form, and sometimes parent component (if not form).
- #set_form_col ⇒ Object
-
#set_form_row ⇒ Object
private XXX why are we calling 3 methods in a row, why not OE manages these 3 There’s double calling going on.
- #widgets ⇒ Object
Methods inherited from Widget
#action_manager, #bgcolor, #color, #color_pair, #command, #destroy, #focus, #focusable, #focusable?, #getvalue, #getvalue_for_paint, #hide, #modified?, #move, #override_graphic, #process_key, #property_set, #remove, #repaint_all, #repaint_required, #rowcol, #set_form, #set_modified, #setformrowcol, #setrowcol, #show, #unbind_key
Methods included from Io
#__create_footer_window, #clear_this, #get_file, #print_this, #rb_getchar, #rb_gets, #rb_getstr, #warn
Methods included from Utils
#ORIG_process_key, #ORIGbind_key, #ORIGkeycode_tos, #_process_key, #bind_composite_mapping, #bind_key, #bind_keys, #check_composite_mapping, #create_logger, #define_key, #define_prefix_command, #execute_mapping, #get_attrib, #get_color, #key, #key_tos, #print_key_bindings, #repeatm, #run_command, #shell_out, #shell_output, #suspend, #view, #xxxbind_composite_mapping
Methods included from ConfigSetup
Methods included from EventHandler
#bind, #event?, #event_list, #fire_handler, #fire_property_change, #register_events
Constructor Details
#initialize(form = nil, config = {}, &block) ⇒ Container
Returns a new instance of Container.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 47 def initialize form=nil, config={}, &block @suppress_borders = false @row_offset = @col_offset = 1 @_events ||= [] @stack = true @positioning = :stack super @focusable = true @editable = false @components = [] # all components @focusables = [] # focusable components, makes checks easier init_vars end |
Instance Attribute Details
#current_component ⇒ Object (readonly)
Returns the value of attribute current_component.
45 46 47 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 45 def current_component @current_component end |
Instance Method Details
#add(*items) ⇒ Object Also known as: add_widget
NOTE: since we are handling the traversal, we delink the object from any form’s widgets array that might have been added. Whenever a form is available, we set it (without adding widget to it) so it can print using the form’s window.
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 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 77 def add *items items.each do |c| raise ArgumentError, "Nil component passed to add" unless c if c.is_a? Widget if c.form && c.form != @form $log.debug " removing widget VIMSPLIT #{c.class} wr: #{c.row} row:#{@row} ht:#{@height} " c.form. c c.form = nil # or should i just stack them myself and screw what you've asked for end # take it out of form's control. We will control it. if c.form c.form. c end # shoot, what if at this point the container does not have a form attach_form c if @form end # most likely if you have created both container and widgets # inside app, it would have given row after container @components << c if c.focusable @focusables << c @current_component ||= c # only the first else cursor falls on last on enter end end # items each self end |
#attach_form(c) ⇒ Object
When we get a form, we silently attach it to this object, without the form
knowing. We don't want form managing this object.
109 110 111 112 113 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 109 def attach_form c c.form = @form c.override_graphic @graphic c.parent_component = self end |
#check_component(c) ⇒ Object
163 164 165 166 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 163 def check_component c raise "row is less than container #{c.row} #{@row} " if c.row <= @row raise "col is less than container #{c.col} #{@col} " if c.col <= @col end |
#correct_component(c) ⇒ Object
correct coordinates of comp esp if App has stacked them after this container It is best to use the simple stack feature. The rest could change at any time
and is quite arbitrary. Some folks may set absolute locations if container
is directly on a form, others may set relative locations if it is inside a
tabbed pane or other container. Thus, stacks are best
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 125 def correct_component c raise "Form is still not set in Container" unless @form attach_form(c) unless c.form @last_row ||= @row + 1 inset = 2 # 2011-10-20 current default behaviour is to stack if @positioning == :stack c.row = @last_row c.col = @col + inset # do not advance row, save col for next row @last_row += 1 elsif @positioning == :relative # UNTESTED NOTE if (c.row || 0) <= 0 $log.warn "c.row in CONTAINER is #{c.row} " c.row = @last_row @last_row += 1 elsif c.row > @row + @height -1 $log.warn "c.row in CONTAINER exceeds container. #{c.row} " c.row -= @height - @row_offset else # this is where it should come c.row += @row + @row_offset @last_row = c.row + 1 end if (c.col || 0) <= 0 c.col = @col + inset + @col_offset elsif c.col > @col + @width -1 c.col -= @width elsif c.col == @col c.col += @col_offset + inset else #f c.col < @col c.col += @col+@col_offset end $log.debug "XXX: CORRECT #{c.name} r:#{c.row} c:#{c.col} " end @first_time = false end |
#goto_component(comp) ⇒ Object
set focus on given component Sometimes you have the handle to component, and you want to move focus to it
385 386 387 388 389 390 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 385 def goto_component comp return if comp == @current_component leave_current_component @current_component = comp set_form_row end |
#goto_next_component ⇒ Object
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 299 def goto_next_component if @current_component != nil leave_current_component if on_last_component? #@_entered = false return :UNHANDLED end @current_index = @focusables.index(@current_component) index = @current_index + 1 f = @focusables[index] if f @current_index = index @current_component = f return set_form_row end end @_entered = false return :UNHANDLED end |
#goto_prev_component ⇒ Object
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 318 def goto_prev_component if @current_component != nil leave_current_component if on_first_component? @_entered = false return :UNHANDLED end @current_index = @focusables.index(@current_component) index = @current_index -= 1 f = @focusables[index] if f @current_index = index @current_component = f return set_form_row end end return :UNHANDLED end |
#handle_key(ch) ⇒ Object
called by parent or form, otherwise its private
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 211 def handle_key ch $log.debug " CONTAINER handle_key #{ch} " return if @components.empty? _multiplier = ($multiplier == 0 ? 1 : $multiplier ) # should this go here 2011-10-19 unless @_entered $log.warn "XXX WARN: calling ON_ENTER since in this situation it was not called" on_enter end if ch == KEY_TAB $log.debug "CONTAINER GOTO NEXT TAB" return goto_next_component elsif ch == KEY_BTAB return goto_prev_component end comp = @current_component $log.debug " CONTAINER handle_key #{ch}: #{comp}" if comp ret = comp.handle_key(ch) $log.debug " CONTAINER handle_key#{ch}: #{comp} returned #{ret} " if ret != :UNHANDLED comp.repaint # NOTE: if we don;t do this, then it won't get repainted. I will have to repaint ALL # in repaint of this. return ret end $log.debug "XXX CONTAINER key unhandled by comp #{comp.name} " else $log.warn "XXX CONTAINER key unhandled NULL comp" end case ch when ?\C-c.getbyte(0) $multiplier = 0 return 0 when ?0.getbyte(0)..?9.getbyte(0) $log.debug " VIM coming here to set multiplier #{$multiplier} " $multiplier *= 10 ; $multiplier += (ch-48) return 0 end ret = process_key ch, self # allow user to map left and right if he wants if ret == :UNHANDLED case ch when KEY_UP # form will pick this up and do needful return goto_prev_component #unless on_first_component? when KEY_LEFT # if i don't check for first component, key will go back to form, # but not be processes. so focussed remain here, but be false. # In case of returnign an unhandled TAB, on_leave will happen and cursor will move to # previous component outside of this. return goto_prev_component unless on_first_component? when KEY_RIGHT return goto_next_component #unless on_last_component? when KEY_DOWN return goto_next_component #unless on_last_component? else @_entered = false return :UNHANDLED end end $multiplier = 0 return 0 end |
#init_vars ⇒ Object
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 61 def init_vars @repaint_required = true @row_offset = @col_offset = 0 if @suppress_borders # FIXME supposed to use this !! @internal_width = 2 @internal_width = 1 if @suppress_borders @name ||= "AContainer" @first_time = true end |
#leave_current_component ⇒ Object
leave the component we are on. This should be followed by all containers, so that the on_leave action of earlier comp can be displayed, such as dimming components selections
365 366 367 368 369 370 371 372 373 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 365 def leave_current_component @current_component.on_leave # NOTE this is required, since repaint will just not happen otherwise # Some components are erroneously repainting all, after setting this to true so it is # working there. @current_component.repaint_required true $log.debug " after on_leave RCONT XXX #{@current_component.focussed} #{@current_component.name}" @current_component.repaint end |
#on_enter ⇒ Object
Actually we should only go to current component if it accepted a key stroke. if user tabbed thru it, then no point going back to it. Go to first or last depending on TAB or BACKTAB otherwise. NOTE: if user comes in using DOWN or UP, last traversed component will get the focus
281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 281 def on_enter # if BTAB, the last comp XXX they must be focusable FIXME if $current_key == KEY_BTAB || $current_key == KEY_UP @current_component = @focusables.last else @current_component = @focusables.first end return unless @current_component $log.debug " CONTAINER came to ON_ENTER #{@current_component} " set_form_row @_entered = true end |
#on_first_component? ⇒ Boolean
is focus on first component FIXME check for focusable
376 377 378 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 376 def on_first_component? @current_component == @focusables.first end |
#on_last_component? ⇒ Boolean
is focus on last component FIXME check for focusable
380 381 382 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 380 def on_last_component? @current_component == @focusables.last end |
#on_leave ⇒ Object
we cannot be sure that this will be called especially if this is embedded inside some other component
295 296 297 298 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 295 def on_leave @_entered = false super end |
#repaint ⇒ Object
repaint object called by Form, and sometimes parent component (if not form).
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 171 def repaint my_win = @form ? @form.window : @target_window @graphic = my_win unless @graphic raise " #{@name} NO GRAPHIC set as yet CONTAINER paint " unless @graphic @components.each { |e| correct_component e } if @first_time #@components.each { |e| check_component e } # seeme one if printing out #return unless @repaint_required # if some major change has happened then repaint everything if @repaint_required $log.debug " VIM repaint graphic #{@graphic} " print_borders unless @suppress_borders # do this once only, unless everything changes @components.each { |e| e.repaint_all(true); e.repaint } else @components.each { |e| e.repaint } end # if repaint_required @repaint_required = false end |
#set_form_col ⇒ Object
356 357 358 359 360 361 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 356 def set_form_col return if @current_component.nil? $log.debug " #{@name} CONTAINER EMPTY set_form_col calling sfc for #{@current_component.name} " # already called from above. #@current_component.set_form_col end |
#set_form_row ⇒ Object
private XXX why are we calling 3 methods in a row, why not OE manages these 3 There’s double calling going on.
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 339 def set_form_row return :UNHANDLED if @current_component.nil? cc = @current_component $log.debug "CONT #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} " $log.debug " CONTAINER on enter sfr #{@current_component.name} #{@current_component} " # bug caught here. we were printing a field before it had been set, so it printed out @components.each { |e| correct_component e } if @first_time @current_component.on_enter @current_component.set_form_row # why was this missing in vimsplit. is it $log.debug "CONT2 #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} " # that on_enter does a set_form_row @current_component.set_form_col # XXX @current_component.repaint # OMG this could happen before we've set row and col # XXX compo should do set_form_row and col if it has that end |
#widgets ⇒ Object
115 |
# File 'lib/canis/core/widgets/rcontainer.rb', line 115 def ; @components; end |