- major implementation work completed (testing in progress)
authorDan Lynch <danjlynch@users.sourceforge.net>
Wed, 21 Jun 2006 10:21:40 +0000 (10:21 +0000)
committerDan Lynch <danjlynch@users.sourceforge.net>
Wed, 21 Jun 2006 10:21:40 +0000 (10:21 +0000)
- some optimisation done

src/hci/mucurses/slk.c

index 6833ead..41ef9ab 100644 (file)
@@ -4,7 +4,53 @@
 #include <string.h>
 #include "core.h"
 
-extern struct _softlabelkeys *slks;
+/** @file
+ *
+ * Soft label key functions
+ */
+
+#define MIN_SPACE_SIZE 2
+
+struct _softlabel {
+       // label string
+       char *label;
+       /* Format of soft label 
+          0: left justify
+          1: centre justify
+          2: right justify
+        */
+       unsigned short fmt;
+};
+
+struct _softlabelkeys {
+       struct _softlabel fkeys[12];
+       attr_t attrs;
+       /* Soft label layout format
+          0: 3-2-3
+          1: 4-4
+          2: 4-4-4
+          3: 4-4-4 with index line
+       */
+       unsigned short fmt;
+       unsigned short max_label_len;
+       unsigned short maj_space_len;
+       unsigned short num_labels;
+       unsigned short num_spaces;
+       unsigned short *spaces;
+};
+
+struct _softlabelkeys *slks;
+
+/*
+  I either need to break the primitives here, or write a collection of
+  functions specifically for SLKs that directly access the screen
+  functions - since this technically isn't part of stdscr, I think
+  this should be ok...
+ */
+
+static void _movetoslk ( void ) {
+       stdscr->scr->movetoyx( stdscr->scr, LINES, 0 );
+}
 
 /**
  * Return the attribute used for the soft function keys
@@ -105,12 +151,24 @@ int slk_attr_set ( const attr_t attrs, short colour_pair_number,
 int slk_clear ( void ) {
        if ( slks == NULL )
                return ERR;
-
-       wmove(stdscr,stdscr->height-1,0);
-       wclrtoeol(stdscr);
        return 0;
 }
 
+/**
+ * Set soft label colour pair
+ */
+int slk_colour ( short colour_pair_number ) {
+       if ( slks == NULL ) 
+               return ERR;
+       if ( ( unsigned short )colour_pair_number > COLORS )
+               return ERR;
+
+       slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT )
+               | ( slks->attrs & A_ATTRIBUTES );
+
+       return OK;
+}
+
 /**
  * Initialise the soft function keys
  *
@@ -118,14 +176,44 @@ int slk_clear ( void ) {
  * @ret rc     return status code
  */
 int slk_init ( int fmt ) {
+       unsigned short nmaj, nmin, nblocks, available_width;
+
        if ( (unsigned)fmt > 3 ) {
                return ERR;
        }
 
        slks = malloc(sizeof(struct _softlabelkeys));
        slks->attrs = A_DEFAULT;
-       slks->fmt = (unsigned short)fmt;
-       slks->maxlablen = 5;
+       slks->fmt = fmt;
+       switch(fmt) {
+       case 0:
+               nblocks = 8; nmaj = 2; nmin = 5;
+               slks->spaces = calloc(2, sizeof(unsigned short));
+               slks->spaces[0] = 2; slks->spaces[1] = 4;
+               break;
+       case 1:
+               nblocks = 8; nmaj = 1; nmin = 6;
+               slks->spaces = calloc(1, sizeof(unsigned short));
+               slks->spaces[0] = 3;
+               break;
+       case 2:
+               // same allocations as format 3
+       case 3:
+               nblocks = 12; nmaj = 2; nmin = 9;
+               slks->spaces = calloc(2, sizeof(unsigned short));
+               slks->spaces[0] = 3; slks->spaces[1] = 7;
+               break;
+       }
+
+       // determine maximum label length and major space size
+       available_width = COLS - ( ( MIN_SPACE_SIZE * nmaj ) + nmin );
+       slks->max_label_len = available_width / nblocks;
+       slks->maj_space_len = ( available_width % nblocks ) / nmaj;
+       slks->num_spaces = nmaj;
+
+       // strip a line from the screen
+       LINES -= 1;
+
        return OK;
 }
 
@@ -148,9 +236,34 @@ char* slk_label ( int labnum ) {
  * @ret rc     return status code
  */
 int slk_restore ( void ) {
+       unsigned short i, j,
+               *next_space, *last_space;
+       chtype space_ch;
+       char c;
+
        if ( slks == NULL ) 
                return ERR;
 
+       _movetoslk();
+
+       space_ch = (int)' ' | slks->attrs;
+       next_space = &(slks->spaces[0]);
+       last_space = &(slks->spaces[slks->num_spaces-1]);
+
+       for ( i = 0; i < slks->num_labels ; i++ ) {
+               while ( ( c = *(slks->fkeys[i].label++) ) != '\0' ) {
+                       stdscr->scr->putc( stdscr->scr, (int)c | slks->attrs );
+               }
+               if ( i == *next_space ) {
+                       for ( j = 0; j < slks->maj_space_len; j++ )
+                               stdscr->scr->putc( stdscr->scr, space_ch );
+                       if ( next_space < last_space )
+                               next_space++;
+               } else {
+                       stdscr->scr->putc( stdscr->scr, space_ch );
+               }
+       }
+
        return OK;
 }
 
@@ -169,7 +282,7 @@ int slk_set ( int labnum, const char *label, int fmt ) {
                return ERR;
        if ( (unsigned short)fmt >= 3 )
                return ERR;
-       if ( strlen(label) > slks->maxlablen )
+       if ( strlen(label) > slks->max_label_len )
                return ERR;
 
        strcpy( slks->fkeys[labnum].label, label );