diff options
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/pitchscreen.c | 184 |
1 files changed, 164 insertions, 20 deletions
diff --git a/apps/gui/pitchscreen.c b/apps/gui/pitchscreen.c index a0058724ec..5f987cb5d4 100644 --- a/apps/gui/pitchscreen.c +++ b/apps/gui/pitchscreen.c | |||
@@ -144,6 +144,33 @@ static const unsigned short cent_interp[] = | |||
144 | /* or that of the timestretching algorithm */ | 144 | /* or that of the timestretching algorithm */ |
145 | static bool at_limit = false; | 145 | static bool at_limit = false; |
146 | 146 | ||
147 | /* | ||
148 | * | ||
149 | * The pitchscreen is divided into 3 viewports (each row is a viewport) | ||
150 | * Then each viewport is again divided into 3 colums, each showsing some infos | ||
151 | * Additionally, on touchscreen, each cell represents a button | ||
152 | * | ||
153 | * Below a sketch describing what each cell will show (what's drawn on it) | ||
154 | * -------------------------- | ||
155 | * | | | | <-- pitch up in the middle (text and button) | ||
156 | * | | | | <-- arrows for mode toggling on the sides for touchscreen | ||
157 | * |------------------------| | ||
158 | * | | | | <-- semitone/speed up/down on the sides | ||
159 | * | | | | <-- reset pitch&speed in the middle | ||
160 | * |------------------------| | ||
161 | * | | | | <-- pitch down in the middle | ||
162 | * | | | | <-- Two "OK" for exit on the sides for touchscreen | ||
163 | * |------------------------| | ||
164 | * | ||
165 | * | ||
166 | */ | ||
167 | |||
168 | /* | ||
169 | * Fixes the viewports so they represent the 3 rows, and adds a little margin | ||
170 | * on all sides for the icons (which are drawn outside of the grid | ||
171 | * | ||
172 | * The modified viewports need to be passed to the touchscreen handling function | ||
173 | **/ | ||
147 | static void pitchscreen_fix_viewports(struct viewport *parent, | 174 | static void pitchscreen_fix_viewports(struct viewport *parent, |
148 | struct viewport pitch_viewports[PITCH_ITEM_COUNT]) | 175 | struct viewport pitch_viewports[PITCH_ITEM_COUNT]) |
149 | { | 176 | { |
@@ -152,24 +179,23 @@ static void pitchscreen_fix_viewports(struct viewport *parent, | |||
152 | for (i = 0; i < PITCH_ITEM_COUNT; i++) | 179 | for (i = 0; i < PITCH_ITEM_COUNT; i++) |
153 | { | 180 | { |
154 | pitch_viewports[i] = *parent; | 181 | pitch_viewports[i] = *parent; |
155 | pitch_viewports[i].height = font_height; | 182 | pitch_viewports[i].height = parent->height / PITCH_ITEM_COUNT; |
156 | 183 | pitch_viewports[i].x += ICON_BORDER; | |
157 | if (i == PITCH_TOP || i == PITCH_BOTTOM) | 184 | pitch_viewports[i].width -= 2*ICON_BORDER; |
158 | pitch_viewports[i].flags |= VP_FLAG_ALIGN_CENTER; | ||
159 | } | 185 | } |
160 | pitch_viewports[PITCH_TOP].y += ICON_BORDER; | 186 | pitch_viewports[PITCH_TOP].y += ICON_BORDER; |
187 | pitch_viewports[PITCH_TOP].height -= ICON_BORDER; | ||
161 | 188 | ||
162 | pitch_viewports[PITCH_MID].x += ICON_BORDER; | ||
163 | pitch_viewports[PITCH_MID].width = parent->width - ICON_BORDER*2; | ||
164 | pitch_viewports[PITCH_MID].height = parent->height - ICON_BORDER*2 | ||
165 | - font_height * 2; | ||
166 | if(pitch_viewports[PITCH_MID].height < font_height * 2) | 189 | if(pitch_viewports[PITCH_MID].height < font_height * 2) |
167 | pitch_viewports[PITCH_MID].height = font_height * 2; | 190 | pitch_viewports[PITCH_MID].height = font_height * 2; |
168 | pitch_viewports[PITCH_MID].y += parent->height / 2 - | ||
169 | pitch_viewports[PITCH_MID].height / 2; | ||
170 | 191 | ||
171 | pitch_viewports[PITCH_BOTTOM].y += parent->height - font_height | 192 | pitch_viewports[PITCH_MID].y = pitch_viewports[PITCH_TOP].y |
172 | - ICON_BORDER; | 193 | + pitch_viewports[PITCH_TOP].height; |
194 | |||
195 | pitch_viewports[PITCH_BOTTOM].y = pitch_viewports[PITCH_MID].y | ||
196 | + pitch_viewports[PITCH_MID].height; | ||
197 | |||
198 | pitch_viewports[PITCH_BOTTOM].height -= ICON_BORDER; | ||
173 | } | 199 | } |
174 | 200 | ||
175 | /* must be called before pitchscreen_draw, or within | 201 | /* must be called before pitchscreen_draw, or within |
@@ -207,29 +233,54 @@ static void pitchscreen_draw(struct screen *display, int max_lines, | |||
207 | bool show_lang_pitch; | 233 | bool show_lang_pitch; |
208 | 234 | ||
209 | /* "Pitch up/Pitch down" - hide for a small screen, | 235 | /* "Pitch up/Pitch down" - hide for a small screen, |
210 | * the text is drawn centered automatically */ | 236 | * the text is drawn centered automatically |
237 | * | ||
238 | * note: this assumes 5 lines always fit on a touchscreen (should be | ||
239 | * reasonable) */ | ||
211 | if (max_lines >= 5) | 240 | if (max_lines >= 5) |
212 | { | 241 | { |
242 | int w, h; | ||
243 | struct viewport *vp = &pitch_viewports[PITCH_TOP]; | ||
244 | display->set_viewport(vp); | ||
245 | display->clear_viewport(); | ||
246 | #ifdef HAVE_TOUCHSCREEN | ||
247 | /* two arrows in the top row, left and right column */ | ||
248 | char *arrows[] = { "<", ">"}; | ||
249 | display->getstringsize(arrows[0], &w, &h); | ||
250 | display->putsxy(0, vp->height/2 - h/2, arrows[0]); | ||
251 | display->putsxy(vp->width - w, vp->height/2 - h/2, arrows[1]); | ||
252 | #endif | ||
213 | /* UP: Pitch Up */ | 253 | /* UP: Pitch Up */ |
214 | display->set_viewport(&pitch_viewports[PITCH_TOP]); | ||
215 | if (global_settings.pitch_mode_semitone) | 254 | if (global_settings.pitch_mode_semitone) |
216 | ptr = str(LANG_PITCH_UP_SEMITONE); | 255 | ptr = str(LANG_PITCH_UP_SEMITONE); |
217 | else | 256 | else |
218 | ptr = str(LANG_PITCH_UP); | 257 | ptr = str(LANG_PITCH_UP); |
219 | display->clear_viewport(); | 258 | |
259 | display->getstringsize(ptr, &w, NULL); | ||
220 | /* draw text */ | 260 | /* draw text */ |
221 | display->putsxy(0, 0, ptr); | 261 | display->putsxy(vp->width/2 - w/2, 0, ptr); |
222 | display->update_viewport(); | 262 | display->update_viewport(); |
223 | 263 | ||
224 | /* DOWN: Pitch Down */ | 264 | /* DOWN: Pitch Down */ |
225 | display->set_viewport(&pitch_viewports[PITCH_BOTTOM]); | 265 | vp = &pitch_viewports[PITCH_BOTTOM]; |
266 | display->set_viewport(vp); | ||
267 | display->clear_viewport(); | ||
268 | |||
269 | #ifdef HAVE_TOUCHSCREEN | ||
270 | ptr = str(LANG_KBD_OK); | ||
271 | display->getstringsize(ptr, &w, &h); | ||
272 | /* one OK in the middle first column of the vp (at half height) */ | ||
273 | display->putsxy(vp->width/6 - w/2, vp->height/2 - h/2, ptr); | ||
274 | /* one OK in the middle of the last column of the vp (at half height) */ | ||
275 | display->putsxy(5*vp->width/6 - w/2, vp->height/2 - h/2, ptr); | ||
276 | #endif | ||
226 | if (global_settings.pitch_mode_semitone) | 277 | if (global_settings.pitch_mode_semitone) |
227 | ptr = str(LANG_PITCH_DOWN_SEMITONE); | 278 | ptr = str(LANG_PITCH_DOWN_SEMITONE); |
228 | else | 279 | else |
229 | ptr = str(LANG_PITCH_DOWN); | 280 | ptr = str(LANG_PITCH_DOWN); |
230 | display->clear_viewport(); | 281 | display->getstringsize(ptr, &w, &h); |
231 | /* draw text */ | 282 | /* draw text */ |
232 | display->putsxy(0, 0, ptr); | 283 | display->putsxy(vp->width/2 - w/2, vp->height - h, ptr); |
233 | display->update_viewport(); | 284 | display->update_viewport(); |
234 | } | 285 | } |
235 | 286 | ||
@@ -573,6 +624,91 @@ static int32_t pitch_increase_semitone(int32_t pitch, | |||
573 | return new_semitone; | 624 | return new_semitone; |
574 | } | 625 | } |
575 | 626 | ||
627 | #ifdef HAVE_TOUCHSCREEN | ||
628 | /* | ||
629 | * Check for touchscreen presses as per sketch above in this file | ||
630 | * | ||
631 | * goes through each row of the, checks whether the touchscreen | ||
632 | * was pressed in it. Then it looks the columns of each row for specific actions | ||
633 | */ | ||
634 | static int pitchscreen_do_touchscreen(struct viewport vps[]) | ||
635 | { | ||
636 | short x, y; | ||
637 | struct viewport *this_vp = &vps[PITCH_TOP]; | ||
638 | int ret; | ||
639 | ret = action_get_touchscreen_press_in_vp(&x, &y, this_vp); | ||
640 | |||
641 | /* top row */ | ||
642 | if (ret > ACTION_UNKNOWN) | ||
643 | { /* press on top row, left or right column | ||
644 | * only toggle mode if released */ | ||
645 | int column = this_vp->width / 3; | ||
646 | if ((x < column || x > (2*column)) && (ret == BUTTON_REL)) | ||
647 | return ACTION_PS_TOGGLE_MODE; | ||
648 | |||
649 | |||
650 | else if (x >= column && x <= (2*column)) | ||
651 | { /* center column pressed */ | ||
652 | if (ret == BUTTON_REPEAT) | ||
653 | return ACTION_PS_INC_BIG; | ||
654 | else if (ret == BUTTON_TOUCHSCREEN) | ||
655 | return ACTION_PS_INC_SMALL; | ||
656 | } | ||
657 | return ACTION_NONE; | ||
658 | } | ||
659 | |||
660 | /* now the center row */ | ||
661 | this_vp = &vps[PITCH_MID]; | ||
662 | ret = action_get_touchscreen_press_in_vp(&x, &y, this_vp); | ||
663 | |||
664 | if (ret > ACTION_UNKNOWN) | ||
665 | { | ||
666 | int column = this_vp->width / 3; | ||
667 | |||
668 | if (x < column) | ||
669 | { /* left column */ | ||
670 | if (ret & BUTTON_REL) | ||
671 | return ACTION_PS_NUDGE_LEFTOFF; | ||
672 | else if (ret & BUTTON_REPEAT) | ||
673 | return ACTION_PS_SLOWER; | ||
674 | return ACTION_PS_NUDGE_LEFT; | ||
675 | } | ||
676 | else if (x > (2*column)) | ||
677 | { /* right column */ | ||
678 | if (ret & BUTTON_REL) | ||
679 | return ACTION_PS_NUDGE_LEFTOFF; | ||
680 | else if (ret & BUTTON_REPEAT) | ||
681 | return ACTION_PS_FASTER; | ||
682 | return ACTION_PS_NUDGE_LEFT; | ||
683 | } | ||
684 | /* center column was pressed */ | ||
685 | return ACTION_PS_RESET; | ||
686 | } | ||
687 | |||
688 | /* now the bottom row */ | ||
689 | this_vp = &vps[PITCH_BOTTOM]; | ||
690 | ret = action_get_touchscreen_press_in_vp(&x, &y, this_vp); | ||
691 | |||
692 | if (ret > ACTION_UNKNOWN) | ||
693 | { | ||
694 | int column = this_vp->width / 3; | ||
695 | |||
696 | /* left or right column is exit */ | ||
697 | if ((x < column || x > (2*column)) && (ret == BUTTON_REL)) | ||
698 | return ACTION_PS_EXIT; | ||
699 | else if (x >= column && x <= (2*column)) | ||
700 | { /* center column was pressed */ | ||
701 | if (ret == BUTTON_REPEAT) | ||
702 | return ACTION_PS_DEC_BIG; | ||
703 | else if (ret == BUTTON_TOUCHSCREEN) | ||
704 | return ACTION_PS_DEC_SMALL; | ||
705 | } | ||
706 | return ACTION_NONE; | ||
707 | } | ||
708 | return ACTION_NONE; | ||
709 | } | ||
710 | |||
711 | #endif | ||
576 | /* | 712 | /* |
577 | returns: | 713 | returns: |
578 | 0 on exit | 714 | 0 on exit |
@@ -649,6 +785,14 @@ int gui_syncpitchscreen_run(void) | |||
649 | new_speed = 0; | 785 | new_speed = 0; |
650 | #endif | 786 | #endif |
651 | button = get_action(CONTEXT_PITCHSCREEN, HZ); | 787 | button = get_action(CONTEXT_PITCHSCREEN, HZ); |
788 | |||
789 | #ifdef HAVE_TOUCHSCREEN | ||
790 | if (button == ACTION_TOUCHSCREEN) | ||
791 | { | ||
792 | FOR_NB_SCREENS(i) | ||
793 | button = pitchscreen_do_touchscreen(pitch_viewports[i]); | ||
794 | } | ||
795 | #endif | ||
652 | switch (button) | 796 | switch (button) |
653 | { | 797 | { |
654 | case ACTION_PS_INC_SMALL: | 798 | case ACTION_PS_INC_SMALL: |