Class: RETerm::Window
- Inherits:
-
Object
- Object
- RETerm::Window
- Includes:
- EventDispatcher, LogHelpers
- Defined in:
- lib/reterm/window.rb
Overview
Windows are areas rendered on screen, associated with components to be rendered in them. They specify the position to start drawing component as well as the maximum width and height. A border may be drawn around a window and a ColorPair associated.
If Layout is added to a Window, children may subsequently be added. This should be performed via the Layout#add_child method.
Constant Summary
Constants included from LogHelpers
Instance Attribute Summary collapse
-
#children ⇒ Object
Returns the value of attribute children.
-
#cols ⇒ Object
Returns the value of attribute cols.
-
#component ⇒ Object
Returns the value of attribute component.
-
#hborder ⇒ Object
Returns the value of attribute hborder.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#rows ⇒ Object
Returns the value of attribute rows.
-
#vborder ⇒ Object
Returns the value of attribute vborder.
-
#win ⇒ Object
readonly
Returns the value of attribute win.
-
#window_id ⇒ Object
readonly
Returns the value of attribute window_id.
-
#x ⇒ Object
Returns the value of attribute x.
-
#y ⇒ Object
Returns the value of attribute y.
Class Method Summary collapse
-
.adjust_proportional(parent, rows, cols) ⇒ Object
Adjusts rows/cols in a context dependent manner TODO should proporational percentage be of remaining area?.
-
.align(parent, x, y, rows, cols) ⇒ Object
Adjusts x/y in context dependent manner.
-
.all ⇒ Object
Static method returning all tracked windows.
-
.fill_parent(parent, x, y, rows, cols) ⇒ Object
Adjusts rows / cols so as to fill parent.
-
.top ⇒ Object
Static method returning top level windows.
Instance Method Summary collapse
-
#activate!(*input) ⇒ Object
Activate window component.
-
#actual_cols ⇒ Object
Return window cols.
-
#actual_rows ⇒ Object
Return window rows.
-
#bold! ⇒ Object
Enable bold formatting.
-
#border! ⇒ Object
Draw Border around window.
-
#cdk? ⇒ Boolean
Return bool indicating if cdk is enabled for this window/component.
-
#cdk_scr ⇒ Object
Return cdk screen (only used by CDK components).
-
#child_containing(x, y, z) ⇒ Object
Return child containing specified screen coordiantes, else nil.
-
#children? ⇒ Boolean
Return boolean indicating if this window has children.
-
#clear! ⇒ Object
Clear window by removing all children and reinitializing window space.
-
#colored? ⇒ Boolean
Return bool indiciating if colors are set.
-
#colors=(c) ⇒ Object
Set window color.
-
#component? ⇒ Boolean
Return bool indicating if this window has a component associated with it.
-
#create_child(h = {}) ⇒ Object
Create child window, this method should not be invoked by end-user, rather it is is invoked the Layout#add_child is called.
-
#del_child(child) ⇒ Object
Remove child window, like #create_child, this is used internally and should not be invoked by the end user.
-
#dimensions ⇒ Object
Return window dimensions as an array containing rows & cols.
-
#draw! ⇒ Object
Draw component in window.
-
#erase ⇒ Object
Erase window drawing area.
-
#erase_scr ⇒ Object
Erases window screen by overwriting it with blanks.
- #expand? ⇒ Boolean
-
#finalize! ⇒ Object
Invoke window finalization routine by destroying it and all children.
-
#first_child? ⇒ Boolean
Return boolean indicating if this window is the first child of its parent.
-
#getch ⇒ Object
Blocking call to capture next character from window.
-
#initialize(args = {}) ⇒ Window
constructor
Instantiate Window with given args.
-
#last_child? ⇒ Boolean
Return boolean indicating if this window is the last child of its parent.
- #must_expand? ⇒ Boolean
-
#mvaddstr(*a) ⇒ Object
Write string at specified loc.
-
#no_bold! ⇒ Object
Disable bold formatting.
-
#no_border! ⇒ Object
Remove Border around window.
-
#no_reverse! ⇒ Object
Disabled reverse formatting.
- #noutrefresh ⇒ Object
-
#parent? ⇒ Boolean
Return boolean if this window is a child of another.
-
#refresh ⇒ Object
Refresh / resynchronize window and all children.
- #request_expansion(r, c) ⇒ Object
- #resize(rows, cols) ⇒ Object
-
#reverse! ⇒ Object
Enable reverse formatting.
-
#root ⇒ Object
Return root window (recusively), self if parent is not set.
-
#sync! ⇒ Object
Dispatch to component synchronization.
-
#sync_getch ⇒ Object
Normal getch unless sync enabled in which case, timeout will be checked & components synchronized.
- #total_x ⇒ Object
- #total_y ⇒ Object
Methods included from LogHelpers
Methods included from EventDispatcher
Constructor Details
#initialize(args = {}) ⇒ Window
Instantiate Window with given args. None are required, but unless :rows, :cols, :x, or :y is specified, window will be created in it’s default position.
This method will generate a unique id for each window and add it to a static registry for subsequent tracking.
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 149 150 151 152 153 154 155 156 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 |
# File 'lib/reterm/window.rb', line 124 def initialize(args={}) @@registry ||= [] @@registry << self @@wid ||= 0 @@wid += 1 @window_id = @@wid @children = [] @x = args[:x] || 0 @y = args[:y] || 0 @vborder = args[:vborder] || 0 @hborder = args[:hborder] || 0 component = args[:component] @rows = args[:rows] || (component ? (component.requested_rows + component.extra_padding) : Terminal.rows) @cols = args[:cols] || (component ? (component.requested_cols + component.extra_padding) : Terminal.cols) if args[:parent] @parent = args[:parent] @rows, @cols = *Window.adjust_proportional(@parent, @rows, @cols) @x, @y = *Window.align(@parent, @x, @y, @rows, @cols) @win = parent.win.derwin(@rows, @cols, @y, @x) else @parent = nil @rows, @cols = *Window.adjust_proportional(Terminal, @rows, @cols) @x, @y = *Window.align(Terminal, @x, @y, @rows, @cols) @win = Ncurses::WINDOW.new(@rows, @cols, @y, @x) end raise ArgumentError, "could not create window" if !@win self.component = component if !!component Ncurses::keypad(@win, true) @win.timeout(SYNC_TIMEOUT) if sync_enabled? # XXX = !!args[:expand] = !!args[:must_expand] @fill = !!args[:fill] end |
Instance Attribute Details
#children ⇒ Object
Returns the value of attribute children.
43 44 45 |
# File 'lib/reterm/window.rb', line 43 def children @children end |
#cols ⇒ Object
Returns the value of attribute cols.
32 33 34 |
# File 'lib/reterm/window.rb', line 32 def cols @cols end |
#component ⇒ Object
Returns the value of attribute component.
38 39 40 |
# File 'lib/reterm/window.rb', line 38 def component @component end |
#hborder ⇒ Object
Returns the value of attribute hborder.
36 37 38 |
# File 'lib/reterm/window.rb', line 36 def hborder @hborder end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
42 43 44 |
# File 'lib/reterm/window.rb', line 42 def parent @parent end |
#rows ⇒ Object
Returns the value of attribute rows.
32 33 34 |
# File 'lib/reterm/window.rb', line 32 def rows @rows end |
#vborder ⇒ Object
Returns the value of attribute vborder.
35 36 37 |
# File 'lib/reterm/window.rb', line 35 def vborder @vborder end |
#win ⇒ Object (readonly)
Returns the value of attribute win.
40 41 42 |
# File 'lib/reterm/window.rb', line 40 def win @win end |
#window_id ⇒ Object (readonly)
Returns the value of attribute window_id.
30 31 32 |
# File 'lib/reterm/window.rb', line 30 def window_id @window_id end |
#x ⇒ Object
Returns the value of attribute x.
33 34 35 |
# File 'lib/reterm/window.rb', line 33 def x @x end |
#y ⇒ Object
Returns the value of attribute y.
33 34 35 |
# File 'lib/reterm/window.rb', line 33 def y @y end |
Class Method Details
.adjust_proportional(parent, rows, cols) ⇒ Object
Adjusts rows/cols in a context dependent manner TODO should proporational percentage be of remaining area?
187 188 189 190 191 192 193 194 195 |
# File 'lib/reterm/window.rb', line 187 def self.adjust_proportional(parent, rows, cols) nr = rows nc = cols nr = parent.rows * nr if rows < 1 nc = parent.cols * nc if cols < 1 return nr, nc end |
.align(parent, x, y, rows, cols) ⇒ Object
Adjusts x/y in context dependent manner
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/reterm/window.rb', line 198 def self.align(parent, x, y, rows, cols) nx = x ny = y nx = 1 if x == :left ny = 1 if y == :top nx = parent.cols - cols - 1 if x == :right ny = parent.rows - rows - 1 if y == :bottom nx = parent.cols / 2 - cols / 2 if x == :center ny = parent.rows / 2 - rows / 2 if y == :center return nx, ny end |
.all ⇒ Object
Static method returning all tracked windows
297 298 299 300 |
# File 'lib/reterm/window.rb', line 297 def self.all @@registry ||= [] @@registry end |
.fill_parent(parent, x, y, rows, cols) ⇒ Object
Adjusts rows / cols so as to fill parent
215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/reterm/window.rb', line 215 def self.fill_parent(parent, x, y, rows, cols) if (y + rows) < parent.rows rows = parent.rows - y - 1 end if (x + cols) < parent.cols cols = parent.cols - x - 1 end return rows, cols end |
.top ⇒ Object
Static method returning top level windows
303 304 305 306 |
# File 'lib/reterm/window.rb', line 303 def self.top @@registry ||= [] @@registry.select { |w| !w.parent? } end |
Instance Method Details
#activate!(*input) ⇒ Object
Activate window component
524 525 526 |
# File 'lib/reterm/window.rb', line 524 def activate!(*input) component.activate!(*input) end |
#actual_cols ⇒ Object
Return window cols
514 515 516 |
# File 'lib/reterm/window.rb', line 514 def actual_cols dimensions[1] end |
#actual_rows ⇒ Object
Return window rows
509 510 511 |
# File 'lib/reterm/window.rb', line 509 def actual_rows dimensions[0] end |
#bold! ⇒ Object
Enable bold formatting
454 455 456 457 458 459 460 |
# File 'lib/reterm/window.rb', line 454 def bold! @win.attron(Ncurses::A_BOLD) return unless block_given? yield @win.attroff(Ncurses::A_BOLD) end |
#border! ⇒ Object
Draw Border around window
417 418 419 |
# File 'lib/reterm/window.rb', line 417 def border! @win.box(@vborder, @hborder) end |
#cdk? ⇒ Boolean
Return bool indicating if cdk is enabled for this window/component
290 291 292 |
# File 'lib/reterm/window.rb', line 290 def cdk? !!@cdk_scr end |
#cdk_scr ⇒ Object
Return cdk screen (only used by CDK components)
284 285 286 287 |
# File 'lib/reterm/window.rb', line 284 def cdk_scr enable_cdk! @cdk_scr ||= CDK::SCREEN.new(@win) end |
#child_containing(x, y, z) ⇒ Object
Return child containing specified screen coordiantes, else nil
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/reterm/window.rb', line 330 def child_containing(x, y, z) found = nil children.find { |c| next if found # recursively descend into layout children if c.component.kind_of?(Layout) found = c.child_containing(x, y, z) else found = c.total_x <= x && c.total_y <= y && # c.z >= z (c.total_x + c.cols) >= x && (c.total_y + c.rows) >= y found = c if found end } found end |
#children? ⇒ Boolean
Return boolean indicating if this window has children
67 68 69 |
# File 'lib/reterm/window.rb', line 67 def children? !@children.empty? end |
#clear! ⇒ Object
Clear window by removing all children and reinitializing window space
365 366 367 368 369 370 371 372 |
# File 'lib/reterm/window.rb', line 365 def clear! children.each { |c| del_child(c) } @children = [] erase end |
#colored? ⇒ Boolean
Return bool indiciating if colors are set
482 483 484 |
# File 'lib/reterm/window.rb', line 482 def colored? !!@colors end |
#colors=(c) ⇒ Object
Set window color
487 488 489 490 491 492 493 494 495 496 |
# File 'lib/reterm/window.rb', line 487 def colors=(c) @colors = c.is_a?(ColorPair) ? c : ColorPair.for(c).first @win.bkgd(Ncurses.COLOR_PAIR(@colors.id)) unless @win.nil? component.colors = @colors if component? children.each { |ch| ch.colors = c } end |
#component? ⇒ Boolean
Return bool indicating if this window has a component associated with it
47 48 49 |
# File 'lib/reterm/window.rb', line 47 def component? !!@component end |
#create_child(h = {}) ⇒ Object
Create child window, this method should not be invoked by end-user, rather it is is invoked the Layout#add_child is called.
313 314 315 316 317 318 |
# File 'lib/reterm/window.rb', line 313 def create_child(h={}) c = self.class.new h.merge(:parent => self) c.colors = @colors if colored? children << c c end |
#del_child(child) ⇒ Object
Remove child window, like #create_child, this is used internally and should not be invoked by the end user
322 323 324 325 326 327 |
# File 'lib/reterm/window.rb', line 322 def del_child(child) @children.delete(child) @@registry.delete(child) child.finalize! child.win.delwin if !!child.win end |
#dimensions ⇒ Object
Return window dimensions as an array containing rows & cols
499 500 501 502 503 504 505 506 |
# File 'lib/reterm/window.rb', line 499 def dimensions rows = [] cols = [] @win.getmaxyx(rows, cols) rows = rows.first cols = cols.first [rows, cols] end |
#draw! ⇒ Object
Draw component in window
519 520 521 |
# File 'lib/reterm/window.rb', line 519 def draw! component.draw! if component? end |
#erase ⇒ Object
Erase window drawing area
375 376 377 378 379 380 381 382 383 |
# File 'lib/reterm/window.rb', line 375 def erase children.each { |c| c.erase } @win.werase if @win component.component.erase if cdk? && component? && component.init? end |
#erase_scr ⇒ Object
Erases window screen by overwriting it with blanks
386 387 388 389 390 |
# File 'lib/reterm/window.rb', line 386 def erase_scr 0.upto(rows) { |r| mvaddstr(r, 1, " " * cols) } end |
#expand? ⇒ Boolean
245 246 247 |
# File 'lib/reterm/window.rb', line 245 def !! end |
#finalize! ⇒ Object
Invoke window finalization routine by destroying it and all children
231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/reterm/window.rb', line 231 def finalize! erase @@registry.delete(self) children.each { |c| del_child c } cdk_scr.destroy if cdk? component.finalize! if component? end |
#first_child? ⇒ Boolean
Return boolean indicating if this window is the first child of its parent
73 74 75 76 |
# File 'lib/reterm/window.rb', line 73 def first_child? return true unless parent? parent.children.index(self) == 0 end |
#getch ⇒ Object
Blocking call to capture next character from window
422 423 424 |
# File 'lib/reterm/window.rb', line 422 def getch @win.getch end |
#last_child? ⇒ Boolean
Return boolean indicating if this window is the last child of its parent
80 81 82 83 |
# File 'lib/reterm/window.rb', line 80 def last_child? return true unless parent? parent.children.index(self) == (parent.children.size - 1) end |
#must_expand? ⇒ Boolean
249 250 251 |
# File 'lib/reterm/window.rb', line 249 def !! end |
#mvaddstr(*a) ⇒ Object
Write string at specified loc
449 450 451 |
# File 'lib/reterm/window.rb', line 449 def mvaddstr(*a) @win.mvaddstr(*a) end |
#no_bold! ⇒ Object
Disable bold formatting
463 464 465 |
# File 'lib/reterm/window.rb', line 463 def no_bold! @win.attroff(Ncurses::A_BOLD) end |
#no_border! ⇒ Object
Remove Border around window
412 413 414 |
# File 'lib/reterm/window.rb', line 412 def no_border! @win.border(' '.ord, ' '.ord, ' '.ord, ' '.ord, ' '.ord, ' '.ord, ' '.ord, ' '.ord) end |
#no_reverse! ⇒ Object
Disabled reverse formatting
477 478 479 |
# File 'lib/reterm/window.rb', line 477 def no_reverse! @win.attroff(Ncurses::A_REVERSE) end |
#noutrefresh ⇒ Object
402 403 404 405 406 407 408 409 |
# File 'lib/reterm/window.rb', line 402 def noutrefresh @win.noutrefresh children.each { |c| c.noutrefresh } component.component.screen.noutrefresh if cdk? end |
#parent? ⇒ Boolean
Return boolean if this window is a child of another
62 63 64 |
# File 'lib/reterm/window.rb', line 62 def parent? !!@parent end |
#refresh ⇒ Object
Refresh / resynchronize window and all children
393 394 395 396 397 398 399 400 |
# File 'lib/reterm/window.rb', line 393 def refresh @win.refresh children.each { |c| c.refresh } component.component.screen.refresh if cdk? end |
#request_expansion(r, c) ⇒ Object
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/reterm/window.rb', line 253 def request_expansion(r, c) h = {:rows => r, :cols => c, :x => x, :y => y} if parent? if parent.component.exceeds_bounds_with?(h) if parent.component. parent.component.(h) else raise ArgumentError, "cannot expand" if return false end end else unless Terminal.contains?(h) raise ArgumentError, "terminal too small" if return false end end resize(r, c) true end |
#resize(rows, cols) ⇒ Object
352 353 354 355 356 357 358 359 360 |
# File 'lib/reterm/window.rb', line 352 def resize(rows, cols) r = win.resize rows, cols raise ArgumentError, "could not resize window" if r == -1 @rows = rows @cols = cols self end |
#reverse! ⇒ Object
Enable reverse formatting
468 469 470 471 472 473 474 |
# File 'lib/reterm/window.rb', line 468 def reverse! @win.attron(Ncurses::A_REVERSE) return unless block_given? yield @win.attroff(Ncurses::A_REVERSE) end |
#root ⇒ Object
Return root window (recusively), self if parent is not set
86 87 88 |
# File 'lib/reterm/window.rb', line 86 def root parent? ? parent.root : self end |
#sync! ⇒ Object
Dispatch to component synchronization
441 442 443 444 445 446 |
# File 'lib/reterm/window.rb', line 441 def sync! component.sync! if component? children.each { |c| c.sync! } end |
#sync_getch ⇒ Object
Normal getch unless sync enabled in which case, timeout will be checked & components synchronized
428 429 430 431 432 433 434 435 436 437 438 |
# File 'lib/reterm/window.rb', line 428 def sync_getch return self.getch unless sync_enabled? c = -1 while c == -1 && !shutdown? c = self.getch run_sync! end c end |
#total_x ⇒ Object
90 91 92 |
# File 'lib/reterm/window.rb', line 90 def total_x @tx ||= parent? ? (parent.total_x + x) : x end |
#total_y ⇒ Object
94 95 96 |
# File 'lib/reterm/window.rb', line 94 def total_y @ty ||= parent? ? (parent.total_y + y) : y end |