iPXE
jumpscroll.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 /**
00027  * Jump scrolling
00028  *
00029  */
00030 
00031 #include <assert.h>
00032 #include <ipxe/keys.h>
00033 #include <ipxe/jumpscroll.h>
00034 
00035 /**
00036  * Handle keypress
00037  *
00038  * @v scroll            Jump scroller
00039  * @v key               Key pressed by user
00040  * @ret move            Scroller movement, or zero
00041  */
00042 int jump_scroll_key ( struct jump_scroller *scroll, int key ) {
00043 
00044         /* Sanity checks */
00045         assert ( scroll->rows != 0 );
00046         assert ( scroll->count != 0 );
00047         assert ( scroll->current < scroll->count );
00048         assert ( scroll->first < scroll->count );
00049         assert ( scroll->first <= scroll->current );
00050         assert ( scroll->current < ( scroll->first + scroll->rows ) );
00051 
00052         /* Handle key, if applicable */
00053         switch ( key ) {
00054         case KEY_UP:
00055                 return -1;
00056         case KEY_DOWN:
00057                 return +1;
00058         case KEY_PPAGE:
00059                 return ( scroll->first - scroll->current - 1 );
00060         case KEY_NPAGE:
00061                 return ( scroll->first - scroll->current + scroll->rows );
00062         case KEY_HOME:
00063                 return -( scroll->count );
00064         case KEY_END:
00065                 return +( scroll->count );
00066         default:
00067                 return 0;
00068         }
00069 }
00070 
00071 /**
00072  * Move scroller
00073  *
00074  * @v scroll            Jump scroller
00075  * @v move              Scroller movement
00076  * @ret move            Continuing scroller movement (if applicable)
00077  */
00078 int jump_scroll_move ( struct jump_scroller *scroll, int move ) {
00079         int current = scroll->current;
00080         int last = ( scroll->count - 1 );
00081 
00082         /* Sanity checks */
00083         assert ( move != 0 );
00084         assert ( scroll->count != 0 );
00085 
00086         /* Move to the new current item */
00087         current += move;
00088 
00089         /* Check for start/end of list */
00090         if ( current < 0 ) {
00091                 /* We have attempted to move before the start of the
00092                  * list.  Move to the start of the list and continue
00093                  * moving forwards (if applicable).
00094                  */
00095                 scroll->current = 0;
00096                 return +1;
00097         } else if ( current > last ) {
00098                 /* We have attempted to move after the end of the
00099                  * list.  Move to the end of the list and continue
00100                  * moving backwards (if applicable).
00101                  */
00102                 scroll->current = last;
00103                 return -1;
00104         } else {
00105                 /* Update the current item and continue moving in the
00106                  * same direction (if applicable).
00107                  */
00108                 scroll->current = current;
00109                 return ( ( move > 0 ) ? +1 : -1 );
00110         }
00111 }
00112 
00113 /**
00114  * Jump scroll to new page (if applicable)
00115  *
00116  * @v scroll            Jump scroller
00117  * @ret jumped          Jumped to a new page
00118  */
00119 int jump_scroll ( struct jump_scroller *scroll ) {
00120         unsigned int index;
00121 
00122         /* Sanity checks */
00123         assert ( scroll->rows != 0 );
00124         assert ( scroll->count != 0 );
00125         assert ( scroll->current < scroll->count );
00126         assert ( scroll->first < scroll->count );
00127 
00128         /* Do nothing if we are already on the correct page */
00129         index = ( scroll->current - scroll->first );
00130         if ( index < scroll->rows )
00131                 return 0;
00132 
00133         /* Move to required page */
00134         while ( scroll->first < scroll->current )
00135                 scroll->first += scroll->rows;
00136         while ( scroll->first > scroll->current )
00137                 scroll->first -= scroll->rows;
00138 
00139         return 1;
00140 }