BeRTOS
|
00001 00038 #include "leveledit.h" 00039 00040 #include "cfg/cfg_menu.h" 00041 #include <cfg/macros.h> /* MAX() */ 00042 00043 #include <drv/kbd.h> 00044 #include <drv/timer.h> 00045 00046 #include <gui/levelbar.h> 00047 00048 #include <cpu/pgm.h> 00049 00050 #include <gfx/text.h> 00051 #include <gfx/font.h> 00052 00053 #if CONFIG_MENU_MENUBAR 00054 #include <gui/menubar.h> 00055 #endif 00056 00057 #warning FIXME: Revise me! 00058 00059 #define LBAR_HEIGHT 16 00060 00064 void level_edit(struct LevelEdit *lev) 00065 { 00066 #if CONFIG_MENU_MENUBAR 00067 /* Labels for menubars */ 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 /* CONFIG_MENU_MENUBAR */ 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 // Allow keys repetition. 00087 old_rpt_mask = kbd_setRepeatMask(K_UP | K_DOWN); 00088 00089 text_clear(lev->bitmap); 00090 //text_style(STYLEF_UNDERLINE, STYLEF_UNDERLINE); 00091 text_puts(lev->title, lev->bitmap); 00092 //text_style(0, STYLEF_UNDERLINE); 00093 00094 if (lev->type & LEVELEDIT_DOUBLE) 00095 { 00096 int chn = 0; /* edit both channels */ 00097 00098 /* Levelbars init */ 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 /* CONFIG_MENU_MENUBAR */ 00109 00110 /* Input loop for double level setting */ 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 /* Accept input implicitly */ 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 /* CONFIG_MENU_MENUBAR */ 00154 } 00155 00156 /* Increment step to achieve greater accelerations on larger values */ 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 /* If changing both channels (chn == 0), don't change 00167 * level if one of two is at min or max */ 00168 if (chn != 0 || 00169 (*lev->ch1_val + step <= lev->max 00170 && *lev->ch2_val + step <= lev->max)) 00171 { 00172 /* If chn == 0 change both channels */ 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 } // end for(;;) 00212 } 00213 else 00214 { 00215 const PGM_ATTR char *fmt = lev->unit ? PGM_STR("%d %s") : PGM_STR("%d"); 00216 00217 /* 00218 const int textw = MAX(PGM_FUNC(text_widthf)(lev->bitmap, fmt, lev->max, lev->unit), 00219 PGM_FUNC(text_widthf)(lev->bitmap, fmt, lev->min, lev->unit)); 00220 00221 const coord_t barlen = lev->bitmap->width - 6 - textw; 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 /* CONFIG_MENU_MENUBAR */ 00233 00234 /* Input loop for single level setting */ 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 /* Accept input implicitly */ 00259 keys = K_CANCEL; 00260 break; 00261 } 00262 #endif 00263 00264 } 00265 while (!(keys = kbd_peek())); 00266 00267 if (keys & K_CANCEL) 00268 break; 00269 00270 /* Increment step to achieve greater accelerations on larger values */ 00271 if (keys & K_REPEAT) 00272 step = MIN(rep_step, step + 1); 00273 else 00274 step = lev->step; 00275 00276 if (keys & K_UP) 00277 { 00278 *lev->ch1_val += step; 00279 if (*lev->ch1_val > lev->max) 00280 *lev->ch1_val = lev->max; 00281 } 00282 00283 if (keys & K_DOWN) 00284 { 00285 *lev->ch1_val -= step; 00286 if (*lev->ch1_val < lev->min) 00287 *lev->ch1_val = lev->min; 00288 } 00289 00290 if (lev->set_hook) 00291 lev->set_hook(); 00292 } 00293 } 00294 00295 kbd_setRepeatMask(old_rpt_mask); 00296 } 00297 00302 void level_init(struct LevelEdit *lev, 00303 int type, 00304 struct Bitmap *bmp, const char *title, const char *unit, 00305 int min, int max, int step, 00306 int *ch1_val, int *ch2_val, 00307 level_set_callback *set_hook, display_callback *display_hook) 00308 { 00309 lev->type = type; 00310 lev->bitmap = bmp; 00311 lev->title = title; 00312 lev->unit = unit; 00313 lev->min = min; 00314 lev->max = max; 00315 lev->step = step; 00316 00317 lev->ch1_val = ch1_val; 00318 lev->ch2_val = ch2_val; 00319 lev->set_hook = set_hook; 00320 lev->display_hook = display_hook; 00321 }