menubar.c

Go to the documentation of this file.
00001 
00014 #include "menubar.h"
00015 
00016 #include <gfx/gfx.h>
00017 #include <gfx/text.h>
00018 #include <gfx/font.h>
00019 #include <cfg/compiler.h>
00020 
00021 #if CPU_AVR
00022     #include <avr/pgmspace.h> /* strlen_P() */
00023 #else
00024     #define strlen_P(s)             strlen(s)
00025     #define text_puts_P(s, b)       text_puts(s, b)
00026     #define pgm_read_uint16_t(addr) (*(addr))
00027 #endif
00028 
00029 #include <string.h> /* strlen, memcpy */
00030 
00031 
00033 static const pgm_char lab_1[]  = "";
00034 static const pgm_char lab_2[]  = "mute";
00035 static const pgm_char lab_3[]  = "menu";
00036 static const pgm_char lab_4[]  = "back";
00037 static const pgm_char lab_5[]  = " ok ";
00038 static const pgm_char lab_6[]  = "Ch 1";
00039 static const pgm_char lab_7[]  = "Ch 2";
00040 static const pgm_char lab_8[]  = "C1+2";
00041 static const pgm_char lab_9[]  = " "UP_ARROW" ";
00042 static const pgm_char lab_10[] = " "DOWN_ARROW" ";
00043 static const pgm_char lab_11[] = " - ";
00044 static const pgm_char lab_12[] = " + ";
00045 static const pgm_char lab_13[] = "sel ";
00046 #if OEM_BRAND == OEM_CLAIRBROS
00047 static const pgm_char lab_14[] = "gain";
00048 #else
00049 static const pgm_char lab_14[] = "lock";
00050 #endif
00051 static const pgm_char lab_15[] = "unlock";
00052 static const pgm_char lab_16[] = "more";
00053 static const pgm_char lab_17[] = "edit";
00054 static const pgm_char lab_18[] = "fast";
00055 static const pgm_char lab_19[] = LEFT_ARROW" ";
00056 static const pgm_char lab_20[] = " "RIGHT_ARROW;
00057 static const pgm_char lab_21[] = "slow";
00058 static const pgm_char lab_22[] = "yes";
00059 static const pgm_char lab_23[] = "no";
00060 
00061 
00062 static const pgm_char * PROGMEM label_strings[LABEL_CNT] = {
00063     lab_1, lab_2, lab_3, lab_4, lab_5, lab_6, lab_7, lab_8, lab_9,
00064     lab_10, lab_11, lab_12, lab_13, lab_14, lab_15, lab_16, lab_17,
00065     lab_18, lab_19, lab_20, lab_21, lab_22, lab_23
00066 };
00067 
00073 #define PTRLBL(x) ((unsigned int)(x) < 256 ? \
00074     (const pgm_char *)pgm_read_uint16_t(label_strings + (unsigned int)(x)) \
00075     : (const pgm_char *)(x))
00076 
00077 
00082 void mbar_init(
00083         struct MenuBar *mb,
00084         struct Bitmap *bmp,
00085         const_iptr_t labels[],
00086         int num_labels)
00087 {
00088     mb->bitmap     = bmp;
00089     mb->labels     = labels;
00090     mb->num_labels = num_labels;
00091 }
00092 
00093 
00097 void mbar_draw(const struct MenuBar *mb)
00098 {
00099     uint8_t oldstyle;
00100     int i;
00101     size_t maxlen = 0;  /* Length of the longest label */
00102     coord_t x1, x2, y1, y2, label_padding;
00103 
00104     /* Maximum space available for a label */
00105     coord_t slot_width = mb->bitmap->width / mb->num_labels;
00106 
00107     /* Find longest label */
00108     for (i = 0; i < mb->num_labels; i++)
00109         if (strlen_P(PTRLBL(mb->labels[i])) > maxlen)
00110             maxlen = strlen_P(PTRLBL(mb->labels[i]));
00111 
00112     oldstyle = text_style(mb->bitmap, STYLEF_INVERT, STYLEF_MASK);
00113 
00114     /* y coords for menubar: bottom of the bitmap */
00115     y1 = mb->bitmap->height - FONT_HEIGHT;
00116     y2 = mb->bitmap->height;
00117 
00118     /* Clear menubar area */
00119     gfx_rectClear(mb->bitmap, 0, y1, mb->bitmap->width, y2);
00120 
00121     for (i = 0; i < mb->num_labels; i++)
00122     {
00123         size_t lablen = strlen_P(PTRLBL(mb->labels[i]));
00124 
00125         /* Don't draw empty labels */
00126         if (mb->labels[i] == (const_iptr_t)LABEL_EMPTY)
00127             continue;
00128 
00129         /* x coords: magic formula for equal distribution of the
00130          * labels along bitmap
00131          */
00132         label_padding = slot_width - (FONT_WIDTH * lablen + 2);
00133         x1 = i * (slot_width + (label_padding / (mb->num_labels - 1)));
00134         x2 = x1 + lablen * FONT_WIDTH + 1;
00135 
00136         /* Draw vertical line before.
00137          * Uncomment +1 for "rounded" menubars */
00138         gfx_line(mb->bitmap, x1, y1 /* + 1 */, x1, y2);
00139 
00140         /* Draw text */
00141         text_setCoord(mb->bitmap, x1 + 1, y1);
00142         text_puts_P(PTRLBL(mb->labels[i]), mb->bitmap);
00143 
00144         /* Draw vertical line after
00145          * Uncomment +1 for "rounded" menubars */
00146         gfx_line(mb->bitmap, x2, y1 /* + 1 */, x2, y2);
00147     }
00148 
00149     text_style(mb->bitmap, oldstyle, STYLEF_MASK);
00150 }