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); } } } ?>