diff --git a/ncurses/example.php b/ncurses/example.php
index c1b789e..0b75255 100644
--- a/ncurses/example.php
+++ b/ncurses/example.php
@@ -17,27 +17,44 @@ require_once( 'ncurses.php' );
* @package Nc
* @subpackage Example
*/
-class MyApp extends NcApp {
- function run() {
- $nc_main = new NcWindow( $this, 0, 0, 0, 0 );
- $nc_main->title( 'Hello There' );
- $nc_main->write( 0, 0, file_get_contents( __FILE__ ) );
- $nc_main->get_char();
- $nc_small = new NcWindow( $nc_main, 10, 60, 5, 20 );
- $nc_small->title( 'Progress Bars' );
- ncurses_attron( NCURSES_A_REVERSE );
- $bar_1 = new NcProgressBar( $nc_small, 0, 0, 0, 100, true );
- $bar_1->pos( 57 );
- $bar_2 = new NcProgressBar( $nc_small, 0, 1, 0, 100, false );
- $bar_2->pos( 11 );
- $nc_small->write( 3, 0, 'Text Input:' );
- $input = new NcTextInput( $nc_small, -12, 3, 12 );
- $foo = $input->get();
- $nc_small->write_centered( 4, 'Press any key to destroy this window' );
- $nc_small->get_char();
- $nc_small->hide();
- $nc_main->get_char();
+
+define( 'DEBUG', 1 );
+class LogView extends NcTableView {
+ public function __construct($parent, $height, $width, $y, $x, $params = array()) {
+ parent::__construct($parent, $height, $width, $y, $x, $params);
+ // If we don't prevent the event logging table from logging its own signals,
+ // it'll find itself in a recursive spiral into memory usage hell
+ $this->emit_log_filter[] = 'change';
}
}
-$app = new MyApp();
+
+class MyEventApp extends NcApp {
+ function init() {
+ $this->screen->title('Ncurses Example Application');
+ $input = array();
+ for($i = 0; $i < 3; $i++) {
+ $input[] = new NcTextInput($this->screen, 0, 2*$i, 0);
+ }
+ $log = new LogView($this->screen, $this->screen->height() - 11, 0, 7, 0, array(
+ 'columns' => array(
+ 'class' => 'Class',
+ 'message' => 'Message'
+ )
+ ));
+ $log->title('Application Log');
+ $progress = new NcProgressBar($this->screen, 0, $this->screen->height() - 4, 0);
+ $button = new NcButton($this->screen, 3, 10, $this->screen->height() - 3, 0, 'Quit');
+ Signaler::connect($this, 'log', $log, 'load');
+ Signaler::connect($log, 'change', $progress, 'pos');
+ Signaler::connect($this, 'log_items', $progress, 'max');
+ Signaler::connect($button, 'clicked', $this, 'quit');
+ $log->load($this->log);
+ }
+ function log(&$object, $message) {
+ parent::log($object, $message);
+ $this->emit('log_items', count($this->log) - 1);
+ }
+}
+$app = new MyEventApp();
+$app->exec();
?>
diff --git a/ncurses/ncurses.button.php b/ncurses/ncurses.button.php
new file mode 100644
index 0000000..96ecb21
--- /dev/null
+++ b/ncurses/ncurses.button.php
@@ -0,0 +1,63 @@
+label($label);
+ }
+ public function title($value = false) {
+ parent::title('');
+ }
+ public function label($value = false) {
+ if( $value === false ) {
+ return $this->label;
+ } else {
+ if( $this->active() ) {
+ $this->attribute_on( NCURSES_A_REVERSE );
+ }
+ $this->write_centered(floor($this->height() / 2), $value);
+ $this->attribute_off(NCURSES_A_REVERSE);
+ $this->label = $value;
+ }
+ }
+ public function click() {
+ $this->emit('clicked');
+ }
+ public function focus() {
+ parent::focus();
+ $this->label($this->label);
+ }
+ public function blur() {
+ parent::blur();
+ $this->label($this->label);
+ }
+ public function on_key_press($key) {
+ switch( $key ) {
+ case 13:
+ // RETURN
+ $this->click();
+ break;
+ default:
+ parent::on_key_press($key);
+ }
+ }
+}
+?>
diff --git a/ncurses/ncurses.php b/ncurses/ncurses.php
index e48af33..233e0d2 100644
--- a/ncurses/ncurses.php
+++ b/ncurses/ncurses.php
@@ -12,13 +12,23 @@
* @package Nc
*/
+require_once('signals.php');
+include_once('ncurses.window.php');
+include_once('ncurses.button.php');
+include_once('ncurses.progressbar.php');
+include_once('ncurses.textinput.php');
+include_once('ncurses.tableview.php');
+
/**
* PHP ncurses application
*
* @package Nc
*/
-abstract class NcApp {
- var $screen;
+abstract class NcApp extends Signaler {
+ protected $nc_screen;
+ protected $screen;
+ protected $log = array();
+ protected $done = false;
/**
* Constructor
@@ -32,9 +42,11 @@ abstract class NcApp {
ncurses_init();
$echo ? ncurses_echo() : ncurses_noecho();
ncurses_curs_set( (bool)$cursor );
- $this->screen = ncurses_newwin( 0, 0, 0, 0 );
+ $this->nc_screen = ncurses_newwin( 0, 0, 0, 0 );
ncurses_refresh();
- $this->run();
+ $this->log($this, 'nCurses Initialized');
+ $this->screen = new NcWindow($this, 0, 0, 0, 0);
+ $this->init();
}
/**
* Destructor
@@ -46,625 +58,29 @@ abstract class NcApp {
ncurses_refresh();
ncurses_end();
}
+ public function log(&$object, $message) {
+ if( DEBUG ) {
+ $this->log[] = array(
+ 'class' => get_class($object),
+ 'message' => $message
+ );
+ $this->emit('log', $this->log);
+ }
+ }
+ public function exec() {
+ if( $this->screen instanceof NcWindow ) {
+ while(!$this->done) {
+ $key = ncurses_getch();
+ $this->screen->on_key_press($key);
+ }
+ }
+ }
+ public function quit() {
+ $this->done = true;
+ }
/**
* This is a placeholder function for application code
*/
- abstract function run();
-}
-
-/**
-* Ncurses window
-*
-* Provides a basic window object. A border can be optionally enabled if the window
-* is large enough to accomodate it, and is enabled by default. If a title is set,
-* it will be visible at the top of the border if one exists.
-*
-* If a parent window is provided, the window will be registered as a child of the
-* parent, and will be relatively positioned to the parent.
-*
-* @package Nc
-*/
-class NcWindow {
- /**
- * @var resource nc_window resource for the border window, if one exists
- */
- var $frame;
- /**
- * @var resource nc_window resource for the container window
- */
- var $window;
- /**
- * @var array nc_panel resources for the window and its container
- */
- var $panels = array();
- /**
- * @var array children array of child NcWindow references
- */
- var $children = array();
- /**
- * @var NcWindow reference to this object's direct parent, if one exists
- */
- var $parent = false;
- /**
- * @var integer Absolute column position of the window
- */
- var $x;
- /**
- * @var integer Absolute row position of the window
- */
- var $y;
- /**
- * @var integer Width of contained window
- */
- var $width;
- /**
- * @var integer Height of contained window
- */
- var $height;
- /**
- * @var string Window title
- */
- var $title;
-
- /**
- * Constructor
- *
- * Builds the requested ncurses window.
- *
- * @param NcWindow $parent Parent window
- * @param integer $height Height
- * @param integer $width Width
- * @param integer $y Row
- * @param integer $x Column
- * @param boolean $framed Include a frame (border). Required for window titles.
- */
- public function __construct( $parent, $height, $width, $y, $x, $framed = true ) {
- if( $parent instanceof NcWindow ) {
- $this->parent = $parent;
- $this->parent->add_child( $this );
- $x += $parent->x;
- $y += $parent->y;
- $width += $width <= 0 ? $parent->width : 0;
- $height += $height <= 0 ? $parent->height : 0;
- }
- if( $framed ) {
- $this->frame = ncurses_newwin( $height, $width, $y, $x );
- ncurses_getmaxyx( $this->frame, $max_y, $max_x );
- if( $max_y >= 2 && $max_x >= 2 ) {
- $this->window = ncurses_newwin( $max_y - 2, $max_x - 2, $y + 1, $x + 1 );
- ncurses_wborder( $this->frame, 0,0, 0,0, 0,0, 0,0 );
- ncurses_wrefresh( $this->frame );
- $this->panels[] = ncurses_new_panel( $this->frame );
- } else {
- $this->window = $this->frame;
- $this->frame = false;
- }
- } else {
- $this->frame = false;
- $this->window = ncurses_newwin( $height, $width, $y, $x );
- ncurses_getmaxyx( $this->window, $max_y, $max_x );
- }
- $this->width = $this->frame ? $max_x - 2 : $max_x;
- $this->height = $this->frame ? $max_y - 2 : $max_y;
- $this->x = $this->frame ? $x + 1 : $x;
- $this->y = $this->frame ? $y + 1 : $y;
- ncurses_wrefresh( $this->window );
- $this->panels[] = ncurses_new_panel( $this->window );
- ncurses_update_panels();
- }
- /**
- * Destructor
- */
- public function __destruct() {
- foreach( $this->panels as $id => $panel ) {
- ncurses_del_panel( $this->panels[$id] );
- }
- ncurses_delwin( $this->window );
- if( $this->frame !== false ) {
- ncurses_delwin( $this->frame );
- }
- }
- /**
- * Set or retrieve a window title
- *
- * Sets window title to the value provided, returns the current window title
- * if one is not.
- *
- * @param string $value New window title
- * @return string Window title
- */
- public function title( $value = false ) {
- if( $value === false ) {
- return $this->title;
- } elseif( $this->frame !== false ) {
- $this->title = $value;
- ncurses_wborder( $this->frame, 0,0, 0,0, 0,0, 0,0 );
- ncurses_mvwaddstr( $this->frame, 0, 1, $this->title );
- ncurses_update_panels();
- ncurses_doupdate();
- }
- }
- /**
- * Activate an ncurses output attribute
- *
- * @param integer NCURSES_A_* constant
- */
- public function attribute_on( $attribute ) {
- ncurses_wattron( $this->window, $attribute );
- }
- /**
- * Deactivate an ncurses output attribute
- *
- * @param integer NCURSES_A_* constant
- */
- public function attribute_off( $attribute ) {
- ncurses_wattroff( $this->window, $attribute );
- }
- /**
- * Write text to the window
- *
- * Writes text to the window at the specified coordinates.
- * Text is truncated to prevent it overflowing off the side of the window. If
- * the text contains newlines, it is split and each new line will continue from
- * the same x position as the first, rather than wrapping back to the far left
- * side of the window as ncurses normally would.
- *
- * @param integer $y Row
- * @param integer $x Column
- * @param string $text Text to write
- * @param boolean $update Update the window upon completion
- */
- public function write( $y, $x, $text, $update = true ) {
- $y = $y < 0 ? $this->height + $y : $y;
- $x = $x < 0 ? $this->width + $x : $x;
- $lines = preg_split( '/\r?(\n|\r)/', $text );
- foreach( $lines as $id => $line ) {
- $line = substr( $line, 0, $this->width - $x );
- ncurses_mvwaddstr( $this->window, $y + $id, $x, $line );
- }
- if( $update ) {
- ncurses_update_panels();
- ncurses_doupdate();
- }
- }
- /**
- * Write centered text
- *
- * Writes text centered horizontally within the window on the specified line.
- *
- * @param integer $y Row
- * @param string $text Text to write
- * @param boolean $update Update the window upon completion
- */
- public function write_centered( $y, $text, $update = true ) {
- $this->write(
- $y,
- floor( $this->width / 2 ) - floor( strlen( $text ) / 2 ),
- $text,
- $update
- );
- }
- /**
- * Write fixed-width text
- *
- * Writes a string truncated or padded with spaces to fill the requested width.
- * If the width is unspecified or zero, the width is defined as the length from
- * the starting coordinate to the right edge of the window.
- *
- * @param integer $y Row
- * @param integer $x Column
- * @param string $text Text to write
- * @param integer $width Field length
- * @param boolean $update Update the window upon completion
- */
- public function write_fixed( $y, $x, $text, $width = 0, $update = true ) {
- $width = $width > 0 ? $width : $this->width - $x;
- $this->write( $y, $x, $this->_string_fixed( $text, $width ), $update );
- }
- /**
- * Build a fixed-width string
- *
- * Truncates a string if it exceeds the specified width, pads it with spaces
- * if it is too short.
- *
- * @param string $text Text to format
- * @param integer $width Field length
- * @return string Fixed-width string
- */
- protected function _string_fixed( $text, $width = 0 ) {
- $width = $width < 0 ? 0 : $width;
- $text = substr( $text, 0, $width );
- $text .= str_repeat( ' ', $width - strlen( $text ) );
- return $text;
- }
- /**
- * Assign a window as a child of this window
- *
- * Children of a window are hidden and shown along with their parent widget.
- *
- * @param NcWindow $child Child window
- */
- public function add_child( $child ) {
- $this->children[] = $child;
- }
- /**
- * Hide the window
- *
- * @param boolean $update Update the window upon completion
- */
- public function hide( $update = true ) {
- foreach( $this->panels as $panel ) {
- ncurses_hide_panel( $panel );
- }
- foreach( $this->children as $child ) {
- $child->hide( false );
- }
- if( $update ) {
- ncurses_update_panels();
- ncurses_doupdate();
- }
- }
- /**
- * Show the window
- *
- * @param boolean $update Update the window upon completion
- */
- public function show( $update = true ) {
- foreach( $this->panels as $panel ) {
- ncurses_show_panel( $panel );
- }
- foreach( $this->children as $child ) {
- $child->show( false );
- }
- if( $update ) {
- ncurses_update_panels();
- ncurses_doupdate();
- }
- }
- /**
- * Clear the window's contents
- *
- * @param boolean $update Update the window upon completion
- */
- public function erase( $update = true ) {
- ncurses_werase( $this->window );
- if( $update ) {
- ncurses_wrefresh( $this->window );
- ncurses_doupdate();
- }
- }
- /**
- * Read a character from the keyboard and return it
- *
- * @param boolean $flush Flush the input buffer before requesting a key
- * @return integer Keycode
- */
- public function get_char( $flush = true ) {
- if( $flush ) {
- ncurses_flushinp();
- }
- return ncurses_getch();
- //return ncurses_wgetch( $this->window );
- }
-}
-
-/**
-* Progress Bar
-*
-* @package Nc
-*/
-class NcProgressBar extends NcWindow {
- /**
- * @var float Maximum value
- */
- var $max;
- /**
- * @var float Current value
- */
- var $value;
- /**
- * @var boolean Show percentage
- */
- var $show_pct;
-
- /**
- * Constructor
- *
- * Creates a new progress bar widget
- *
- * @param NcWindow $parent Parent window
- * @param integer $width Width
- * @param integer $y Row
- * @param integer $x Column
- * @param float $max Maximum value
- * @param boolean $show_pct Display the percentage alongside the progress bar
- */
- public function __construct( &$parent, $width, $y, $x, $max = 100, $show_pct = true ) {
- parent::__construct( $parent, 1, $width, $y, $x, false );
- $this->max = $max;
- $this->show_pct = $show_pct;
- $this->pos( 0 );
- }
- /**
- * Set or get the current value
- *
- * @param float $value New value
- * @return float Current value
- */
- public function pos( $value = false ) {
- if( $value === false ) {
- return $this->value;
- } else {
- $value = $value > $this->max ? $this->max : $value;
- $this->value = $value;
- $this->write( 0, 0, '[', false );
- $width = $this->width - ( $this->show_pct ? 7 : 2 );
- $width = $width >= 0 ? $width : 0;
- $complete = floor( $width * $value / $this->max );
- $this->write( 0, 1, str_repeat( '#', $complete ), false );
- $this->write( 0, 1 + $complete, str_repeat( ' ', $width - $complete ), false );
- $this->write( 0, $width + 1, ']', false );
- if( $this->show_pct ) {
- $this->write( 0, $width + 3, sprintf( '%3d%%', floor( $value / $this->max * 100 ) ), false );
- }
- ncurses_update_panels();
- ncurses_doupdate();
- }
- }
- /**
- * Get or set maximum value
- *
- * @param float $value New maximum
- * @return float Current maximum
- */
- public function max( $value = false ) {
- if( $value === false ) {
- return $this->max;
- } else {
- $this->max = $value > 0 ? $value : $this->max;
- $this->pos( $this->value );
- }
- }
-}
-
-/**
-* Text Input
-*
-* @package Nc
-*/
-class NcTextInput extends NcWindow {
- /**
- * @var string Current value
- */
- var $value = '';
- /**
- * @var boolean Active
- */
- var $active = false;
- /**
- * @var string Perl regular expression for filtering input
- */
- var $filter = false;
-
- /**
- * Constructor
- *
- * Creates a new text input widget
- *
- * @param NcWindow $parent Parent window
- * @param integer $width Width
- * @param integer $y Row
- * @param integer $x Column
- * @param string $value Initial value
- * @param string $filter Perl regular expression for filtering input
- */
- public function __construct( &$parent, $width, $y, $x, $value = '', $filter = false ) {
- parent::__construct( $parent, 1, $width, $y, $x, false );
- $this->value = $value;
- $this->filter = $filter !== false && @preg_match( $filter, '' ) !== false ? $filter : false;
- $this->update();
- }
- /**
- * Update the input control on the screen
- *
- * Widget is highlighted when active
- */
- public function update() {
- $this->attribute_on( NCURSES_A_UNDERLINE );
- if( $this->active ) {
- $this->attribute_on( NCURSES_A_REVERSE );
- }
- $this->write_fixed( 0, 0, substr( $this->value, - $this->width ) );
- $this->attribute_off( NCURSES_A_UNDERLINE );
- $this->attribute_off( NCURSES_A_REVERSE );
- }
- /**
- * Get or set value
- */
- public function value( $value = false ) {
- if( $value === false ) {
- return $this->value;
- } else {
- $this->value = $value;
- }
- }
- /**
- * Activate input widget and accept input
- *
- * Input ends when the user presses the enter key.
- * If a filter has been set and the input does not pass the filter, the value
- * reverts to the previous value, and this function returns false.
- *
- * @return string|boolean Text entered, or false
- */
- public function get() {
- $this->active = true;
- $this->update();
- while( $this->active ) {
- $key = $this->get_char();
- switch( $key ) {
- case NCURSES_KEY_BACKSPACE:
- $this->value = substr( $this->value, 0, strlen( $this->value ) - 1 );
- break;
- case 13:
- $this->active = false;
- break;
- default:
- if( in_array( $key, range( 32, 126 ) ) ) {
- $this->value .= chr( $key );
- }
- }
- $this->update();
- }
- $this->update();
- return $this->filter !== false && @preg_match( $this->filter, $this->value ) < 1 ? false : $this->value;
- }
-}
-
-/**
-* Table View
-*
-* @package Nc
-*/
-class NcTableView extends NcWindow {
- /**
- * @var array Column headings
- */
- var $columns;
- /**
- * @var array Recordset
- */
- var $records;
- /**
- * @var integer Currently selected record index
- */
- var $selected;
-
- /**
- * Constructor
- *
- * Creates a new table view
- *
- * @param NcWindow $parent Parent window
- * @param integer $height Height
- * @param integer $width Width
- * @param integer $y Row
- * @param integer $x Column
- * @param array Array of optional parameters, as follows:
- * array(
- * 'columns' => array( 'key' => 'Column Name', ... ),
- * 'records' => array( array( 'key' => 'value', ... ), ... )
- * )
- */
- public function __construct( $parent, $height, $width, $y, $x, $params = array() ) {
- parent::__construct( $parent, $height, $width, $y, $x );
- $params = !is_array( $params ) ? array() : $params;
- $this->columns = isset( $params['columns'] ) && is_array( $params['columns'] ) ? $params['columns'] : array();
- $this->records = isset( $params['records'] ) && is_array( $params['records'] ) ? array_values( $params['records'] ) : array();
- }
- /**
- * Redraw the table and select a record
- *
- * Redraws the table with the specified record selected and the view scrolled
- * accordingly.
- *
- * @param integer $selected Selected row
- */
- public function update( $selected = 0 ) {
- $selected = $selected >= 0 ? $selected : 0;
- $selected = $selected < count( $this->records ) ? $selected : count( $this->records ) - 1;
- $this->selected = $selected;
- $cols = isset( $this->columns ) && is_array( $this->columns ) ? $this->columns : array();
- if( count( $cols ) == 0 ) {
- // If there's no columns defined, try and grab 'em from the keys from the first record
- $record = $this->records[0];
- $record = is_array( $record ) ? $record : array( $record );
- foreach( array_keys( $record ) as $col ) {
- $cols[$col] = $col;
- }
- }
- $column_ids = array_keys( $cols );
- $column_widths = $rows = array();
- foreach( $cols as $id => $column ) {
- $column_widths[$id] = strlen( $column );
- }
- foreach( $this->records as $id => $record ) {
- $record = is_array( $record ) ? $record : array( $record );
- $fields = array();
- foreach( $column_ids as $col ) {
- $field = isset( $record[$col] ) ? $record[$col] : '';
- $field = is_scalar( $field ) ? $field : gettype( $field );
- $fields[$col] = $field;
- $column_widths[$col] = $column_widths[$col] < strlen( $field ) ? strlen( $field ) : $column_widths[$col];
- }
- $rows[] = $fields;
- }
- foreach( $cols as $id => $col ) {
- $cols[$id] = $col . str_repeat( ' ', $column_widths[$id] - strlen( $col ) );
- }
- $this->attribute_on( NCURSES_A_UNDERLINE );
- $this->attribute_on( NCURSES_A_BOLD );
- $this->write_fixed( 0, 0, implode( ' ', $cols ), 0, false );
- $this->attribute_off( NCURSES_A_UNDERLINE );
- $this->attribute_off( NCURSES_A_BOLD );
-
- $max_items = ( $this->height - 2 );
- $offset = ( $selected > $max_items ) ? $selected - $max_items : 0;
- foreach( $rows as $id => $row ) {
- if( $id < $offset ) {
- continue;
- } elseif( $id - $offset > $max_items ) {
- // We've reached the maximum row height for this window
- break;
- }
- foreach( $row as $col => $field ) {
- $row[$col] = $field . str_repeat( ' ', $column_widths[$col] - strlen( $field ) );
- }
- if( $selected == $id ) {
- $this->attribute_on( NCURSES_A_REVERSE );
- }
- $this->write_fixed( $id - $offset + 1, 0, implode( ' | ', $row ), 0, false );
- $this->attribute_off( NCURSES_A_REVERSE );
- }
- $x = 0;
- foreach( array_values( $column_widths ) as $id => $width ) {
- $x += $width + ( $id == 0 ? 1 : 3 );
- // Every Column
- ncurses_wmove( $this->window, 1, $x );
- ncurses_wvline( $this->window, NCURSES_ACS_VLINE, $this->height - 1 );
- // Header Row
- ncurses_wmove( $this->window, 0, $x );
- $this->attribute_on( NCURSES_A_UNDERLINE );
- ncurses_wvline( $this->window, NCURSES_ACS_VLINE, 1 );
- $this->attribute_off( NCURSES_A_UNDERLINE );
- // Highlighted Row
- if( count( $this->records ) > 0 ) {
- ncurses_wmove( $this->window, $selected - $offset + 1, $x );
- $this->attribute_on( NCURSES_A_REVERSE );
- ncurses_wvline( $this->window, NCURSES_ACS_VLINE, 1 );
- $this->attribute_off( NCURSES_A_REVERSE );
- }
- }
- // Finally, update
- ncurses_wrefresh( $this->window );
- ncurses_doupdate();
- }
- /**
- * Load a recordset
- *
- * Recordset should be an array in the following format:
- * array( array( 'key' => 'value', ... ), ... )
- *
- * @param array $records Recordset
- * @return boolean True if recordset loaded successfully, false otherwise
- */
- public function load( $records ) {
- if( !is_array( $records ) ) {
- return false;
- }
- $this->records = array_values( $records );
- $this->update();
- return true;
- }
+ abstract function init();
}
?>
diff --git a/ncurses/ncurses.progressbar.php b/ncurses/ncurses.progressbar.php
new file mode 100644
index 0000000..1d7300f
--- /dev/null
+++ b/ncurses/ncurses.progressbar.php
@@ -0,0 +1,81 @@
+enabled = false; // Cannot accept focus
+ $this->max = $max;
+ $this->show_pct = $show_pct;
+ $this->pos( 0 );
+ }
+ /**
+ * Set or get the current value
+ *
+ * @param float $value New value
+ * @return float Current value
+ */
+ public function pos( $value = false ) {
+ if( $value === false ) {
+ return $this->value;
+ } else {
+ $value = $value > $this->max ? $this->max : $value;
+ $this->value = $value;
+ $this->write( 0, 0, '[', false );
+ $width = $this->width - ( $this->show_pct ? 7 : 2 );
+ $width = $width >= 0 ? $width : 0;
+ $complete = floor( $width * $value / $this->max );
+ $this->write( 0, 1, str_repeat( '#', $complete ), false );
+ $this->write( 0, 1 + $complete, str_repeat( ' ', $width - $complete ), false );
+ $this->write( 0, $width + 1, ']', false );
+ if( $this->show_pct ) {
+ $this->write( 0, $width + 3, sprintf( '%3d%%', floor( $value / $this->max * 100 ) ), false );
+ }
+ ncurses_update_panels();
+ ncurses_doupdate();
+ }
+ }
+ /**
+ * Get or set maximum value
+ *
+ * @param float $value New maximum
+ * @return float Current maximum
+ */
+ public function max( $value = false ) {
+ if( $value === false ) {
+ return $this->max;
+ } else {
+ $this->max = $value > 0 ? $value : $this->max;
+ $this->pos( $this->value );
+ }
+ }
+}
+?>
diff --git a/ncurses/ncurses.tableview.php b/ncurses/ncurses.tableview.php
new file mode 100644
index 0000000..f91f7ab
--- /dev/null
+++ b/ncurses/ncurses.tableview.php
@@ -0,0 +1,169 @@
+array(
+ * 'columns' => array( 'key' => 'Column Name', ... ),
+ * 'records' => array( array( 'key' => 'value', ... ), ... )
+ * )
+ */
+ public function __construct( $parent, $height, $width, $y, $x, $params = array() ) {
+ parent::__construct( $parent, $height, $width, $y, $x );
+ $params = !is_array( $params ) ? array() : $params;
+ $this->columns = isset( $params['columns'] ) && is_array( $params['columns'] ) ? $params['columns'] : array();
+ $this->records = isset( $params['records'] ) && is_array( $params['records'] ) ? array_values( $params['records'] ) : array();
+ }
+ /**
+ * Redraw the table and select a record
+ *
+ * Redraws the table with the specified record selected and the view scrolled
+ * accordingly.
+ *
+ * @param integer $selected Selected row
+ */
+ public function update( $selected = null ) {
+ $selected = $selected === null ? $this->selected : $selected;
+ $selected = $selected >= 0 ? $selected : 0;
+ $selected = $selected < count( $this->records ) ? $selected : count( $this->records ) - 1;
+ $this->selected = $selected;
+ $cols = isset( $this->columns ) && is_array( $this->columns ) ? $this->columns : array();
+ if( count( $cols ) == 0 ) {
+ // If there's no columns defined, try and grab 'em from the keys from the first record
+ $record = $this->records[0];
+ $record = is_array( $record ) ? $record : array( $record );
+ foreach( array_keys( $record ) as $col ) {
+ $cols[$col] = $col;
+ }
+ }
+ $column_ids = array_keys( $cols );
+ $column_widths = $rows = array();
+ foreach( $cols as $id => $column ) {
+ $column_widths[$id] = strlen( $column );
+ }
+ foreach( $this->records as $id => $record ) {
+ $record = is_array( $record ) ? $record : array( $record );
+ $fields = array();
+ foreach( $column_ids as $col ) {
+ $field = isset( $record[$col] ) ? $record[$col] : '';
+ $field = is_scalar( $field ) ? $field : gettype( $field );
+ $fields[$col] = $field;
+ $column_widths[$col] = $column_widths[$col] < strlen( $field ) ? strlen( $field ) : $column_widths[$col];
+ }
+ $rows[] = $fields;
+ }
+ foreach( $cols as $id => $col ) {
+ $cols[$id] = $col . str_repeat( ' ', $column_widths[$id] - strlen( $col ) );
+ }
+ $this->attribute_on( NCURSES_A_UNDERLINE );
+ $this->attribute_on( NCURSES_A_BOLD );
+ $this->write_fixed( 0, 0, implode( ' ', $cols ), 0, false );
+ $this->attribute_off( NCURSES_A_UNDERLINE );
+ $this->attribute_off( NCURSES_A_BOLD );
+
+ $max_items = ( $this->height - 2 );
+ $offset = ( $selected > $max_items ) ? $selected - $max_items : 0;
+ foreach( $rows as $id => $row ) {
+ if( $id < $offset ) {
+ continue;
+ } elseif( $id - $offset > $max_items ) {
+ // We've reached the maximum row height for this window
+ break;
+ }
+ foreach( $row as $col => $field ) {
+ $row[$col] = $field . str_repeat( ' ', $column_widths[$col] - strlen( $field ) );
+ }
+ if( $selected == $id ) {
+ $this->attribute_on( NCURSES_A_REVERSE );
+ }
+ $this->write_fixed( $id - $offset + 1, 0, implode( ' | ', $row ), 0, false );
+ $this->attribute_off( NCURSES_A_REVERSE );
+ }
+ $x = 0;
+ foreach( array_values( $column_widths ) as $id => $width ) {
+ $x += $width + ( $id == 0 ? 1 : 3 );
+ // Every Column
+ ncurses_wmove( $this->window, 1, $x );
+ ncurses_wvline( $this->window, NCURSES_ACS_VLINE, $this->height - 1 );
+ // Header Row
+ ncurses_wmove( $this->window, 0, $x );
+ $this->attribute_on( NCURSES_A_UNDERLINE );
+ ncurses_wvline( $this->window, NCURSES_ACS_VLINE, 1 );
+ $this->attribute_off( NCURSES_A_UNDERLINE );
+ // Highlighted Row
+ if( count( $this->records ) > 0 ) {
+ ncurses_wmove( $this->window, $selected - $offset + 1, $x );
+ $this->attribute_on( NCURSES_A_REVERSE );
+ ncurses_wvline( $this->window, NCURSES_ACS_VLINE, 1 );
+ $this->attribute_off( NCURSES_A_REVERSE );
+ }
+ }
+ // Finally, update
+ ncurses_wrefresh( $this->window );
+ ncurses_doupdate();
+ $this->emit('change', $this->selected);
+ }
+ /**
+ * Load a recordset
+ *
+ * Recordset should be an array in the following format:
+ * array( array( 'key' => 'value', ... ), ... )
+ *
+ * @param array $records Recordset
+ * @return boolean True if recordset loaded successfully, false otherwise
+ */
+ public function load( $records ) {
+ if( !is_array( $records ) ) {
+ return false;
+ }
+ $this->records = array_values( $records );
+ $this->update();
+ return true;
+ }
+
+ public function on_key_press($key) {
+ switch( $key ) {
+ case NCURSES_KEY_UP:
+ $this->update($this->selected - 1);
+ break;
+ case NCURSES_KEY_DOWN:
+ $this->update($this->selected + 1);
+ break;
+ case NCURSES_KEY_PPAGE:
+ $this->update($this->selected - $this->height - 2 );
+ break;
+ case NCURSES_KEY_NPAGE:
+ $this->update($this->selected + $this->height - 2 );
+ break;
+ default:
+ parent::on_key_press($key);
+ }
+ }
+}
+?>
diff --git a/ncurses/ncurses.textinput.php b/ncurses/ncurses.textinput.php
new file mode 100644
index 0000000..b6299eb
--- /dev/null
+++ b/ncurses/ncurses.textinput.php
@@ -0,0 +1,135 @@
+last_value = $this->value = $value;
+ $this->filter = $filter !== false && @preg_match( $filter, '' ) !== false ? $filter : false;
+ $this->update();
+ }
+ /**
+ * Update the input control on the screen
+ *
+ * Widget is highlighted when active
+ */
+ public function update() {
+ $this->attribute_on( NCURSES_A_UNDERLINE );
+ if( $this->active ) {
+ $this->attribute_on( NCURSES_A_REVERSE );
+ }
+ $this->write_fixed( 0, 0, substr( $this->value, - $this->width ) );
+ $this->attribute_off( NCURSES_A_UNDERLINE );
+ $this->attribute_off( NCURSES_A_REVERSE );
+ }
+ /**
+ * Get or set value
+ */
+ public function value( $value = false ) {
+ if( $value === false ) {
+ return $this->value;
+ } else {
+ $this->value = $value;
+ }
+ }
+ /**
+ * Activate input widget and accept input
+ *
+ * Input ends when the user presses the enter key.
+ * If a filter has been set and the input does not pass the filter, the value
+ * reverts to the previous value, and this function returns false.
+ *
+ * @return string|boolean Text entered, or false
+ */
+ public function get() {
+ $this->active = true;
+ $this->update();
+ while( $this->active ) {
+ $key = $this->get_char();
+ switch( $key ) {
+ case NCURSES_KEY_BACKSPACE:
+ $this->value = substr( $this->value, 0, strlen( $this->value ) - 1 );
+ break;
+ case 13:
+ $this->active = false;
+ break;
+ default:
+ if( in_array( $key, range( 32, 126 ) ) ) {
+ $this->value .= chr( $key );
+ }
+ }
+ $this->update();
+ }
+ $this->update();
+ return $this->filter !== false && @preg_match( $this->filter, $this->value ) < 1 ? false : $this->value;
+ }
+ public function focus() {
+ parent::focus();
+ $this->active = true;
+ $this->update();
+ }
+ public function blur() {
+ $this->active = false;
+ $this->update();
+ parent::blur();
+ }
+ public function on_key_press($key) {
+ switch( $key ) {
+ case NCURSES_KEY_BACKSPACE:
+ $this->value = substr( $this->value, 0, strlen( $this->value ) - 1 );
+ break;
+ case 27:
+ // ESC
+ $this->value = $this->last_value;
+ break;
+ case 9:
+ // TAB
+ case 13:
+ // RETURN
+ if( $this->value !== $this->last_value ) {
+ $this->emit('change', $this->value);
+ }
+ $this->blur();
+ break;
+ default:
+ if( in_array( $key, range( 32, 126 ) ) ) {
+ $this->value .= chr( $key );
+ }
+ parent::on_key_press($key);
+ }
+ $this->update();
+ }
+}
+?>
diff --git a/ncurses/ncurses.window.php b/ncurses/ncurses.window.php
new file mode 100644
index 0000000..9b80756
--- /dev/null
+++ b/ncurses/ncurses.window.php
@@ -0,0 +1,425 @@
+
+* @copyright Copyright (c) 2008, Correl J. Roush
+* @version 0.1
+*
+* @package Nc
+*/
+
+require_once('signals.php');
+
+/**
+* Ncurses window
+*
+* Provides a basic window object. A border can be optionally enabled if the window
+* is large enough to accomodate it, and is enabled by default. If a title is set,
+* it will be visible at the top of the border if one exists.
+*
+* If a parent window is provided, the window will be registered as a child of the
+* parent, and will be relatively positioned to the parent.
+*
+* @package Nc
+*/
+class NcWindow extends Signaler {
+ protected static $max_id = 0;
+ protected $id = 0;
+ /**
+ * @var resource nc_window resource for the border window, if one exists
+ */
+ protected $frame;
+ /**
+ * @var resource nc_window resource for the container window
+ */
+ protected $window;
+ /**
+ * @var array nc_panel resources for the window and its container
+ */
+ protected $panels = array();
+ /**
+ * @var array children array of child NcWindow references
+ */
+ protected $children = array();
+ /**
+ * @var NcWindow reference to this object's direct parent, if one exists
+ */
+ protected $parent = false;
+ protected $app = false;
+ /**
+ * @var int ID of the current active object
+ */
+ public static $active_window = false;
+ public static $windows = array();
+ /**
+ * @var integer Absolute column position of the window
+ */
+ protected $x;
+ /**
+ * @var integer Absolute row position of the window
+ */
+ protected $y;
+ /**
+ * @var integer Width of contained window
+ */
+ protected $width;
+ /**
+ * @var integer Height of contained window
+ */
+ protected $height;
+ /**
+ * @var string Window title
+ */
+ protected $title;
+ protected $enabled = true;
+ protected $visible = true;
+ protected $shortcuts = array();
+ protected $emit_log_filter = array('keypress');
+
+ /**
+ * Constructor
+ *
+ * Builds the requested ncurses window.
+ *
+ * @param NcWindow $parent Parent window
+ * @param integer $height Height
+ * @param integer $width Width
+ * @param integer $y Row
+ * @param integer $x Column
+ * @param boolean $framed Include a frame (border). Required for window titles.
+ */
+ public function __construct( &$parent, $height, $width, $y, $x, $framed = true ) {
+ $this->id = count(self::$windows);
+ self::$windows[] = &$this;
+ if( self::$active_window === false ) {
+ self::$active_window = $this->id;
+ }
+ if( $parent instanceof NcWindow ) {
+ $this->parent = &$parent;
+ $this->app = &$parent->app;
+ $x += $parent->x;
+ $y += $parent->y;
+ $width += $width <= 0 ? $parent->width : 0;
+ $height += $height <= 0 ? $parent->height : 0;
+ } elseif( $parent instanceof NcApp ) {
+ $this->app = &$parent;
+ }
+ if( $framed ) {
+ $this->frame = ncurses_newwin( $height, $width, $y, $x );
+ ncurses_getmaxyx( $this->frame, $max_y, $max_x );
+ if( $max_y >= 2 && $max_x >= 2 ) {
+ $this->window = ncurses_newwin( $max_y - 2, $max_x - 2, $y + 1, $x + 1 );
+ ncurses_wborder( $this->frame, 0,0, 0,0, 0,0, 0,0 );
+ ncurses_wrefresh( $this->frame );
+ $this->panels[] = ncurses_new_panel( $this->frame );
+ } else {
+ $this->window = $this->frame;
+ $this->frame = false;
+ }
+ } else {
+ $this->frame = false;
+ $this->window = ncurses_newwin( $height, $width, $y, $x );
+ ncurses_getmaxyx( $this->window, $max_y, $max_x );
+ }
+ $this->width = $this->frame ? $max_x - 2 : $max_x;
+ $this->height = $this->frame ? $max_y - 2 : $max_y;
+ $this->x = $this->frame ? $x + 1 : $x;
+ $this->y = $this->frame ? $y + 1 : $y;
+ ncurses_wrefresh( $this->window );
+ $this->panels[] = ncurses_new_panel( $this->window );
+ ncurses_update_panels();
+ if( $this->parent instanceof NcWindow ) {
+ $this->parent->add_child( $this );
+ }
+
+ self::connect($this, '__emit', $this, '__emit');
+ }
+ /**
+ * Destructor
+ */
+ public function __destruct() {
+ foreach( $this->panels as $id => $panel ) {
+ ncurses_del_panel( $this->panels[$id] );
+ }
+ ncurses_delwin( $this->window );
+ if( $this->frame !== false ) {
+ ncurses_delwin( $this->frame );
+ }
+ }
+
+ static public function get_window($id) {
+ return self::$windows[$id];
+ }
+ /**
+ * Set or retrieve a window title
+ *
+ * Sets window title to the value provided, returns the current window title
+ * if one is not.
+ *
+ * @param string $value New window title
+ * @return string Window title
+ */
+ public function title( $value = false ) {
+ if( $value === false ) {
+ return $this->title;
+ } elseif( $this->frame !== false ) {
+ $this->title = $value;
+ ncurses_wborder( $this->frame, 0,0, 0,0, 0,0, 0,0 );
+ ncurses_mvwaddstr( $this->frame, 0, 1, $this->title );
+ ncurses_update_panels();
+ ncurses_doupdate();
+ }
+ }
+ public function height() { return $this->height; }
+ public function width() { return $this->width; }
+ public function enabled() { return (bool)$this->enabled; }
+ public function active() { return (bool)($this->id === self::$active_window); }
+ /**
+ * Activate an ncurses output attribute
+ *
+ * @param integer NCURSES_A_* constant
+ */
+ public function attribute_on( $attribute ) {
+ ncurses_wattron( $this->window, $attribute );
+ }
+ /**
+ * Deactivate an ncurses output attribute
+ *
+ * @param integer NCURSES_A_* constant
+ */
+ public function attribute_off( $attribute ) {
+ ncurses_wattroff( $this->window, $attribute );
+ }
+ /**
+ * Write text to the window
+ *
+ * Writes text to the window at the specified coordinates.
+ * Text is truncated to prevent it overflowing off the side of the window. If
+ * the text contains newlines, it is split and each new line will continue from
+ * the same x position as the first, rather than wrapping back to the far left
+ * side of the window as ncurses normally would.
+ *
+ * @param integer $y Row
+ * @param integer $x Column
+ * @param string $text Text to write
+ * @param boolean $update Update the window upon completion
+ */
+ public function write( $y, $x, $text, $update = true ) {
+ $y = $y < 0 ? $this->height + $y : $y;
+ $x = $x < 0 ? $this->width + $x : $x;
+ $lines = preg_split( '/\r?(\n|\r)/', $text );
+ foreach( $lines as $id => $line ) {
+ $line = substr( $line, 0, $this->width - $x );
+ ncurses_mvwaddstr( $this->window, $y + $id, $x, $line );
+ }
+ if( $update ) {
+ ncurses_update_panels();
+ ncurses_doupdate();
+ }
+ }
+ /**
+ * Write centered text
+ *
+ * Writes text centered horizontally within the window on the specified line.
+ *
+ * @param integer $y Row
+ * @param string $text Text to write
+ * @param boolean $update Update the window upon completion
+ */
+ public function write_centered( $y, $text, $update = true ) {
+ $this->write(
+ $y,
+ floor( $this->width / 2 ) - floor( strlen( $text ) / 2 ),
+ $text,
+ $update
+ );
+ }
+ /**
+ * Write fixed-width text
+ *
+ * Writes a string truncated or padded with spaces to fill the requested width.
+ * If the width is unspecified or zero, the width is defined as the length from
+ * the starting coordinate to the right edge of the window.
+ *
+ * @param integer $y Row
+ * @param integer $x Column
+ * @param string $text Text to write
+ * @param integer $width Field length
+ * @param boolean $update Update the window upon completion
+ */
+ public function write_fixed( $y, $x, $text, $width = 0, $update = true ) {
+ $width = $width > 0 ? $width : $this->width - $x;
+ $this->write( $y, $x, $this->_string_fixed( $text, $width ), $update );
+ }
+ /**
+ * Build a fixed-width string
+ *
+ * Truncates a string if it exceeds the specified width, pads it with spaces
+ * if it is too short.
+ *
+ * @param string $text Text to format
+ * @param integer $width Field length
+ * @return string Fixed-width string
+ */
+ protected function _string_fixed( $text, $width = 0 ) {
+ $width = $width < 0 ? 0 : $width;
+ $text = substr( $text, 0, $width );
+ $text .= str_repeat( ' ', $width - strlen( $text ) );
+ return $text;
+ }
+ /**
+ * Assign a window as a child of this window
+ *
+ * Children of a window are hidden and shown along with their parent widget.
+ *
+ * @param NcWindow $child Child window
+ */
+ public function add_child( $child ) {
+ $this->children[$child->id] = $child;
+ if( count($this->children) == 1 ) {
+ // Make the first child active
+ self::$active_window = $child->id;
+ $child->focus();
+ }
+ }
+ /**
+ * Hide the window
+ *
+ * @param boolean $update Update the window upon completion
+ */
+ public function hide( $update = true ) {
+ foreach( $this->panels as $panel ) {
+ ncurses_hide_panel( $panel );
+ }
+ foreach( $this->children as $child ) {
+ $child->hide( false );
+ }
+ if( $update ) {
+ ncurses_update_panels();
+ ncurses_doupdate();
+ }
+ $this->visible = false;
+ }
+ /**
+ * Show the window
+ *
+ * @param boolean $update Update the window upon completion
+ */
+ public function show( $update = true ) {
+ foreach( $this->panels as $panel ) {
+ ncurses_show_panel( $panel );
+ }
+ foreach( $this->children as $child ) {
+ $child->show( false );
+ }
+ if( $update ) {
+ ncurses_update_panels();
+ ncurses_doupdate();
+ }
+ $this->visible = true;
+ }
+ /**
+ * Clear the window's contents
+ *
+ * @param boolean $update Update the window upon completion
+ */
+ public function erase( $update = true ) {
+ ncurses_werase( $this->window );
+ if( $update ) {
+ ncurses_wrefresh( $this->window );
+ ncurses_doupdate();
+ }
+ }
+ /**
+ * Read a character from the keyboard and return it
+ *
+ * @param boolean $flush Flush the input buffer before requesting a key
+ * @return integer Keycode
+ */
+ public function get_char( $flush = true ) {
+ if( $flush ) {
+ ncurses_flushinp();
+ }
+ return ncurses_getch();
+ //return ncurses_wgetch( $this->window );
+ }
+
+ public function shortcut($key, $object = null) {
+ $key = ord(strtolower(chr($key)));
+ if( $object !== null ) {
+ $this->shortcuts[$key] = $object;
+ } elseif( in_array($key, array_keys($this->shortcuts)) ) {
+ unset($this->shortcuts[$key]);
+ }
+ }
+ /* Event slots */
+ public function log($message) {
+ if( $this->app ) {
+ $this->app->log($this, "[{$this->id}] $message");
+ }
+ }
+ public function __emit($signal, $args) {
+ if( !in_array($signal, $this->emit_log_filter) ) {
+ foreach($args as $key => $value) {
+ $args[$key] = (string)$value;
+ }
+ $args = implode(',', $args);
+ $this->log("Emitted {$signal}({$args})");
+ }
+ }
+ public function focus() {
+ self::$active_window = $this->id;
+ $this->emit('focus');
+ }
+ public function blur() {
+ $this->emit('blur');
+ if( $this->parent instanceof NcWindow ) {
+ $this->parent->focus_next();
+ }
+ }
+ public function disable() {
+ $this->enabled = false;
+ $this->blur();
+ }
+ public function focus_next() {
+ $next = false;
+ $first = false;
+ foreach( $this->children as $child ) {
+ if( $child->visible && $child->enabled ) {
+ if( $first === false ) {
+ $first = $child;
+ }
+ $next = &$child;
+ if( self::$active_window && $next->id > self::$active_window ) {
+ break;
+ }
+ }
+ }
+ if( $next === false ) {
+ $next = &$this;
+ } elseif( $next->id == self::$active_window ) {
+ $next = &$first;
+ }
+ $next->focus();
+ }
+ public function on_key_press($key) {
+ if( self::$active_window === $this->id ) {
+ // This is the active window, handle input
+ switch($key) {
+ case 9:
+ // TAB
+ $this->blur();
+ break;
+ }
+ } else {
+ // Pass it along to the active child widget
+ self::get_window(self::$active_window)->on_key_press($key);
+ }
+ $this->emit('keypress', $key);
+ }
+}
+?>
diff --git a/ncurses/signals.php b/ncurses/signals.php
new file mode 100644
index 0000000..cc39ebc
--- /dev/null
+++ b/ncurses/signals.php
@@ -0,0 +1,53 @@
+_listeners) ) {
+ $emitter->_listeners[$signal] = array();
+ }
+ $emitter->_listeners[$signal][] = array(
+ 'object' => &$responder,
+ 'method' => $slot
+ );
+ }
+ protected function emit() {
+ self::$current = &$this;
+ $args = func_get_args();
+ if( count($args) == 0 ) {
+ // Called without any arguments, raise an error
+ return false;
+ }
+ $signal = array_shift($args);
+ $sent = 0;
+ if( array_key_exists($signal, $this->_listeners) ) {
+ foreach( $this->_listeners[$signal] as $key => $listener ) {
+ if(
+ !is_object($listener['object'])
+ || !method_exists($listener['object'], $listener['method'])
+ ) {
+ // Something happened to the object since it was connected,
+ // and it is no longer usable. Drop it.
+ unset($this->_listeners[$key]);
+ } else {
+ // Everything's good, set the callback loose.
+ $result = call_user_func_array(array($listener['object'], $listener['method']), $args);
+ if( $result !== false ) {
+ $sent++;
+ }
+ }
+ }
+ }
+ // Special signal for debugging purposes
+ if( $signal !== '__emit' ) { $this->emit('__emit', $signal, $args); }
+ return $sent;
+ }
+}
+?>
diff --git a/scanner.php b/scanner.php
index c6e6def..b723c89 100644
--- a/scanner.php
+++ b/scanner.php
@@ -361,10 +361,10 @@ if( $curses ) {
$nc_faults->update( $nc_faults->selected + 1 );
break;
case NCURSES_KEY_PPAGE:
- $nc_faults->update( $nc_faults->selected - $nc_faults->height - 1 );
+ $nc_faults->update( $nc_faults->selected - $nc_faults->height() - 1 );
break;
case NCURSES_KEY_NPAGE:
- $nc_faults->update( $nc_faults->selected + $nc_faults->height - 1 );
+ $nc_faults->update( $nc_faults->selected + $nc_faults->height() - 1 );
break;
case 10:
case 13:
@@ -395,8 +395,8 @@ if( $curses ) {
$filename = $nc_save_file_input->get();
$nc_save_confirm = new NcWindow( $nc_save, -10, -10, 5, 5 );
$nc_save_confirm->title( get_class( $modules['output'] ) );
- $nc_save_confirm->write_centered( floor( $nc_save_confirm->height / 2 ) - 2, "Save results to '{$filename}'?" );
- $nc_save_confirm->write_centered( floor( $nc_save_confirm->height / 2 ), '[Y]es [N]o [C]ancel' );
+ $nc_save_confirm->write_centered( floor( $nc_save_confirm->height() / 2 ) - 2, "Save results to '{$filename}'?" );
+ $nc_save_confirm->write_centered( floor( $nc_save_confirm->height() / 2 ), '[Y]es [N]o [C]ancel' );
$valid_key = false;
while( !$valid_key ) {
switch( $nc_save_confirm->get_char() ) {
@@ -417,8 +417,8 @@ if( $curses ) {
$result = $modules['output']->write( $filename );
$save_message = ( $result === false ) ? 'Save Failed' : 'Saved successfully';
$nc_save_confirm->erase();
- $nc_save_confirm->write_centered( floor( $nc_save_confirm->height / 2 ) - 2, $save_message );
- $nc_save_confirm->write_centered( floor( $nc_save_confirm->height / 2 ), 'Press any key to continue' );
+ $nc_save_confirm->write_centered( floor( $nc_save_confirm->height() / 2 ) - 2, $save_message );
+ $nc_save_confirm->write_centered( floor( $nc_save_confirm->height() / 2 ), 'Press any key to continue' );
$nc_save_confirm->show();
$nc_save_confirm->get_char();
}