00001
00039 #include "leveledit.h"
00040
00041 #include "cfg/cfg_gfx.h"
00042 #include <cfg/macros.h>
00043
00044 #include <drv/kbd.h>
00045 #include <drv/timer.h>
00046
00047 #include <gui/levelbar.h>
00048
00049 #include <cpu/pgm.h>
00050
00051 #include <gfx/text.h>
00052 #include <gfx/font.h>
00053
00054 #if CONFIG_MENU_MENUBAR
00055 #include <gui/menubar.h>
00056 #endif
00057
00058 #include <drv/lcd_gfx.h>
00059
00060 #warning FIXME: Revise me!
00061
00062 #define LBAR_HEIGHT 16
00063
00067 void level_edit(struct LevelEdit *lev)
00068 {
00069 #if CONFIG_MENU_MENUBAR
00070
00071 enum LabelId ch_labels[] = { LABEL_C1PLUS2, LABEL_CH_1, LABEL_CH_2 };
00072 const_iptr_t labels[] =
00073 {
00074 (const_iptr_t)LABEL_BACK,
00075 (const_iptr_t)LABEL_MINUS,
00076 (const_iptr_t)LABEL_PLUS,
00077 (const_iptr_t)LABEL_EMPTY
00078 };
00079 struct MenuBar mb;
00080 #endif
00081
00082 struct LevelBar bar1, bar2;
00083 keymask_t keys, old_rpt_mask;
00084 int step, rep_step;
00085
00086 rep_step = MAX(lev->step, ((lev->max - lev->min) / 200));
00087 step = lev->step;
00088
00089
00090 old_rpt_mask = kbd_setRepeatMask(K_UP | K_DOWN);
00091
00092 text_clear(lev->bitmap);
00093
00094 text_puts(lev->title, lev->bitmap);
00095
00096
00097 if (lev->type & LEVELEDIT_DOUBLE)
00098 {
00099 int chn = 0;
00100
00101
00102 lbar_init(&bar1, lev->bitmap, LBAR_HORIZONTAL,
00103 lev->min, lev->max, *lev->ch1_val, 0, 16, lev->bitmap->width / 2 - 1, 23);
00104 lbar_init(&bar2, lev->bitmap, LBAR_HORIZONTAL,
00105 lev->min, lev->max, *lev->ch2_val, lev->bitmap->width / 2 + 1, 16, lev->bitmap->width, 23);
00106
00107 #if CONFIG_MENU_MENUBAR
00108 labels[3] = (const_iptr_t)ch_labels[chn];
00109 mbar_init(&mb, lev->bitmap, labels, countof(labels));
00110 mbar_draw(&mb);
00111 #endif
00112
00113
00114 for (;;)
00115 {
00116 #if CONFIG_LEVELEDIT_TIMEOUT != 0
00117 ticks_t idle_timeout = timer_clock();
00118 #endif
00119 do
00120 {
00121 if (lev->display_hook)
00122 lev->display_hook(lev);
00123 else
00124 {
00125 text_xprintf(lev->bitmap, 1, 0, TEXT_CENTER | TEXT_FILL, lev->unit);
00126 PGM_FUNC(text_xprintf)(lev->bitmap, 1, 3, 0, PGM_STR("%d"), *lev->ch1_val);
00127 PGM_FUNC(text_xprintf)(lev->bitmap, 1, 14, 0, PGM_STR("%d"), *lev->ch2_val);
00128
00129 lbar_setLevel(&bar1, *lev->ch1_val);
00130 lbar_setLevel(&bar2, *lev->ch2_val);
00131 lbar_draw(&bar1);
00132 lbar_draw(&bar2);
00133 }
00134
00135 #if CONFIG_LEVELEDIT_TIMEOUT != 0
00136 if (timer_clock() - idle_timeout > ms_to_ticks(CONFIG_LEVELEDIT_TIMEOUT))
00137 {
00138
00139 keys = K_OK;
00140 break;
00141 }
00142 #endif
00143 }
00144 while (!(keys = kbd_peek()));
00145
00146 if (keys & K_CANCEL)
00147 break;
00148
00149 if (keys & K_OK)
00150 {
00151 chn = (chn + 1) % 3;
00152
00153 #if CONFIG_MENU_MENUBAR
00154 labels[3] = (const_iptr_t)ch_labels[chn];
00155 mbar_draw(&mb);
00156 #endif
00157 }
00158
00159
00160 if (keys & K_REPEAT)
00161 step = MIN(rep_step, step + 1);
00162 else
00163 step = lev->step;
00164
00165 if (keys & (K_UP | K_DOWN))
00166 {
00167 if (keys & K_UP)
00168 {
00169
00170
00171 if (chn != 0 ||
00172 (*lev->ch1_val + step <= lev->max
00173 && *lev->ch2_val + step <= lev->max))
00174 {
00175
00176 if (chn != 2)
00177 {
00178 *lev->ch1_val += step;
00179 if (*lev->ch1_val > lev->max)
00180 *lev->ch1_val = lev->max;
00181 }
00182 if (chn != 1)
00183 {
00184 *lev->ch2_val += step;
00185 if (*lev->ch2_val > lev->max)
00186 *lev->ch2_val = lev->max;
00187 }
00188 }
00189 }
00190 else
00191 {
00192 if (chn != 0 ||
00193 (*lev->ch1_val - step >= lev->min
00194 && *lev->ch2_val - step >= lev->min))
00195 {
00196 if (chn != 2)
00197 {
00198 *lev->ch1_val -= step;
00199 if (*lev->ch1_val < lev->min)
00200 *lev->ch1_val = lev->min;
00201 }
00202 if (chn != 1)
00203 {
00204 *lev->ch2_val -= step;
00205 if (*lev->ch2_val < lev->min)
00206 *lev->ch2_val = lev->min;
00207 }
00208 }
00209 }
00210
00211 if (lev->set_hook)
00212 lev->set_hook();
00213 }
00214 }
00215 }
00216 else
00217 {
00218 const PGM_ATTR char *fmt = lev->unit ? PGM_STR("%d %s") : PGM_STR("%d");
00219
00220
00221
00222
00223
00224
00225
00226 const coord_t barlen = lev->bitmap->width;
00227 const coord_t barvtop = lev->bitmap->height / 2 - LBAR_HEIGHT/2 + lev->bitmap->font->height;
00228 lbar_init(&bar1, lev->bitmap, LBAR_HORIZONTAL,
00229 lev->min, lev->max, *lev->ch1_val,
00230 0, barvtop, barlen, barvtop + LBAR_HEIGHT);
00231
00232 #if CONFIG_MENU_MENUBAR
00233 mbar_init(&mb, lev->bitmap, labels, countof(labels));
00234 mbar_draw(&mb);
00235 #endif
00236
00237
00238 for (;;)
00239 {
00240 #if CONFIG_LEVELEDIT_TIMEOUT != 0
00241 ticks_t idle_timeout = timer_clock();
00242 #endif
00243 do
00244 {
00245 if (lev->display_hook)
00246 lev->display_hook(lev);
00247 else
00248 {
00249 if (lev->type != LEVELEDIT_NOBAR)
00250 {
00251 lbar_setLevel(&bar1, *lev->ch1_val);
00252 lbar_draw(&bar1);
00253 }
00254 PGM_FUNC(text_xyprintf)(lev->bitmap, 0, bar1.y1 - lev->bitmap->font->height,
00255 TEXT_CENTER | TEXT_FILL, fmt, *lev->ch1_val, lev->unit);
00256 }
00257
00258 #if CONFIG_LEVELEDIT_TIMEOUT != 0
00259 if (timer_clock() - idle_timeout > CONFIG_LEVELEDIT_TIMEOUT)
00260 {
00261
00262 keys = K_CANCEL;
00263 break;
00264 }
00265 #endif
00266
00267 }
00268 while (!(keys = kbd_peek()));
00269
00270 if (keys & K_CANCEL)
00271 break;
00272
00273
00274 if (keys & K_REPEAT)
00275 step = MIN(rep_step, step + 1);
00276 else
00277 step = lev->step;
00278
00279 if (keys & K_UP)
00280 {
00281 *lev->ch1_val += step;
00282 if (*lev->ch1_val > lev->max)
00283 *lev->ch1_val = lev->max;
00284 }
00285
00286 if (keys & K_DOWN)
00287 {
00288 *lev->ch1_val -= step;
00289 if (*lev->ch1_val < lev->min)
00290 *lev->ch1_val = lev->min;
00291 }
00292
00293 if (lev->set_hook)
00294 lev->set_hook();
00295 }
00296 }
00297
00298 kbd_setRepeatMask(old_rpt_mask);
00299 }
00300
00305 void level_init(struct LevelEdit *lev,
00306 int type,
00307 struct Bitmap *bmp, const char *title, const char *unit,
00308 int min, int max, int step,
00309 int *ch1_val, int *ch2_val,
00310 level_set_callback *set_hook, display_callback *display_hook)
00311 {
00312 lev->type = type;
00313 lev->bitmap = bmp;
00314 lev->title = title;
00315 lev->unit = unit;
00316 lev->min = min;
00317 lev->max = max;
00318 lev->step = step;
00319
00320 lev->ch1_val = ch1_val;
00321 lev->ch2_val = ch2_val;
00322 lev->set_hook = set_hook;
00323 lev->display_hook = display_hook;
00324 }