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