class Crysterm::Screen
- Crysterm::Screen
- Reference
- Object
Overview
Represents a screen.
Included Modules
- Crysterm::Macros
- Crysterm::Mixin::Children
- Crysterm::Mixin::Instances
- Crysterm::Mixin::Name
- Crysterm::Mixin::Pos
- EventHandler
Defined in:
screen.crscreen_angles.cr
screen_attributes.cr
screen_children.cr
screen_cursor.cr
screen_decoration.cr
screen_drawing.cr
screen_focus.cr
screen_interaction.cr
screen_rendering.cr
screen_resize.cr
screen_rows.cr
screen_screenshot.cr
Constant Summary
-
ANGLE_TABLE =
{0 => ' ', 1 => '│', 2 => '─', 3 => '┌', 4 => '│', 5 => '│', 6 => '└', 7 => '├', 8 => '─', 9 => '┐', 10 => '─', 11 => '┬', 12 => '┘', 13 => '┤', 14 => '┴', 15 => '┼'}
-
Every ACS angle character can be represented by 4 bits ordered like this: [langle][uangle][rangle][dangle]
-
ANGLES =
{'┘', '┐', '┌', '└', '┼', '├', '┤', '┴', '┬', '│', '─'}
-
All angles, uniq list
-
BITWISE_D_ANGLE =
1 << 0
-
BITWISE_L_ANGLE =
1 << 3
-
BITWISE_R_ANGLE =
1 << 1
-
BITWISE_U_ANGLE =
1 << 2
-
D_ANGLES =
{'┘', '└', '┼', '├', '┤', '┴', '│'}
-
DEFAULT_ATTR =
((0 << 18) | (511 << 9)) | 511
-
DEFAULT_CHAR =
' '
-
L_ANGLES =
{'┌', '└', '┼', '├', '┴', '┬', '─'}
-
Left, top, right, and bottom angles
-
R_ANGLES =
{'┘', '┐', '┼', '┤', '┴', '┬', '─'}
-
U_ANGLES =
{'┐', '┌', '┼', '├', '┤', '┬', '│'}
Constructors
Class Method Summary
-
.global(create : Bool = true)
Creates and/or returns the "global" (first) created instance.
-
.instances
List of existing instances.
-
.total
Returns number of created instances
Instance Method Summary
- #<<(element)
- #>>(element)
- #_border_stops : Hash(Int32, Bool)
- #_border_stops=(_border_stops : Hash(Int32, Bool))
- #_ci : Int32
- #_ci=(_ci : Int32)
- #_dock_borders
- #_focus(cur : Widget, old : Widget | Nil = nil)
-
#_get_angle(lines, x, y)
Returns appropriate angle char for point (y,x) in
#lines
-
#_listen_keys(el : Widget | Nil = nil)
And this is for the other/alternative method where the screen first gets the keys, then potentially passes onto children elements.
-
#_render
Real render
- #_saved_focus : Widget | Nil
- #_saved_focus=(_saved_focus : Widget | Nil)
-
#aheight : Int32
Returns current screen height.
-
#alloc(dirty = false)
Allocates screen buffers (a new pending/staging buffer and a new output buffer).
-
#always_propagate : Array(Tput::Key)
Array of keys to ignore when keys are locked or grabbed.
-
#always_propagate=(always_propagate : Array(Tput::Key))
Array of keys to ignore when keys are locked or grabbed.
-
#apply_cursor
Applies current cursor settings in
@cursor
to screen/display - #attach(element)
-
#attr2code(code, cur, dfl)
Converts an SGR string to our own attribute format.
-
#awidth : Int32
Returns current screen width.
- #blank_line(ch = ' ', dirty = false)
-
#clean_sides(el)
Parse the sides of an element to determine whether an element has uniform cells on both sides.
-
#clear_region(xi, xl, yi, yl, override)
Clears any chosen region on the screen.
-
#code2attr(code)
Converts our own attribute format to an SGR string.
- #cursor : Crysterm::Screen::Cursor
-
#cursor_color(color : Tput::Color | Nil = nil)
Sets cursor color
-
#cursor_reset
Re-enables and resets hardware cursor
-
#cursor_shape(shape : Tput::CursorShape = Tput::CursorShape::Block, blink : Bool = false)
Sets cursor shape
-
#default_attr : Int32
XXX move somewhere else? Default cell attribute
-
#default_attr=(default_attr : Int32)
XXX move somewhere else? Default cell attribute
-
#default_char : Char
XXX move somewhere else? Default cell character
-
#default_char=(default_char : Char)
XXX move somewhere else? Default cell character
-
#delete_bottom(top, bottom)
Deletes line at bottom of screen.
-
#delete_line(n, y, top, bottom)
Deletes lines from the screen.
-
#delete_line_nc(n, y, top, bottom)
Deletes lines from the screen using ncurses-compatible method.
-
#delete_top(top, bottom)
Deletes line at top of screen.
-
#destroy
Destroys self and removes it from the global list of
Screen
s. - #detach(element)
-
#dock_borders=(dock_borders : Bool)
Automatically "dock" borders with other elements instead of overlapping, depending on position.
-
#dock_borders? : Bool
Automatically "dock" borders with other elements instead of overlapping, depending on position.
-
#draw(start = 0, stop = @lines.size - 1)
Draws the screen based on the contents of in-memory grid of cells (
@lines
). -
#emit_key(el, e : Event)
Emits a Event::KeyPress as usual and also emits an event for the individual key, if any.
- #enter
-
#error : IO
Error IO.
-
#error=(error : IO)
Error IO.
-
#exec(screen : Crysterm::Screen | Nil = nil)
Displays the main screen, set up IO hooks, and starts the main loop.
-
#fill_region(attr, ch, xi, xl, yi, yl, override = false)
Fills any chosen region on the screen with chosen character and attributes.
-
#focus(el)
Makes
el
become the current/top element in the focus history list. -
#focus_next
Focuses next element in the list of focusable elements.
-
#focus_offset(offset)
Focuses an element by an offset in the list of focusable elements.
-
#focus_pop
Removes focus from the current element and focuses the element that was previously in focus.
-
#focus_previous
Focuses previous element in the list of focusable elements.
-
#focus_push(el)
Focuses element
el
. -
#focused : Widget | Nil
Returns the current/top element from the focus history list.
-
#force_unicode=(force_unicode : Bool)
Force Unicode (UTF-8) even if terminfo auto-detection did not find support for it?
-
#force_unicode? : Bool
Force Unicode (UTF-8) even if terminfo auto-detection did not find support for it?
-
#grab_keys=(grab_keys : Bool)
Is the focused element grab and receiving all keypresses?
-
#grab_keys? : Bool
Is the focused element grab and receiving all keypresses?
-
#height : Int32
Display height TODO make these check @output, not STDOUT which is probably used.
-
#height=(height : Int32)
Display height TODO make these check @output, not STDOUT which is probably used.
-
#hide_cursor
Hides cursor
-
#ibottom
Amount of space taken by decorations on bottom, to be subtracted from widget's total height
-
#iheight
Returns current screen height.
-
#ileft
Amount of space taken by decorations on the left side, to be subtracted from widget's total width
-
#input : IO
Input IO
-
#input=(input : IO)
Input IO
-
#insert(element, i = -1)
Inserts
element
into list of children widgets -
#insert_bottom(top, bottom)
Inserts line at bottom of screen.
-
#insert_line(n, y, top, bottom)
Inserts lines into the screen.
-
#insert_line_nc(n, y, top, bottom)
Inserts lines into the screen using ncurses-compatible method.
-
#insert_top(top, bottom)
Inserts line at top of screen.
- #interval : Float64
- #interval=(interval : Float64)
-
#iright
Amount of space taken by decorations on the right side, to be subtracted from widget's total width
-
#itop
Amount of space taken by decorations on top, to be subtracted from widget's total height
-
#iwidth
Returns current screen width.
-
#last_rendered_position
TODO Instead of self, this should just return an object which reports the position like LPos.
- #leave
- #lines : Array(Crysterm::Screen::Row)
- #lines=(lines : Array(Crysterm::Screen::Row))
-
#listen
Sets up IO listeners for keyboard (and mouse, but mouse is currently unsupported).
-
#listen_keys
Starts emitting
Event::KeyPress
events on key presses. - #new_method(*args)
- #olines : Array(Crysterm::Screen::Row)
- #olines=(olines : Array(Crysterm::Screen::Row))
- #on_attach(e)
-
#on_destroy(e)
Destroys current
Display
. - #on_detach(e)
- #on_resize(e)
-
#optimization : OptimizationFlag
Optimization flags to use for rendering and/or drawing.
-
#optimization=(optimization : OptimizationFlag)
Optimization flags to use for rendering and/or drawing.
-
#output : IO
Output IO
-
#output=(output : IO)
Output IO
-
#overflow : Crysterm::Overflow
Specifies what to do with "overflowing" (too large) widgets.
-
#overflow=(overflow : Crysterm::Overflow)
Specifies what to do with "overflowing" (too large) widgets.
-
#padding : Crysterm::Padding
For compatibility with widgets.
-
#padding=(padding : Crysterm::Padding)
For compatibility with widgets.
- #post_enter
-
#propagate_keys=(propagate_keys : Bool)
Are keypresses being propagated further, or (except ignored ones) not propagated?
-
#propagate_keys? : Bool
Are keypresses being propagated further, or (except ignored ones) not propagated?
-
#realloc
Reallocates screen buffers and clear the screen.
-
#remove(element)
Removes
element
from list of children widgets -
#render
Delayed render (user render)
- #render_loop
-
#resize
Re-reads current size of all
Display
s and triggers redraw of allScreen
s. -
#resize_interval : Time::Span
Amount of time to wait before redrawing the screen, after the last successive terminal resize event is received.
-
#resize_interval=(resize_interval : Time::Span)
Amount of time to wait before redrawing the screen, after the last successive terminal resize event is received.
-
#restore_focus
Restores focus to the previously saved focused element.
-
#rewind_focus
"Rewinds" focus to the most recent visible and attached element.
-
#save_focus
Saves/remembers the currently focused element.
- #schedule_render
- #screenshot(xi = 0, xl = awidth, yi = 0, yl = aheight, term = false)
-
#send_focus : Bool
Send focus events after mouse is enabled?
-
#send_focus=(send_focus : Bool)
Send focus events after mouse is enabled?
-
#show_avg=(show_avg : Bool)
Include displaying averages in FPS display.
-
#show_avg? : Bool
Include displaying averages in FPS display.
-
#show_cursor
Shows cursor
-
#show_fps : Tput::Point | Nil
Which position on the screen should be used to display FPS stats.
-
#show_fps=(show_fps : Tput::Point | Nil)
Which position on the screen should be used to display FPS stats.
-
#title : String | Nil
Screen title, if/when applicable
-
#title=(title : String | Nil)
Screen title, if/when applicable
-
#tput : Tput
Instance of
Tput
, used for generating term control sequences. -
#width : Int32
Display width TODO make these check @output, not STDOUT which is probably used.
-
#width=(width : Int32)
Display width TODO make these check @output, not STDOUT which is probably used.
Instance methods inherited from module Crysterm::Mixin::Instances
bind
bind,
destroy
destroy
Instance methods inherited from module Crysterm::Mixin::Children
<<(widget : Widget)
<<,
>>(widget : Widget)
>>,
append(element)append(*elements) append, children children, collect_ancestors(el : Widget) : Array(Widget) collect_ancestors, collect_descendants(el : Widget) : Array(Widget) collect_descendants, each_ancestor(&block : Proc(Widget, Nil)) : Nil each_ancestor, each_descendant(&block : Proc(Widget, Nil)) : Nil each_descendant, emit_ancestors(ev : EventHandler::Event | EventHandler::Event.class) : Nil emit_ancestors, emit_descendants(ev : EventHandler::Event | EventHandler::Event.class) : Nil emit_descendants, has_ancestor?(obj) has_ancestor?, has_descendant?(obj) has_descendant?, insert(element, i = -1) insert, insert_after(element, other) insert_after, insert_before(element, other) insert_before, prepend(element) prepend, remove(element) remove, self_and_each_ancestor(&block : Proc(Widget, Nil)) : Nil self_and_each_ancestor, self_and_each_descendant(&block : Proc(Widget, Nil)) : Nil self_and_each_descendant
Instance methods inherited from module Crysterm::Mixin::Pos
abottom : Int32 | Nil
abottom,
abottom=(abottom : Int32 | Nil)
abottom=,
aleft : Int32 | Nil
aleft,
aleft=(aleft : Int32 | Nil)
aleft=,
aright : Int32 | Nil
aright,
aright=(aright : Int32 | Nil)
aright=,
atop : Int32 | Nil
atop,
atop=(atop : Int32 | Nil)
atop=,
lpos : LPos | Nil
lpos,
lpos=(lpos : LPos | Nil)
lpos=,
renders
renders,
renders=(renders)
renders=,
scrollable=(scrollable)
scrollable=,
scrollable?
scrollable?
Instance methods inherited from module Crysterm::Mixin::Name
name : String | Nil
name,
name=(name : String | Nil)
name=
Macros inherited from module Crysterm::Macros
alias_method(new_method, old_method)
alias_method,
alias_previous(*new_methods)
alias_previous,
handle(event, handler = nil)
handle
Constructor Detail
Class Method Detail
Creates and/or returns the "global" (first) created instance.
An alternative approach, which is currently not implemented, would be to hold the global in a class variable, and return it here. In that way, the choice of the default/global object at a particular time would be configurable in runtime.
List of existing instances.
For automatic management of this list, make sure that #bind
is called at
creation and #destroy
at termination.
#bind
does not have to be called explicitly because it happens during #initialize
.
#destroy
does need to be called.
Instance Method Detail
Returns appropriate angle char for point (y,x) in #lines
To operate, needs #lines
(the 2d array of cells), and (y,x) point
you're asking for.
And this is for the other/alternative method where the screen first gets the keys, then potentially passes onto children elements.
Returns current screen height. This is now a local operation since we expect Display to push-update us.
Allocates screen buffers (a new pending/staging buffer and a new output buffer).
'Dirty' typically indicates that lines have to be redrawn. In this function's current implementation, if dirty is true it will re-crete the field of screen cells, not adjust the size of existing one.
Array of keys to ignore when keys are locked or grabbed. Useful for defining keys that will always execute their action (e.g. exit a program) regardless of whether keys are propagate.
Array of keys to ignore when keys are locked or grabbed. Useful for defining keys that will always execute their action (e.g. exit a program) regardless of whether keys are propagate.
Returns current screen width. This is now a local operation since we expect Display to push-update us.
Parse the sides of an element to determine whether an element has uniform cells on both sides. If it does, we can use CSR to optimize scrolling on a scrollable element. Not exactly sure how worthwhile this is. This will cause a performance/cpu-usage hit, but will it be less or greater than the performance hit of slow-rendering scrollable boxes with clean sides?
Sets cursor shape
Deletes lines from the screen. (If CSR is used, it bypasses the output buffer.)
Deletes lines from the screen using ncurses-compatible method. (If CSR is used, it bypasses the output buffer.)
This is how ncurses does it. Scroll down (up cursor-wise). This will only work for top line deletion as opposed to arbitrary lines.
Destroys self and removes it from the global list of Screen
s.
Also remove all global events relevant to the object.
If no screens remain, the app is essentially reset to its initial state.
Automatically "dock" borders with other elements instead of overlapping, depending on position. These border-overlapped elements: ┌─────────┌─────────┐ │ box1 │ box2 │ └─────────└─────────┘ Become: ┌─────────┬─────────┐ │ box1 │ box2 │ └─────────┴─────────┘
Automatically "dock" borders with other elements instead of overlapping, depending on position. These border-overlapped elements: ┌─────────┌─────────┐ │ box1 │ box2 │ └─────────└─────────┘ Become: ┌─────────┬─────────┐ │ box1 │ box2 │ └─────────┴─────────┘
Draws the screen based on the contents of in-memory grid of cells (@lines
).
Emits a Event::KeyPress as usual and also emits an event for the individual key, if any.
This allows listeners to not only listen for a generic
Event::KeyPress
and then check for #key
, but they can
directly listen for e.g. Event::KeyPress::CtrlP
.
Error IO. (Could be used for redirecting error output to a particular widget.)
Displays the main screen, set up IO hooks, and starts the main loop.
This is similar to how it is done in the Qt framework.
This function will render the specified screen
or the first Screen
assigned to Display
.
Fills any chosen region on the screen with chosen character and attributes.
Focuses an element by an offset in the list of focusable elements.
E.g. focus_offset 1
moves focus to the next focusable element.
focus_offset 3
moves focus 3 focusable elements further.
If the end of list of focusable elements is reached before the item to focus is found, the search continues from the beginning.
Removes focus from the current element and focuses the element that was previously in focus.
Returns the current/top element from the focus history list.
Force Unicode (UTF-8) even if terminfo auto-detection did not find support for it?
Force Unicode (UTF-8) even if terminfo auto-detection did not find support for it?
Display height
TODO make these check @output, not STDOUT which is probably used. Also see how urwid does the size check
Display height
TODO make these check @output, not STDOUT which is probably used. Also see how urwid does the size check
Amount of space taken by decorations on bottom, to be subtracted from widget's total height
Amount of space taken by decorations on the left side, to be subtracted from widget's total width
Inserts element
into list of children widgets
Inserts lines into the screen. (If CSR is used, it bypasses the output buffer.)
Inserts lines into the screen using ncurses-compatible method. (If CSR is used, it bypasses the output buffer.)
This is how ncurses does it. Scroll down (up cursor-wise). This will only work for top line deletion as opposed to arbitrary lines.
Amount of space taken by decorations on the right side, to be subtracted from widget's total width
TODO Instead of self, this should just return an object which reports the position like LPos. But until screen is always from (0,0) to (height,width) that's not necessary.
Starts emitting Event::KeyPress
events on key presses.
Keys are listened for in a separate Fiber
. There should be at most 1.
Optimization flags to use for rendering and/or drawing. XXX See also a TODO item related to dynamically deciding on default flags.
Optimization flags to use for rendering and/or drawing. XXX See also a TODO item related to dynamically deciding on default flags.
Specifies what to do with "overflowing" (too large) widgets. The default setting of
Overflow::Ignore
simply ignores the overflow and renders the parts that are in view.
Specifies what to do with "overflowing" (too large) widgets. The default setting of
Overflow::Ignore
simply ignores the overflow and renders the parts that are in view.
For compatibility with widgets. But, as a side-effect, screens can have padding! If you define widget at position (0,0), that will be counted after padding. (We leave this at nil for no padding. If we used Padding.new that'd create a 1 cell padding by default.)
For compatibility with widgets. But, as a side-effect, screens can have padding! If you define widget at position (0,0), that will be counted after padding. (We leave this at nil for no padding. If we used Padding.new that'd create a 1 cell padding by default.)
Are keypresses being propagated further, or (except ignored ones) not propagated?
Are keypresses being propagated further, or (except ignored ones) not propagated?
Removes element
from list of children widgets
Re-reads current size of all Display
s and triggers redraw of all Screen
s.
NOTE There is currently no detection for which Display
the resize has
happened on, so a resize in any one managed display causes an update and
redraw of all displays.
Amount of time to wait before redrawing the screen, after the last successive terminal resize event is received.
The value used in Qt is 0.3 seconds. The value commonly used in console apps is 0.2 seconds. Yet another choice could be the frame rate, i.e. 1/29 seconds.
This ensures the resizing/redrawing is done only once, once resizing is over. To have redraws happen even while resizing is going on, reduce this interval.
Amount of time to wait before redrawing the screen, after the last successive terminal resize event is received.
The value used in Qt is 0.3 seconds. The value commonly used in console apps is 0.2 seconds. Yet another choice could be the frame rate, i.e. 1/29 seconds.
This ensures the resizing/redrawing is done only once, once resizing is over. To have redraws happen even while resizing is going on, reduce this interval.
"Rewinds" focus to the most recent visible and attached element.
As a side-effect, prunes the focus history list.
Include displaying averages in FPS display. If this setting is false, only current/ individual frame rates are shown, without values for averages over 30 frames.
Include displaying averages in FPS display. If this setting is false, only current/ individual frame rates are shown, without values for averages over 30 frames.
Which position on the screen should be used to display FPS stats. Nil disables. XXX Currently this is enabled since Crysterm is under development.
Which position on the screen should be used to display FPS stats. Nil disables. XXX Currently this is enabled since Crysterm is under development.
Display width
TODO make these check @output, not STDOUT which is probably used. Also see how urwid does the size check
Display width
TODO make these check @output, not STDOUT which is probably used. Also see how urwid does the size check