diff options
author | Tectu <joel@unormal.org> | 2013-04-05 04:57:11 -0700 |
---|---|---|
committer | Tectu <joel@unormal.org> | 2013-04-05 04:57:11 -0700 |
commit | 4719e96bebb3c98ad746cecc370da35a44d11cbf (patch) | |
tree | 1c2628cac2869e94ed6fe9246a0701a0784ca702 | |
parent | 55d41fe007e34d67737ca9abd11fb7ce2cc46bbc (diff) | |
parent | ee19104dbb51b98a8753414854cc6c5cdee42a55 (diff) | |
download | uGFX-4719e96bebb3c98ad746cecc370da35a44d11cbf.tar.gz uGFX-4719e96bebb3c98ad746cecc370da35a44d11cbf.tar.bz2 uGFX-4719e96bebb3c98ad746cecc370da35a44d11cbf.zip |
Merge pull request #58 from inmarket/master
GWIN Slider plus other cleanups
-rw-r--r-- | demos/modules/ginput/touch_driver_test/gfxconf.h (renamed from demos/modules/ginput_touch_driver_test/gfxconf.h) | 94 | ||||
-rw-r--r-- | demos/modules/ginput/touch_driver_test/main.c (renamed from demos/modules/ginput_touch_driver_test/main.c) | 698 | ||||
-rw-r--r-- | demos/modules/gwin/basic/gfxconf.h (renamed from demos/modules/window/gfxconf.h) | 66 | ||||
-rw-r--r-- | demos/modules/gwin/basic/main.c (renamed from demos/modules/window/main.c) | 134 | ||||
-rw-r--r-- | demos/modules/gwin/console/gfxconf.h (renamed from demos/modules/console/gfxconf.h) | 86 | ||||
-rw-r--r-- | demos/modules/gwin/console/main.c (renamed from demos/modules/console/main.c) | 174 | ||||
-rw-r--r-- | demos/modules/gwin/slider/gfxconf.h | 57 | ||||
-rw-r--r-- | demos/modules/gwin/slider/main.c | 89 | ||||
-rw-r--r-- | demos/modules/gwin/slider/result_647x490.png | bin | 0 -> 24141 bytes | |||
-rw-r--r-- | gfxconf.example.h | 1 | ||||
-rw-r--r-- | include/gwin/gwin.h | 24 | ||||
-rw-r--r-- | include/gwin/options.h | 7 | ||||
-rw-r--r-- | include/gwin/slider.h | 233 | ||||
-rw-r--r-- | src/gwin/gwin.c | 15 | ||||
-rw-r--r-- | src/gwin/gwin.mk | 1 | ||||
-rw-r--r-- | src/gwin/slider.c | 281 |
16 files changed, 1334 insertions, 626 deletions
diff --git a/demos/modules/ginput_touch_driver_test/gfxconf.h b/demos/modules/ginput/touch_driver_test/gfxconf.h index 05f685dd..e00aaedb 100644 --- a/demos/modules/ginput_touch_driver_test/gfxconf.h +++ b/demos/modules/ginput/touch_driver_test/gfxconf.h @@ -1,47 +1,47 @@ -/**
- * This file has a different license to the rest of the GFX system.
- * You can copy, modify and distribute this file as you see fit.
- * You do not need to publish your source modifications to this file.
- * The only thing you are not permitted to do is to relicense it
- * under a different license.
- */
-
-#ifndef _GFXCONF_H
-#define _GFXCONF_H
-
-/* GFX sub-systems to turn on */
-#define GFX_USE_GDISP TRUE
-#define GFX_USE_GWIN TRUE
-#define GFX_USE_GEVENT TRUE
-#define GFX_USE_GTIMER TRUE
-#define GFX_USE_GINPUT TRUE
-
-/* Features for the GDISP sub-system. */
-#define GDISP_NEED_VALIDATION TRUE
-#define GDISP_NEED_CLIP TRUE
-#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
-#define GDISP_NEED_MULTITHREAD TRUE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
-
-/* Builtin Fonts */
-#define GDISP_INCLUDE_FONT_SMALL FALSE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
-#define GDISP_INCLUDE_FONT_UI2 TRUE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
-
-/* Features for the GWIN sub-system. */
-#define GWIN_NEED_BUTTON TRUE
-#define GWIN_NEED_CONSOLE TRUE
-
-/* Features for the GINPUT sub-system. */
-#define GINPUT_NEED_MOUSE TRUE
-
-#endif /* _GFXCONF_H */
+/** + * This file has a different license to the rest of the GFX system. + * You can copy, modify and distribute this file as you see fit. + * You do not need to publish your source modifications to this file. + * The only thing you are not permitted to do is to relicense it + * under a different license. + */ + +#ifndef _GFXCONF_H +#define _GFXCONF_H + +/* GFX sub-systems to turn on */ +#define GFX_USE_GDISP TRUE +#define GFX_USE_GWIN TRUE +#define GFX_USE_GEVENT TRUE +#define GFX_USE_GTIMER TRUE +#define GFX_USE_GINPUT TRUE + +/* Features for the GDISP sub-system. */ +#define GDISP_NEED_VALIDATION TRUE +#define GDISP_NEED_CLIP TRUE +#define GDISP_NEED_TEXT TRUE +#define GDISP_NEED_CIRCLE FALSE +#define GDISP_NEED_ELLIPSE FALSE +#define GDISP_NEED_ARC FALSE +#define GDISP_NEED_SCROLL FALSE +#define GDISP_NEED_PIXELREAD FALSE +#define GDISP_NEED_CONTROL FALSE +#define GDISP_NEED_MULTITHREAD TRUE +#define GDISP_NEED_ASYNC FALSE +#define GDISP_NEED_MSGAPI FALSE + +/* Builtin Fonts */ +#define GDISP_INCLUDE_FONT_SMALL FALSE +#define GDISP_INCLUDE_FONT_LARGER FALSE +#define GDISP_INCLUDE_FONT_UI1 FALSE +#define GDISP_INCLUDE_FONT_UI2 TRUE +#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE + +/* Features for the GWIN sub-system. */ +#define GWIN_NEED_BUTTON TRUE +#define GWIN_NEED_CONSOLE TRUE + +/* Features for the GINPUT sub-system. */ +#define GINPUT_NEED_MOUSE TRUE + +#endif /* _GFXCONF_H */ diff --git a/demos/modules/ginput_touch_driver_test/main.c b/demos/modules/ginput/touch_driver_test/main.c index 306ab631..95d29d28 100644 --- a/demos/modules/ginput_touch_driver_test/main.c +++ b/demos/modules/ginput/touch_driver_test/main.c @@ -1,349 +1,349 @@ -/*
- ChibiOS/GFX - Copyright (C) 2012, 2013
- Joel Bodenmann aka Tectu <joel@unormal.org>
-
- This file is part of ChibiOS/GFX.
-
- ChibiOS/GFX is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/GFX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ch.h"
-#include "hal.h"
-#include "chprintf.h"
-#include "gfx.h"
-
-static GConsoleObject gc;
-static GButtonObject gNext;
-static GButtonObject gPrev;
-static GListener gl;
-
-/*------------------------------------------------------------------------*
- * GINPUT Touch Driver Calibrator. *
- *------------------------------------------------------------------------*/
-int main(void) {
- GSourceHandle gs, gsNext, gsPrev;
- GEvent *pe;
- GEventMouse *pem;
- GEventGWinButton *peb;
- coord_t swidth, sheight;
- GHandle ghc, ghNext, ghPrev;
- BaseSequentialStream *gp;
- GEventType deviceType;
- font_t font;
-
- halInit(); // Initialise the Hardware
- chSysInit(); // Initialize the OS
- gdispInit(); // Initialize the display
-
- // Get the display dimensions
- swidth = gdispGetWidth();
- sheight = gdispGetHeight();
- ghNext = ghPrev = 0;
-
- // Create our title
- font = gdispOpenFont("UI2");
- gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Red, White, justifyLeft);
-
- // Create our main display window
- ghc = gwinCreateConsole(&gc, 0, 20, swidth, sheight-20, font);
- gwinClear(ghc);
- gp = gwinGetConsoleStream(ghc);
-
- // Initialize the mouse in our special no calibration mode.
- geventListenerInit(&gl);
- gs = ginputGetMouse(9999);
- geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
-
- /*
- * Test: Device Type
- */
-
-StepDeviceType:
- gwinClear(ghc);
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "\n1. DEVICE TYPE\n\n");
-
- pem = (GEventMouse *)&gl.event;
- ginputGetMouseStatus(0, pem);
- deviceType = pem->type;
-
- gwinSetColor(ghc, White);
- chprintf(gp, "This is detected as a %s device\n\n",
- deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN"));
-
- if (ghNext)
- chprintf(gp, "Press Next or Back to continue.\n");
- else if (deviceType == GEVENT_MOUSE)
- chprintf(gp, "Click the mouse button to move on to the next test.\n");
- else
- chprintf(gp, "Press and release your finger to move on to the next test.\n");
-
- while(1) {
- pe = geventEventWait(&gl, TIME_INFINITE);
- if (pe->type == GEVENT_GWIN_BUTTON) {
- peb = (GEventGWinButton *)pe;
- if (peb->button == ghPrev)
- goto StepClickJitter;
- if (peb->button == ghNext)
- break;
- }
- if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
- pem = (GEventMouse *)pe;
- if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
- break;
- }
- }
-
- /*
- * Test: Mouse raw reading jitter
- */
-
-StepRawJitter:
- gwinClear(ghc);
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n");
-
- gwinSetColor(ghc, White);
- if (deviceType == GEVENT_MOUSE)
- chprintf(gp, "Press and hold the mouse button.\n\n");
- else
- chprintf(gp, "Press and hold on the surface.\n\n");
- chprintf(gp, "Numbers will display in this window.\n"
- "Ensure that values don't jump around very much when your finger is stationary.\n\n"
- "Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n");
-
- if (ghNext)
- chprintf(gp, "Press Next or Back to continue.\n");
- else if (deviceType == GEVENT_MOUSE)
- chprintf(gp, "Release the mouse button to move on to the next test.\n");
- else
- chprintf(gp, "Release your finger to move on to the next test.\n");
-
- // For this test turn on ALL mouse movement events
- geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER);
-
- while(1) {
- pe = geventEventWait(&gl, TIME_INFINITE);
- if (pe->type == GEVENT_GWIN_BUTTON) {
- peb = (GEventGWinButton *)pe;
- if (peb->button == ghPrev)
- goto StepDeviceType;
- if (peb->button == ghNext)
- break;
- }
- if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
- pem = (GEventMouse *)pe;
- if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
- chprintf(gp, "%u:%u\n", pem->x, pem->y);
- if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
- break;
- }
- }
-
- // Reset to just changed movements.
- geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
-
- /*
- * Test: Calibration
- */
-
-StepCalibrate:
- gwinClear(ghc);
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n");
- gwinSetColor(ghc, Gray);
- chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n");
- gwinSetColor(ghc, White);
- chprintf(gp, "You will be presented with a number of points to touch.\nPress them in turn.\n\n"
- "If the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n");
-
- if (ghNext)
- chprintf(gp, "Press Next to start the calibration.\n");
- else if (deviceType == GEVENT_MOUSE)
- chprintf(gp, "Click the mouse button to start the calibration.\n");
- else
- chprintf(gp, "Press and release your finger to start the calibration.\n");
-
- while(1) {
- pe = geventEventWait(&gl, TIME_INFINITE);
- if (pe->type == GEVENT_GWIN_BUTTON) {
- peb = (GEventGWinButton *)pe;
- if (peb->button == ghPrev)
- goto StepRawJitter;
- if (peb->button == ghNext)
- break;
- }
- if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
- pem = (GEventMouse *)pe;
- if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
- break;
- }
- }
-
- // Calibrate
- ginputCalibrateMouse(0);
-
- /* From now on we can use Next and Previous Buttons */
- if (!ghNext) {
-
- ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, font, GBTN_NORMAL);
- gwinSetButtonText(ghNext, "Next", FALSE);
- gsNext = gwinGetButtonSource(ghNext);
- geventAttachSource(&gl, gsNext, 0);
- gwinAttachButtonMouseSource(ghNext, gs);
-
- ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL);
- gwinSetButtonText(ghPrev, "Back", FALSE);
- gsPrev = gwinGetButtonSource(ghPrev);
- geventAttachSource(&gl, gsPrev, 0);
- gwinAttachButtonMouseSource(ghPrev, gs);
-
-#if 0
- {
- GSourceHandle gsButton1, gsButton2;
-
- // Attach a couple of hardware toggle buttons to our Next and Back buttons as well.
- // We can always use the mouse to trigger the buttons if you don't want to use hardware toggles.
- // This code depends on your hardware. Turn it on only if you have
- // defined a board definition for your toggle driver. Then change
- // the next two lines to be correct for your hardware. The values
- // below are correct for the Win32 toggle driver.
- gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1);
- gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2);
- gwinAttachButtonToggleSource(ghNext, gsButton2);
- gwinAttachButtonToggleSource(ghPrev, gsButton1);
- }
-#endif
- }
-
- // Calibration used the whole screen - re-establish our title
- gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Green, White, justifyLeft);
- gwinButtonDraw(ghNext);
- gwinButtonDraw(ghPrev);
-
- /*
- * Test: Mouse movement jitter
- */
-
-StepJitter:
- gwinClear(ghc);
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n");
-
- gwinSetColor(ghc, White);
- if (deviceType == GEVENT_MOUSE)
- chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n");
- else
- chprintf(gp, "Press firmly on the surface and move around as if to draw.\n\n");
-
- chprintf(gp, "Dots will display in this window. Ensure that when you stop moving your finger that "
- "new dots stop displaying.\nNew dots should only display when your finger is moving.\n\n"
- "Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n");
- chprintf(gp, "Press Next or Back to continue.\n\n");
-
- while(1) {
- pe = geventEventWait(&gl, TIME_INFINITE);
- if (pe->type == GEVENT_GWIN_BUTTON) {
- peb = (GEventGWinButton *)pe;
- if (peb->button == ghPrev)
- goto StepCalibrate;
- if (peb->button == ghNext)
- break;
- }
- if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
- pem = (GEventMouse *)pe;
- if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
- chprintf(gp, ".");
- }
- }
-
- /*
- * Test: Polling frequency
- */
-
-StepPolling:
- gwinClear(ghc);
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n");
-
- gwinSetColor(ghc, White);
- chprintf(gp, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n");
- chprintf(gp, "A green line will follow your finger.\n"
- "Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without "
- "gaps that are too big.\nDecreasing the value increases CPU usage.\n"
- "About 25 (millisecs) normally produces good results."
- "This test can be ignored for interrupt driven drivers.\n\n");
- chprintf(gp, "Press Next or Back to continue.\n\n");
-
- while(1) {
- pe = geventEventWait(&gl, TIME_INFINITE);
- if (pe->type == GEVENT_GWIN_BUTTON) {
- peb = (GEventGWinButton *)pe;
- if (peb->button == ghPrev)
- goto StepJitter;
- if (peb->button == ghNext)
- break;
- }
- if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
- pem = (GEventMouse *)pe;
- if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
- gdispDrawPixel(pem->x, pem->y, Green);
- }
- }
-
- /*
- * Test: Click Jitter
- */
-
-StepClickJitter:
- gwinClear(ghc);
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n");
-
- gwinSetColor(ghc, White);
- chprintf(gp, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n");
- chprintf(gp, "For a mouse click with the left and right buttons.\n\n");
- chprintf(gp, "Dots will display in this window. A yellow dash is a left (or short) click. "
- "A red x is a right (or long) click.\n\n"
- "Adjust GINPUT_MOUSE_CLICK_JITTER to the smallest value that this reliably works for.\n"
- "Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\n"
- "TIME_INFINITE means there are no long presses (although a right mouse button will still work).\n\n"
- "Note: moving your finger (mouse) during a click cancels it.\n\n");
- chprintf(gp, "This is the last test but you can press Next or Back to continue.\n\n");
-
- while(1) {
- pe = geventEventWait(&gl, TIME_INFINITE);
- if (pe->type == GEVENT_GWIN_BUTTON) {
- peb = (GEventGWinButton *)pe;
- if (peb->button == ghPrev)
- goto StepPolling;
- if (peb->button == ghNext)
- break;
- }
- if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
- pem = (GEventMouse *)pe;
- if ((pem->meta & GMETA_MOUSE_CLICK)) {
- gwinSetColor(ghc, Yellow);
- chprintf(gp, "-");
- }
- if ((pem->meta & GMETA_MOUSE_CXTCLICK)) {
- gwinSetColor(ghc, Red);
- chprintf(gp, "x");
- }
- }
- }
-
- // Can't let this really exit
- goto StepDeviceType;
-}
+/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu <joel@unormal.org> + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "ch.h" +#include "hal.h" +#include "chprintf.h" +#include "gfx.h" + +static GConsoleObject gc; +static GButtonObject gNext; +static GButtonObject gPrev; +static GListener gl; + +/*------------------------------------------------------------------------* + * GINPUT Touch Driver Calibrator. * + *------------------------------------------------------------------------*/ +int main(void) { + GSourceHandle gs, gsNext, gsPrev; + GEvent *pe; + GEventMouse *pem; + GEventGWinButton *peb; + coord_t swidth, sheight; + GHandle ghc, ghNext, ghPrev; + BaseSequentialStream *gp; + GEventType deviceType; + font_t font; + + halInit(); // Initialise the Hardware + chSysInit(); // Initialize the OS + gdispInit(); // Initialize the display + + // Get the display dimensions + swidth = gdispGetWidth(); + sheight = gdispGetHeight(); + ghNext = ghPrev = 0; + + // Create our title + font = gdispOpenFont("UI2"); + gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Red, White, justifyLeft); + + // Create our main display window + ghc = gwinCreateConsole(&gc, 0, 20, swidth, sheight-20, font); + gwinClear(ghc); + gp = gwinGetConsoleStream(ghc); + + // Initialize the mouse in our special no calibration mode. + geventListenerInit(&gl); + gs = ginputGetMouse(9999); + geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); + + /* + * Test: Device Type + */ + +StepDeviceType: + gwinClear(ghc); + gwinSetColor(ghc, Yellow); + chprintf(gp, "\n1. DEVICE TYPE\n\n"); + + pem = (GEventMouse *)&gl.event; + ginputGetMouseStatus(0, pem); + deviceType = pem->type; + + gwinSetColor(ghc, White); + chprintf(gp, "This is detected as a %s device\n\n", + deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN")); + + if (ghNext) + chprintf(gp, "Press Next or Back to continue.\n"); + else if (deviceType == GEVENT_MOUSE) + chprintf(gp, "Click the mouse button to move on to the next test.\n"); + else + chprintf(gp, "Press and release your finger to move on to the next test.\n"); + + while(1) { + pe = geventEventWait(&gl, TIME_INFINITE); + if (pe->type == GEVENT_GWIN_BUTTON) { + peb = (GEventGWinButton *)pe; + if (peb->button == ghPrev) + goto StepClickJitter; + if (peb->button == ghNext) + break; + } + if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { + pem = (GEventMouse *)pe; + if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) + break; + } + } + + /* + * Test: Mouse raw reading jitter + */ + +StepRawJitter: + gwinClear(ghc); + gwinSetColor(ghc, Yellow); + chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n"); + + gwinSetColor(ghc, White); + if (deviceType == GEVENT_MOUSE) + chprintf(gp, "Press and hold the mouse button.\n\n"); + else + chprintf(gp, "Press and hold on the surface.\n\n"); + chprintf(gp, "Numbers will display in this window.\n" + "Ensure that values don't jump around very much when your finger is stationary.\n\n" + "Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n"); + + if (ghNext) + chprintf(gp, "Press Next or Back to continue.\n"); + else if (deviceType == GEVENT_MOUSE) + chprintf(gp, "Release the mouse button to move on to the next test.\n"); + else + chprintf(gp, "Release your finger to move on to the next test.\n"); + + // For this test turn on ALL mouse movement events + geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER); + + while(1) { + pe = geventEventWait(&gl, TIME_INFINITE); + if (pe->type == GEVENT_GWIN_BUTTON) { + peb = (GEventGWinButton *)pe; + if (peb->button == ghPrev) + goto StepDeviceType; + if (peb->button == ghNext) + break; + } + if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { + pem = (GEventMouse *)pe; + if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) + chprintf(gp, "%u:%u\n", pem->x, pem->y); + if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) + break; + } + } + + // Reset to just changed movements. + geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); + + /* + * Test: Calibration + */ + +StepCalibrate: + gwinClear(ghc); + gwinSetColor(ghc, Yellow); + chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n"); + gwinSetColor(ghc, Gray); + chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n"); + gwinSetColor(ghc, White); + chprintf(gp, "You will be presented with a number of points to touch.\nPress them in turn.\n\n" + "If the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n"); + + if (ghNext) + chprintf(gp, "Press Next to start the calibration.\n"); + else if (deviceType == GEVENT_MOUSE) + chprintf(gp, "Click the mouse button to start the calibration.\n"); + else + chprintf(gp, "Press and release your finger to start the calibration.\n"); + + while(1) { + pe = geventEventWait(&gl, TIME_INFINITE); + if (pe->type == GEVENT_GWIN_BUTTON) { + peb = (GEventGWinButton *)pe; + if (peb->button == ghPrev) + goto StepRawJitter; + if (peb->button == ghNext) + break; + } + if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { + pem = (GEventMouse *)pe; + if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) + break; + } + } + + // Calibrate + ginputCalibrateMouse(0); + + /* From now on we can use Next and Previous Buttons */ + if (!ghNext) { + + ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, font, GBTN_NORMAL); + gwinSetButtonText(ghNext, "Next", FALSE); + gsNext = gwinGetButtonSource(ghNext); + geventAttachSource(&gl, gsNext, 0); + gwinAttachButtonMouseSource(ghNext, gs); + + ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL); + gwinSetButtonText(ghPrev, "Back", FALSE); + gsPrev = gwinGetButtonSource(ghPrev); + geventAttachSource(&gl, gsPrev, 0); + gwinAttachButtonMouseSource(ghPrev, gs); + +#if 0 + { + GSourceHandle gsButton1, gsButton2; + + // Attach a couple of hardware toggle buttons to our Next and Back buttons as well. + // We can always use the mouse to trigger the buttons if you don't want to use hardware toggles. + // This code depends on your hardware. Turn it on only if you have + // defined a board definition for your toggle driver. Then change + // the next two lines to be correct for your hardware. The values + // below are correct for the Win32 toggle driver. + gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1); + gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2); + gwinAttachButtonToggleSource(ghNext, gsButton2); + gwinAttachButtonToggleSource(ghPrev, gsButton1); + } +#endif + } + + // Calibration used the whole screen - re-establish our title + gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Green, White, justifyLeft); + gwinButtonDraw(ghNext); + gwinButtonDraw(ghPrev); + + /* + * Test: Mouse movement jitter + */ + +StepJitter: + gwinClear(ghc); + gwinSetColor(ghc, Yellow); + chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n"); + + gwinSetColor(ghc, White); + if (deviceType == GEVENT_MOUSE) + chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n"); + else + chprintf(gp, "Press firmly on the surface and move around as if to draw.\n\n"); + + chprintf(gp, "Dots will display in this window. Ensure that when you stop moving your finger that " + "new dots stop displaying.\nNew dots should only display when your finger is moving.\n\n" + "Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n"); + chprintf(gp, "Press Next or Back to continue.\n\n"); + + while(1) { + pe = geventEventWait(&gl, TIME_INFINITE); + if (pe->type == GEVENT_GWIN_BUTTON) { + peb = (GEventGWinButton *)pe; + if (peb->button == ghPrev) + goto StepCalibrate; + if (peb->button == ghNext) + break; + } + if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { + pem = (GEventMouse *)pe; + if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) + chprintf(gp, "."); + } + } + + /* + * Test: Polling frequency + */ + +StepPolling: + gwinClear(ghc); + gwinSetColor(ghc, Yellow); + chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n"); + + gwinSetColor(ghc, White); + chprintf(gp, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n"); + chprintf(gp, "A green line will follow your finger.\n" + "Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without " + "gaps that are too big.\nDecreasing the value increases CPU usage.\n" + "About 25 (millisecs) normally produces good results." + "This test can be ignored for interrupt driven drivers.\n\n"); + chprintf(gp, "Press Next or Back to continue.\n\n"); + + while(1) { + pe = geventEventWait(&gl, TIME_INFINITE); + if (pe->type == GEVENT_GWIN_BUTTON) { + peb = (GEventGWinButton *)pe; + if (peb->button == ghPrev) + goto StepJitter; + if (peb->button == ghNext) + break; + } + if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { + pem = (GEventMouse *)pe; + if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) + gdispDrawPixel(pem->x, pem->y, Green); + } + } + + /* + * Test: Click Jitter + */ + +StepClickJitter: + gwinClear(ghc); + gwinSetColor(ghc, Yellow); + chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n"); + + gwinSetColor(ghc, White); + chprintf(gp, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n"); + chprintf(gp, "For a mouse click with the left and right buttons.\n\n"); + chprintf(gp, "Dots will display in this window. A yellow dash is a left (or short) click. " + "A red x is a right (or long) click.\n\n" + "Adjust GINPUT_MOUSE_CLICK_JITTER to the smallest value that this reliably works for.\n" + "Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\n" + "TIME_INFINITE means there are no long presses (although a right mouse button will still work).\n\n" + "Note: moving your finger (mouse) during a click cancels it.\n\n"); + chprintf(gp, "This is the last test but you can press Next or Back to continue.\n\n"); + + while(1) { + pe = geventEventWait(&gl, TIME_INFINITE); + if (pe->type == GEVENT_GWIN_BUTTON) { + peb = (GEventGWinButton *)pe; + if (peb->button == ghPrev) + goto StepPolling; + if (peb->button == ghNext) + break; + } + if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { + pem = (GEventMouse *)pe; + if ((pem->meta & GMETA_MOUSE_CLICK)) { + gwinSetColor(ghc, Yellow); + chprintf(gp, "-"); + } + if ((pem->meta & GMETA_MOUSE_CXTCLICK)) { + gwinSetColor(ghc, Red); + chprintf(gp, "x"); + } + } + } + + // Can't let this really exit + goto StepDeviceType; +} diff --git a/demos/modules/window/gfxconf.h b/demos/modules/gwin/basic/gfxconf.h index c8080075..e567e5a0 100644 --- a/demos/modules/window/gfxconf.h +++ b/demos/modules/gwin/basic/gfxconf.h @@ -1,33 +1,33 @@ -/**
- * This file has a different license to the rest of the GFX system.
- * You can copy, modify and distribute this file as you see fit.
- * You do not need to publish your source modifications to this file.
- * The only thing you are not permitted to do is to relicense it
- * under a different license.
- */
-
-#ifndef _GFXCONF_H
-#define _GFXCONF_H
-
-/* GFX sub-systems to turn on */
-#define GFX_USE_GDISP TRUE
-#define GFX_USE_GWIN TRUE
-#define GFX_USE_GEVENT FALSE
-#define GFX_USE_GTIMER FALSE
-#define GFX_USE_GINPUT FALSE
-
-/* Features for the GDISP sub-system. */
-#define GDISP_NEED_VALIDATION TRUE
-#define GDISP_NEED_CLIP TRUE
-#define GDISP_NEED_TEXT FALSE
-#define GDISP_NEED_CIRCLE TRUE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
-#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
-
-#endif /* _GFXCONF_H */
+/** + * This file has a different license to the rest of the GFX system. + * You can copy, modify and distribute this file as you see fit. + * You do not need to publish your source modifications to this file. + * The only thing you are not permitted to do is to relicense it + * under a different license. + */ + +#ifndef _GFXCONF_H +#define _GFXCONF_H + +/* GFX sub-systems to turn on */ +#define GFX_USE_GDISP TRUE +#define GFX_USE_GWIN TRUE +#define GFX_USE_GEVENT FALSE +#define GFX_USE_GTIMER FALSE +#define GFX_USE_GINPUT FALSE + +/* Features for the GDISP sub-system. */ +#define GDISP_NEED_VALIDATION TRUE +#define GDISP_NEED_CLIP TRUE +#define GDISP_NEED_TEXT FALSE +#define GDISP_NEED_CIRCLE TRUE +#define GDISP_NEED_ELLIPSE FALSE +#define GDISP_NEED_ARC FALSE +#define GDISP_NEED_SCROLL FALSE +#define GDISP_NEED_PIXELREAD FALSE +#define GDISP_NEED_CONTROL FALSE +#define GDISP_NEED_MULTITHREAD FALSE +#define GDISP_NEED_ASYNC FALSE +#define GDISP_NEED_MSGAPI FALSE + +#endif /* _GFXCONF_H */ diff --git a/demos/modules/window/main.c b/demos/modules/gwin/basic/main.c index 6571f109..a0326fac 100644 --- a/demos/modules/window/main.c +++ b/demos/modules/gwin/basic/main.c @@ -1,67 +1,67 @@ -/*
- ChibiOS/GFX - Copyright (C) 2012, 2013
- Joel Bodenmann aka Tectu <joel@unormal.org>
-
- This file is part of ChibiOS/GFX.
-
- ChibiOS/GFX is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/GFX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ch.h"
-#include "hal.h"
-#include "gfx.h"
-
-/* The handles for our two Windows */
-GHandle GW1, GW2;
-
-int main(void) {
- halInit();
- chSysInit();
- coord_t i, j;
-
- /* Initialize and clear the display */
- gdispInit();
- gdispClear(Lime);
-
- /* Create two windows */
- GW1 = gwinCreateWindow(NULL, 20, 10, 200, 150);
- GW2 = gwinCreateWindow(NULL, 50, 190, 150, 100);
-
- /* Set fore- and background colors for both windows */
- gwinSetColor(GW1, Black);
- gwinSetBgColor(GW1, White);
- gwinSetColor(GW2, White);
- gwinSetBgColor(GW2, Blue);
-
- /* Clear both windows - to set background color */
- gwinClear(GW1);
- gwinClear(GW2);
-
- gwinDrawLine (GW1, 5, 30, 150, 110);
- for(i=5, j=0; i < 200 && j < 150; i+=3, j+=i/20)
- gwinDrawPixel (GW1, i, j);
-
- /*
- * Draw two filled circles at the same coordinate
- * of each window to demonstrate the relative coordinates
- * of windows
- */
- gwinFillCircle(GW1, 20, 20, 15);
- gwinFillCircle(GW2, 20, 20, 15);
-
- while(TRUE) {
- chThdSleepMilliseconds(500);
- }
-}
-
+/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu <joel@unormal.org> + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "ch.h" +#include "hal.h" +#include "gfx.h" + +/* The handles for our two Windows */ +GHandle GW1, GW2; + +int main(void) { + halInit(); + chSysInit(); + coord_t i, j; + + /* Initialize and clear the display */ + gdispInit(); + gdispClear(Lime); + + /* Create two windows */ + GW1 = gwinCreateWindow(NULL, 20, 10, 200, 150); + GW2 = gwinCreateWindow(NULL, 50, 190, 150, 100); + + /* Set fore- and background colors for both windows */ + gwinSetColor(GW1, Black); + gwinSetBgColor(GW1, White); + gwinSetColor(GW2, White); + gwinSetBgColor(GW2, Blue); + + /* Clear both windows - to set background color */ + gwinClear(GW1); + gwinClear(GW2); + + gwinDrawLine (GW1, 5, 30, 150, 110); + for(i=5, j=0; i < 200 && j < 150; i+=3, j+=i/20) + gwinDrawPixel (GW1, i, j); + + /* + * Draw two filled circles at the same coordinate + * of each window to demonstrate the relative coordinates + * of windows + */ + gwinFillCircle(GW1, 20, 20, 15); + gwinFillCircle(GW2, 20, 20, 15); + + while(TRUE) { + chThdSleepMilliseconds(500); + } +} + diff --git a/demos/modules/console/gfxconf.h b/demos/modules/gwin/console/gfxconf.h index 254bf181..178beb86 100644 --- a/demos/modules/console/gfxconf.h +++ b/demos/modules/gwin/console/gfxconf.h @@ -1,43 +1,43 @@ -/**
- * This file has a different license to the rest of the GFX system.
- * You can copy, modify and distribute this file as you see fit.
- * You do not need to publish your source modifications to this file.
- * The only thing you are not permitted to do is to relicense it
- * under a different license.
- */
-
-#ifndef _GFXCONF_H
-#define _GFXCONF_H
-
-/* GFX sub-systems to turn on */
-#define GFX_USE_GDISP TRUE
-#define GFX_USE_GWIN TRUE
-#define GFX_USE_GEVENT FALSE
-#define GFX_USE_GTIMER FALSE
-#define GFX_USE_GINPUT FALSE
-
-/* Features for the GDISP sub-system. */
-#define GDISP_NEED_VALIDATION TRUE
-#define GDISP_NEED_CLIP TRUE
-#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
-#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
-
-/* Builtin Fonts */
-#define GDISP_INCLUDE_FONT_SMALL TRUE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
-#define GDISP_INCLUDE_FONT_UI2 TRUE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
-
-/* Features for the GWIN sub-system. */
-#define GWIN_NEED_CONSOLE TRUE
-
-#endif /* _GFXCONF_H */
+/** + * This file has a different license to the rest of the GFX system. + * You can copy, modify and distribute this file as you see fit. + * You do not need to publish your source modifications to this file. + * The only thing you are not permitted to do is to relicense it + * under a different license. + */ + +#ifndef _GFXCONF_H +#define _GFXCONF_H + +/* GFX sub-systems to turn on */ +#define GFX_USE_GDISP TRUE +#define GFX_USE_GWIN TRUE +#define GFX_USE_GEVENT FALSE +#define GFX_USE_GTIMER FALSE +#define GFX_USE_GINPUT FALSE + +/* Features for the GDISP sub-system. */ +#define GDISP_NEED_VALIDATION TRUE +#define GDISP_NEED_CLIP TRUE +#define GDISP_NEED_TEXT TRUE +#define GDISP_NEED_CIRCLE FALSE +#define GDISP_NEED_ELLIPSE FALSE +#define GDISP_NEED_ARC FALSE +#define GDISP_NEED_SCROLL FALSE +#define GDISP_NEED_PIXELREAD FALSE +#define GDISP_NEED_CONTROL FALSE +#define GDISP_NEED_MULTITHREAD FALSE +#define GDISP_NEED_ASYNC FALSE +#define GDISP_NEED_MSGAPI FALSE + +/* Builtin Fonts */ +#define GDISP_INCLUDE_FONT_SMALL TRUE +#define GDISP_INCLUDE_FONT_LARGER FALSE +#define GDISP_INCLUDE_FONT_UI1 FALSE +#define GDISP_INCLUDE_FONT_UI2 TRUE +#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE + +/* Features for the GWIN sub-system. */ +#define GWIN_NEED_CONSOLE TRUE + +#endif /* _GFXCONF_H */ diff --git a/demos/modules/console/main.c b/demos/modules/gwin/console/main.c index 63a4c6ee..90ebf86f 100644 --- a/demos/modules/console/main.c +++ b/demos/modules/gwin/console/main.c @@ -1,87 +1,87 @@ -/*
- ChibiOS/GFX - Copyright (C) 2012, 2013
- Joel Bodenmann aka Tectu <joel@unormal.org>
-
- This file is part of ChibiOS/GFX.
-
- ChibiOS/GFX is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/GFX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ch.h"
-#include "hal.h"
-#include "chprintf.h"
-#include "gfx.h"
-
-/* The handles for our three consoles */
-GHandle GW1, GW2, GW3;
-
-/* The streams for our three consoles */
-BaseSequentialStream *S1, *S2, *S3;
-
-int main(void) {
- uint8_t i;
- font_t font1, font2;
-
- halInit();
- chSysInit();
-
- /* initialize and clear the display */
- gdispInit();
- gdispClear(Black);
- font1 = gdispOpenFont("UI2 Double");
- font2 = gdispOpenFont("Small");
-
- /* create the three console windows and set a font for each */
- GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, font1);
- GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), font2);
- GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), font2);
-
- /* Set the fore- and background colors for each console */
- gwinSetColor(GW1, Green);
- gwinSetBgColor(GW1, Black);
- gwinSetColor(GW2, White);
- gwinSetBgColor(GW2, Blue);
- gwinSetColor(GW3, Black);
- gwinSetBgColor(GW3, Red);
-
- /* clear all console windows - to set background */
- gwinClear(GW1);
- gwinClear(GW2);
- gwinClear(GW3);
-
- /* receive the stream pointers of each console */
- S1 = gwinGetConsoleStream(GW1);
- S2 = gwinGetConsoleStream(GW2);
- S3 = gwinGetConsoleStream(GW3);
-
- /* Output some data on the first console */
- for(i = 0; i < 10; i++) {
- chprintf(S1, "Hello ChibiOS/GFX!\r\n");
- }
-
- /* Output some data on the second console */
- for(i = 0; i < 16; i++) {
- chprintf(S2, "Message Nr.: %d\r\n", i+1);
- }
-
- /* Output some data on the third console */
- for(i = 0; i < 18; i++) {
- chprintf(S3, "Message Nr.: %d\r\n", i+1);
- }
-
- while(TRUE) {
- chThdSleepMilliseconds(500);
- }
-}
-
+/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu <joel@unormal.org> + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "ch.h" +#include "hal.h" +#include "chprintf.h" +#include "gfx.h" + +/* The handles for our three consoles */ +GHandle GW1, GW2, GW3; + +/* The streams for our three consoles */ +BaseSequentialStream *S1, *S2, *S3; + +int main(void) { + uint8_t i; + font_t font1, font2; + + halInit(); + chSysInit(); + + /* initialize and clear the display */ + gdispInit(); + gdispClear(Black); + font1 = gdispOpenFont("UI2 Double"); + font2 = gdispOpenFont("Small"); + + /* create the three console windows and set a font for each */ + GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, font1); + GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), font2); + GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), font2); + + /* Set the fore- and background colors for each console */ + gwinSetColor(GW1, Green); + gwinSetBgColor(GW1, Black); + gwinSetColor(GW2, White); + gwinSetBgColor(GW2, Blue); + gwinSetColor(GW3, Black); + gwinSetBgColor(GW3, Red); + + /* clear all console windows - to set background */ + gwinClear(GW1); + gwinClear(GW2); + gwinClear(GW3); + + /* receive the stream pointers of each console */ + S1 = gwinGetConsoleStream(GW1); + S2 = gwinGetConsoleStream(GW2); + S3 = gwinGetConsoleStream(GW3); + + /* Output some data on the first console */ + for(i = 0; i < 10; i++) { + chprintf(S1, "Hello ChibiOS/GFX!\r\n"); + } + + /* Output some data on the second console */ + for(i = 0; i < 16; i++) { + chprintf(S2, "Message Nr.: %d\r\n", i+1); + } + + /* Output some data on the third console */ + for(i = 0; i < 18; i++) { + chprintf(S3, "Message Nr.: %d\r\n", i+1); + } + + while(TRUE) { + chThdSleepMilliseconds(500); + } +} + diff --git a/demos/modules/gwin/slider/gfxconf.h b/demos/modules/gwin/slider/gfxconf.h new file mode 100644 index 00000000..477d7d29 --- /dev/null +++ b/demos/modules/gwin/slider/gfxconf.h @@ -0,0 +1,57 @@ +/** + * This file has a different license to the rest of the GFX system. + * You can copy, modify and distribute this file as you see fit. + * You do not need to publish your source modifications to this file. + * The only thing you are not permitted to do is to relicense it + * under a different license. + */ + +#ifndef _GFXCONF_H +#define _GFXCONF_H + +/* GFX sub-systems to turn on */ +#define GFX_USE_GDISP TRUE +#define GFX_USE_GWIN TRUE +#define GFX_USE_GEVENT TRUE +#define GFX_USE_GTIMER TRUE +#define GFX_USE_GINPUT TRUE + +/* Features for the GDISP sub-system. */ +#define GDISP_NEED_VALIDATION TRUE +#define GDISP_NEED_CLIP TRUE +#define GDISP_NEED_TEXT TRUE +#define GDISP_NEED_CIRCLE FALSE +#define GDISP_NEED_ELLIPSE FALSE +#define GDISP_NEED_ARC FALSE +#define GDISP_NEED_CONVEX_POLYGON FALSE +#define GDISP_NEED_SCROLL FALSE +#define GDISP_NEED_PIXELREAD FALSE +#define GDISP_NEED_CONTROL FALSE +#define GDISP_NEED_IMAGE FALSE +#define GDISP_NEED_MULTITHREAD TRUE +#define GDISP_NEED_ASYNC FALSE +#define GDISP_NEED_MSGAPI FALSE + +/* Builtin Fonts */ +#define GDISP_INCLUDE_FONT_SMALL FALSE +#define GDISP_INCLUDE_FONT_LARGER FALSE +#define GDISP_INCLUDE_FONT_UI1 FALSE +#define GDISP_INCLUDE_FONT_UI2 TRUE +#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE + +/* GDISP image decoders */ +#define GDISP_NEED_IMAGE_NATIVE FALSE +#define GDISP_NEED_IMAGE_GIF FALSE +#define GDISP_NEED_IMAGE_BMP FALSE +#define GDISP_NEED_IMAGE_JPG FALSE +#define GDISP_NEED_IMAGE_PNG FALSE + +/* Features for the GWIN sub-system. */ +#define GWIN_NEED_BUTTON FALSE +#define GWIN_NEED_CONSOLE TRUE +#define GWIN_NEED_SLIDER TRUE + +/* Features for the GINPUT sub-system. */ +#define GINPUT_NEED_MOUSE TRUE + +#endif /* _GFXCONF_H */ diff --git a/demos/modules/gwin/slider/main.c b/demos/modules/gwin/slider/main.c new file mode 100644 index 00000000..9a318943 --- /dev/null +++ b/demos/modules/gwin/slider/main.c @@ -0,0 +1,89 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu <joel@unormal.org> + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "ch.h" +#include "hal.h" +#include "gfx.h" +#include "chprintf.h" + +static GListener gl; + +#define SLIDER_WIDTH 20 + +int main(void) { + coord_t swidth, sheight; + GHandle ghSliderH, ghSliderV, ghConsole; + font_t fui2; + GSourceHandle gsMouse; + GEventGWinSlider * pSliderEvent; + BaseSequentialStream *consout; + + halInit(); // Initialize the Hardware + chSysInit(); // Initialize the OS + gdispInit(); // Initialize the display + + gdispClear(Black); + + // Get the display dimensions + swidth = gdispGetWidth(); + sheight = gdispGetHeight(); + + // Get the font + fui2 = gdispOpenFont("UI2"); + + // Create out gwin windows/widgets + ghSliderH = gwinCreateSlider(NULL, 5, 5, swidth-10, SLIDER_WIDTH); + ghSliderV = gwinCreateSlider(NULL, 5, 10+SLIDER_WIDTH, SLIDER_WIDTH, sheight-15+SLIDER_WIDTH); + ghConsole = gwinCreateConsole(NULL, 10+SLIDER_WIDTH, 10+SLIDER_WIDTH, swidth-15-SLIDER_WIDTH, sheight-15-SLIDER_WIDTH, fui2); + consout = gwinGetConsoleStream(ghConsole); + + // Color up the console window + gwinSetColor(ghConsole, White); + gwinSetBgColor(ghConsole, Blue); + + // Assign the mouse to the sliders. + gsMouse = ginputGetMouse(0); + gwinAttachSliderMouseSource(ghSliderH, gsMouse); + gwinAttachSliderMouseSource(ghSliderV, gsMouse); + + // We want to listen for slider events + geventListenerInit(&gl); + geventAttachSource(&gl, gwinGetSliderSource(ghSliderH), 0); + geventAttachSource(&gl, gwinGetSliderSource(ghSliderV), 0); + + // Draw everything on the screen + gwinClear(ghConsole); + gwinSliderDraw(ghSliderH); + gwinSliderDraw(ghSliderV); + + while(1) { + // Get an Event + // - we can assume it is a slider event as that is all we are listening for + pSliderEvent = (GEventGWinSlider *)geventEventWait(&gl, TIME_INFINITE); + + // Double check that assumption + if (pSliderEvent->type != GEVENT_GWIN_SLIDER) + continue; + + chprintf(consout, "%c=%d\n", pSliderEvent->slider == ghSliderH ? 'H' : 'V', pSliderEvent->position); + } + + return 0; +} diff --git a/demos/modules/gwin/slider/result_647x490.png b/demos/modules/gwin/slider/result_647x490.png Binary files differnew file mode 100644 index 00000000..c7b12a93 --- /dev/null +++ b/demos/modules/gwin/slider/result_647x490.png diff --git a/gfxconf.example.h b/gfxconf.example.h index c9a91f2d..5d29600f 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -76,6 +76,7 @@ #define GWIN_NEED_BUTTON FALSE #define GWIN_NEED_CONSOLE FALSE #define GWIN_NEED_GRAPH FALSE +#define GWIN_NEED_SLIDER FALSE /* Features for the GEVENT subsystem. */ #define GEVENT_ASSERT_NO_RESOURCE FALSE diff --git a/include/gwin/gwin.h b/include/gwin/gwin.h index e6b42b31..47c2e38d 100644 --- a/include/gwin/gwin.h +++ b/include/gwin/gwin.h @@ -488,6 +488,29 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt); #endif +#if GDISP_NEED_IMAGE || defined(__DOXYGEN__) + /** + * @brief Draw the image + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @param[in] gh The window handle + * @param[in] img The image structure + * @param[in] x,y The window location to draw the image + * @param[in] cx,cy The area on the screen to draw + * @param[in] sx,sy The image position to start drawing at + * + * @pre gdispImageOpen() must have returned successfully. + * + * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image + * is simply not drawn. + * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a + * fast blit from the cached frame. If not, it reads the input and decodes it as it + * is drawing. This may be significantly slower than if the image has been cached (but + * uses a lot less RAM) + */ + gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); +#endif + #ifdef __cplusplus } #endif @@ -496,6 +519,7 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor #include "gwin/console.h" #include "gwin/button.h" #include "gwin/graph.h" +#include "gwin/slider.h" #endif /* GFX_USE_GWIN */ diff --git a/include/gwin/options.h b/include/gwin/options.h index 4ec9ba5d..e8d527e0 100644 --- a/include/gwin/options.h +++ b/include/gwin/options.h @@ -59,6 +59,13 @@ #ifndef GWIN_NEED_GRAPH #define GWIN_NEED_GRAPH FALSE #endif + /** + * @brief Should slider functions be included. + * @details Defaults to FALSE + */ + #ifndef GWIN_NEED_SLIDER + #define GWIN_NEED_SLIDER FALSE + #endif /** * @} * diff --git a/include/gwin/slider.h b/include/gwin/slider.h new file mode 100644 index 00000000..c7599b33 --- /dev/null +++ b/include/gwin/slider.h @@ -0,0 +1,233 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu <joel@unormal.org> + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @file include/gwin/slider.h + * @brief GWIN Graphic window subsystem header file. + * + * @defgroup Slider Slider + * @ingroup GWIN + * + * @details Create sliders with different styles + * + * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h + * @pre GWIN_NEED_SLIDER must be set to TRUE in your gfxconf.h + * @{ + */ + +#ifndef _GWIN_SLIDER_H +#define _GWIN_SLIDER_H + +#if GWIN_NEED_SLIDER || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +#define GW_SLIDER 0x0004 +#define GEVENT_GWIN_SLIDER (GEVENT_GWIN_FIRST+1) + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +typedef struct GEventGWinSlider_t { + GEventType type; // The type of this event (GEVENT_GWIN_BUTTON) + GHandle slider; // The slider that is returning results + int position; +} GEventGWinSlider; + +// There are currently no GEventGWinSlider listening flags - use 0 + +typedef struct GSliderDrawStyle_t { + color_t color_edge; + color_t color_thumb; + color_t color_active; + color_t color_inactive; +} GSliderDrawStyle; + +typedef void (*GSliderDrawFunction)(GHandle gh, bool_t isVertical, coord_t thumbpos, const GSliderDrawStyle *pstyle, void *param); + +// A button window +typedef struct GSliderObject_t { + GWindowObject gwin; + + GSliderDrawStyle style; + bool_t tracking; + int min; + int max; + int pos; + GSliderDrawFunction fn; + void *param; + GListener listener; +} GSliderObject; + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a slider window. + * @return NULL if there is no resultant drawing area, otherwise a window handle. + * + * @param[in] gb The GSliderObject structure to initialise. If this is NULL the structure is dynamically allocated. + * @param[in] x,y The screen co-ordinates for the bottom left corner of the window + * @param[in] width The width of the window + * @param[in] height The height of the window + * @note The drawing color gets set to White and the background drawing color to Black. + * @note The dimensions and position may be changed to fit on the real screen. + * @note The slider is not automatically drawn. Call gwinSliderDraw() after changing the slider style. + * @note Sets the slider range from 0 to 100 with an initial position of 0 + * + * @api + */ +GHandle gwinCreateSlider(GSliderObject *gb, coord_t x, coord_t y, coord_t width, coord_t height); + +/** + * @brief Set the slider range. + * + * @param[in] gh The window handle (must be a slider window) + * @param[in] min The minimum value + * @param[in] max The maximum value + * @note Sets the position to the minimum value. + * @note The slider is not automatically drawn. Call gwinSliderDraw() after changing the range. + * + * @api + */ +void gwinSetSliderRange(GHandle gh, int min, int max); + +/** + * @brief Set the slider position. + * + * @param[in] gh The window handle (must be a slider window) + * @param[in] pos The new position + * @note If the new position is outside the slider range then the position + * is set to the closest end of the range. + * @note The slider is not automatically drawn. Call gwinSliderDraw() after changing the position. + * + * @api + */ +void gwinSetSliderPosition(GHandle gh, int pos); + +/** + * @brief Set the style of a slider. + * @details The slider style is defined by its colours. + * + * @param[in] gh The window handle (must be a slider window) + * @param[in] pStyle The styling for the slider. + * + * @note The slider is not automatically redrawn. Call gwinSliderDraw() after changing the slider style + * @note The slider style is copied into the internal slider structure - there is no need to + * maintain a static style structure. + * + * @api + */ +void gwinSetSliderStyle(GHandle gh, const GSliderDrawStyle *pStyle); + +/** + * @brief Redraw the slider. + * + * @param[in] gh The window handle (must be a slider window) + * + * @api + */ +void gwinSliderDraw(GHandle gh); + +/** + * @brief Set the callback routine to perform a custom button drawing. + * + * @param[in] gh The window handle (must be a button window) + * @param[in] fn The function to use to draw the button + * @param[in] param A parameter to pass to the button drawing function + * + * @api + */ +void gwinSetSliderCustom(GHandle gh, GSliderDrawFunction fn, void *param); + +/** + * @brief Get the current slider position. + * @return The slider position + * + * @param[in] gh The window handle (must be a button window) + * + * @note The use of a listener to get the slider position is recommended if you + * want continuous updates on the slider position. + * + * @api + */ +#define gwinGetSliderPosition(gh) (((GSliderObject *)(gh))->pos) + +/** + * @brief Get the source handle of a slider + * @details Get the source handle of a slider so the application can listen for events + * + * @param[in] gh The window handle + * + * @api + */ +#define gwinGetSliderSource(gh) ((GSourceHandle)(gh)) + +#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE + /** + * @brief Attach a mouse source + * @details Attach a mouse source to a slider + * + * @param[in] gh The button handle + * @param[in] gsh The source handle + * + * @api + */ + bool_t gwinAttachSliderMouseSource(GHandle gh, GSourceHandle gsh); +#endif + +/** + * @brief Standard slider drawing routines + * @details This routine is called to draw the standard slider. + * + * @param[in] gh The button handle + * @param[in] isVertical The slider is vertically oriented instead of horizontal + * @param[in] thumbpos The position of the slider (0..cx-1 or cy-1..0) + * @param[in] pstyle The current drawing style + * @param[in] param A parameter passed in from the user + * + * @note In your custom slider drawing function you may optionally call this + * standard functions and then draw your extra details on top. + * @note The standard functions below ignore the param parameter. It is there + * only to ensure the functions match the GSliderDrawFunction type. + * @note When called by a slider the framework ensure that it is + * a slider object and sets up clipping to the slider object window. These + * drawing routines then don't have to worry about explicitly doing that. + * + * @api + */ +void gwinSliderDraw_Std(GHandle gh, bool_t isVertical, coord_t thumbpos, const GSliderDrawStyle *pstyle, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /* GWIN_NEED_SLIDER */ + +#endif /* _GWIN_SLIDER_H */ +/** @} */ + diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index a2b702e2..58d75694 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -90,6 +90,12 @@ void gwinDestroyWindow(GHandle gh) { geventDetachSourceListeners((GSourceHandle)gh); break; #endif +#if GWIN_NEED_SLIDER + case GW_SLIDER: + geventDetachSource(&((GSliderObject *)gh)->listener, 0); + geventDetachSourceListeners((GSourceHandle)gh); + break; +#endif default: break; } @@ -285,6 +291,15 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } #endif +#if GDISP_NEED_IMAGE + gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + return gdispImageDraw(img, gh->x+x, gh->y+y, cx, cy, sx, sy); + } +#endif + #endif /* GFX_USE_GWIN */ /** @} */ diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk index 34a57c91..804d5ac9 100644 --- a/src/gwin/gwin.mk +++ b/src/gwin/gwin.mk @@ -1,5 +1,6 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ $(GFXLIB)/src/gwin/console.c \ $(GFXLIB)/src/gwin/button.c \ + $(GFXLIB)/src/gwin/slider.c \ $(GFXLIB)/src/gwin/graph.c diff --git a/src/gwin/slider.c b/src/gwin/slider.c new file mode 100644 index 00000000..034ba6b2 --- /dev/null +++ b/src/gwin/slider.c @@ -0,0 +1,281 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu <joel@unormal.org> + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @file src/gwin/slider.c + * @brief GWIN sub-system slider code. + * + * @defgroup Slider Slider + * @ingroup GWIN + * + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "gfx.h" + +#if (GFX_USE_GWIN && GWIN_NEED_SLIDER) || defined(__DOXYGEN__) + +#include "gwin/internal.h" + +#ifndef GWIN_SLIDER_DEAD_BAND + #define GWIN_SLIDER_DEAD_BAND 5 +#endif + +static void trackSliderDraw(GHandle gh, coord_t x, coord_t y); + +static const GSliderDrawStyle GSliderDefaultStyle = { + HTML2COLOR(0x404040), // color_edge; + HTML2COLOR(0x000000), // color_thumb; + HTML2COLOR(0x00E000), // color_active; + HTML2COLOR(0xE0E0E0), // color_inactive; +}; + +// Process an event callback +static void gwinSliderCallback(void *param, GEvent *pe) { + GSourceListener *psl; + #define gh ((GHandle)param) + #define gsw ((GSliderObject *)param) + #define gsh ((GSourceHandle)param) + #define pme ((GEventMouse *)pe) + #define pse ((GEventGWinSlider *)pe) + + switch (pe->type) { + #if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE + case GEVENT_MOUSE: + case GEVENT_TOUCH: + // If not tracking we only only interested in a mouse down over the slider + if (!gsw->tracking) { + if ((pme->meta & GMETA_MOUSE_DOWN) + && pme->x >= gh->x && pme->x < gh->x + gh->width + && pme->y >= gh->y && pme->y < gh->y + gh->height) { + gsw->tracking = TRUE; + trackSliderDraw(gh, pme->x-gh->x, pme->y-gh->y); + } + return; + } + + // We are tracking the mouse + + // Test for button up + if ((pme->meta & GMETA_MOUSE_UP)) { + gsw->tracking = FALSE; + + #if !GWIN_BUTTON_LAZY_RELEASE + // Are we over the slider? + if (pme->x < gh->x || pme->x >= gh->x + gh->width + || pme->y < gh->y || pme->y >= gh->y + gh->height) { + // No - restore the slider + gwinSliderDraw(gh); + return; + } + #endif + + // Set the new position + if (gh->width < gh->height) + gwinSetSliderPosition(gh, + (gh->height-1-pme->y+gh->y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + else + gwinSetSliderPosition(gh, + (pme->x-gh->x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + + // Update the display + gwinSliderDraw(gh); + + // Generate the event + break; + } + + // If mouse down - track movement + if ((pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) + trackSliderDraw(gh, pme->x-gh->x, pme->y-gh->y); + + return; + #endif + + default: + return; + } + + // Trigger a GWIN Slider Event + psl = 0; + while ((psl = geventGetSourceListener(gsh, psl))) { + if (!(pe = geventGetEventBuffer(psl))) + continue; + pse->type = GEVENT_GWIN_SLIDER; + pse->slider = gh; + pse->position = gsw->pos; + geventSendEvent(psl); + } + + #undef pse + #undef pme + #undef pxe + #undef gsh + #undef gsw + #undef gh +} + +GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, coord_t height) { + if (!(gs = (GSliderObject *)_gwinInit((GWindowObject *)gs, x, y, width, height, sizeof(GSliderObject)))) + return 0; + gs->gwin.type = GW_SLIDER; + gs->fn = gwinSliderDraw_Std; + gs->param = 0; + gwinSetSliderStyle(&gs->gwin, &GSliderDefaultStyle); + gs->min = 0; + gs->max = 100; + gs->pos = 0; + gs->tracking = FALSE; + geventListenerInit(&gs->listener); + geventRegisterCallback(&gs->listener, gwinSliderCallback, gs); + return (GHandle)gs; +} + +void gwinSetSliderRange(GHandle gh, int min, int max) { + #define gsw ((GSliderObject *)gh) + + if (gh->type != GW_SLIDER) + return; + + if (min == max) // prevent divide by 0 errors. + max++; + gsw->min = min; + gsw->max = max; + gsw->pos = min; + #undef gsw +} + +void gwinSetSliderPosition(GHandle gh, int pos) { + #define gsw ((GSliderObject *)gh) + + if (gh->type != GW_SLIDER) + return; + + if (gsw->min <= gsw->max) { + if (pos < gsw->min) gsw->pos = gsw->min; + else if (pos > gsw->max) gsw->pos = gsw->max; + else gsw->pos = pos; + } else { + if (pos > gsw->min) gsw->pos = gsw->min; + else if (pos < gsw->max) gsw->pos = gsw->max; + else gsw->pos = pos; + } + #undef gsw +} + +void gwinSetSliderStyle(GHandle gh, const GSliderDrawStyle *pStyle) { + #define gsw ((GSliderObject *)gh) + + if (gh->type != GW_SLIDER) + return; + + gsw->style.color_edge = pStyle->color_edge; + gsw->style.color_thumb = pStyle->color_thumb; + gsw->style.color_active = pStyle->color_active; + gsw->style.color_inactive = pStyle->color_inactive; + #undef gsw +} + +static void trackSliderDraw(GHandle gh, coord_t x, coord_t y) { + #define gsw ((GSliderObject *)gh) + + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + + if (gh->height <= gh->width) + gsw->fn(gh, FALSE, x, &gsw->style, gsw->param); + else + gsw->fn(gh, TRUE, y, &gsw->style, gsw->param); + + #undef gbw +} + +void gwinSliderDraw(GHandle gh) { + #define gsw ((GSliderObject *)gh) + + if (gh->type != GW_SLIDER) + return; + + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + + if (gh->height <= gh->width) + gsw->fn(gh, FALSE, ((gh->width-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min), &gsw->style, gsw->param); + else + gsw->fn(gh, TRUE, gh->height-1-((gh->height-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min), &gsw->style, gsw->param); + + #undef gbw +} + +void gwinSetSliderCustom(GHandle gh, GSliderDrawFunction fn, void *param) { + #define gsw ((GSliderObject *)gh) + + if (gh->type != GW_SLIDER) + return; + + gsw->fn = fn ? fn : gwinSliderDraw_Std; + gsw->param = param; + + #undef gsw +} + +void gwinSliderDraw_Std(GHandle gh, bool_t isVertical, coord_t thumbpos, const GSliderDrawStyle *pstyle, void *param) { + (void) param; + + if (isVertical) { + if (thumbpos != gh->height-1) + gdispFillArea(gh->x, gh->y+thumbpos, gh->width, gh->height - thumbpos, pstyle->color_active); + if (thumbpos != 0) + gdispFillArea(gh->x, gh->y, gh->width, thumbpos, pstyle->color_inactive); + gdispDrawBox(gh->x, gh->y, gh->width, gh->height, pstyle->color_edge); + gdispDrawLine(gh->x, gh->y+thumbpos, gh->x+gh->width-1, gh->y+thumbpos, pstyle->color_thumb); + if (thumbpos >= 2) + gdispDrawLine(gh->x, gh->y+thumbpos-2, gh->x+gh->width-1, gh->y+thumbpos-2, pstyle->color_thumb); + if (thumbpos <= gh->height-2) + gdispDrawLine(gh->x, gh->y+thumbpos+2, gh->x+gh->width-1, gh->y+thumbpos+2, pstyle->color_thumb); + } else { + if (thumbpos != gh->width-1) + gdispFillArea(gh->x+thumbpos, gh->y, gh->width-thumbpos, gh->height, pstyle->color_inactive); + if (thumbpos != 0) + gdispFillArea(gh->x, gh->y, thumbpos, gh->height, pstyle->color_active); + gdispDrawBox(gh->x, gh->y, gh->width, gh->height, pstyle->color_edge); + gdispDrawLine(gh->x+thumbpos, gh->y, gh->x+thumbpos, gh->y+gh->height-1, pstyle->color_thumb); + if (thumbpos >= 2) + gdispDrawLine(gh->x+thumbpos-2, gh->y, gh->x+thumbpos-2, gh->y+gh->height-1, pstyle->color_thumb); + if (thumbpos <= gh->width-2) + gdispDrawLine(gh->x+thumbpos+2, gh->y, gh->x+thumbpos+2, gh->y+gh->height-1, pstyle->color_thumb); + } +} + +#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE + bool_t gwinAttachSliderMouseSource(GHandle gh, GSourceHandle gsh) { + if (gh->type != GW_SLIDER) + return FALSE; + + return geventAttachSource(&((GSliderObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES); + } +#endif + +#endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */ +/** @} */ + |