Merge pull request #58 from inmarket/master

GWIN Slider plus other cleanups
ugfx_release_2.6
Tectu 2013-04-05 04:57:11 -07:00
commit 4719e96beb
16 changed files with 1334 additions and 626 deletions

View File

@ -1,47 +1,47 @@
/** /**
* This file has a different license to the rest of the GFX system. * 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 can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file. * 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 * The only thing you are not permitted to do is to relicense it
* under a different license. * under a different license.
*/ */
#ifndef _GFXCONF_H #ifndef _GFXCONF_H
#define _GFXCONF_H #define _GFXCONF_H
/* GFX sub-systems to turn on */ /* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE #define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE #define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT TRUE #define GFX_USE_GEVENT TRUE
#define GFX_USE_GTIMER TRUE #define GFX_USE_GTIMER TRUE
#define GFX_USE_GINPUT TRUE #define GFX_USE_GINPUT TRUE
/* Features for the GDISP sub-system. */ /* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE #define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE #define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE #define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE FALSE #define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE #define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE #define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE #define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE #define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE #define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD TRUE #define GDISP_NEED_MULTITHREAD TRUE
#define GDISP_NEED_ASYNC FALSE #define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE #define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */ /* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL FALSE #define GDISP_INCLUDE_FONT_SMALL FALSE
#define GDISP_INCLUDE_FONT_LARGER FALSE #define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE #define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE #define GDISP_INCLUDE_FONT_UI2 TRUE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
/* Features for the GWIN sub-system. */ /* Features for the GWIN sub-system. */
#define GWIN_NEED_BUTTON TRUE #define GWIN_NEED_BUTTON TRUE
#define GWIN_NEED_CONSOLE TRUE #define GWIN_NEED_CONSOLE TRUE
/* Features for the GINPUT sub-system. */ /* Features for the GINPUT sub-system. */
#define GINPUT_NEED_MOUSE TRUE #define GINPUT_NEED_MOUSE TRUE
#endif /* _GFXCONF_H */ #endif /* _GFXCONF_H */

View File

@ -1,349 +1,349 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "chprintf.h" #include "chprintf.h"
#include "gfx.h" #include "gfx.h"
static GConsoleObject gc; static GConsoleObject gc;
static GButtonObject gNext; static GButtonObject gNext;
static GButtonObject gPrev; static GButtonObject gPrev;
static GListener gl; static GListener gl;
/*------------------------------------------------------------------------* /*------------------------------------------------------------------------*
* GINPUT Touch Driver Calibrator. * * GINPUT Touch Driver Calibrator. *
*------------------------------------------------------------------------*/ *------------------------------------------------------------------------*/
int main(void) { int main(void) {
GSourceHandle gs, gsNext, gsPrev; GSourceHandle gs, gsNext, gsPrev;
GEvent *pe; GEvent *pe;
GEventMouse *pem; GEventMouse *pem;
GEventGWinButton *peb; GEventGWinButton *peb;
coord_t swidth, sheight; coord_t swidth, sheight;
GHandle ghc, ghNext, ghPrev; GHandle ghc, ghNext, ghPrev;
BaseSequentialStream *gp; BaseSequentialStream *gp;
GEventType deviceType; GEventType deviceType;
font_t font; font_t font;
halInit(); // Initialise the Hardware halInit(); // Initialise the Hardware
chSysInit(); // Initialize the OS chSysInit(); // Initialize the OS
gdispInit(); // Initialize the display gdispInit(); // Initialize the display
// Get the display dimensions // Get the display dimensions
swidth = gdispGetWidth(); swidth = gdispGetWidth();
sheight = gdispGetHeight(); sheight = gdispGetHeight();
ghNext = ghPrev = 0; ghNext = ghPrev = 0;
// Create our title // Create our title
font = gdispOpenFont("UI2"); font = gdispOpenFont("UI2");
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Red, White, justifyLeft); gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Red, White, justifyLeft);
// Create our main display window // Create our main display window
ghc = gwinCreateConsole(&gc, 0, 20, swidth, sheight-20, font); ghc = gwinCreateConsole(&gc, 0, 20, swidth, sheight-20, font);
gwinClear(ghc); gwinClear(ghc);
gp = gwinGetConsoleStream(ghc); gp = gwinGetConsoleStream(ghc);
// Initialize the mouse in our special no calibration mode. // Initialize the mouse in our special no calibration mode.
geventListenerInit(&gl); geventListenerInit(&gl);
gs = ginputGetMouse(9999); gs = ginputGetMouse(9999);
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
/* /*
* Test: Device Type * Test: Device Type
*/ */
StepDeviceType: StepDeviceType:
gwinClear(ghc); gwinClear(ghc);
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "\n1. DEVICE TYPE\n\n"); chprintf(gp, "\n1. DEVICE TYPE\n\n");
pem = (GEventMouse *)&gl.event; pem = (GEventMouse *)&gl.event;
ginputGetMouseStatus(0, pem); ginputGetMouseStatus(0, pem);
deviceType = pem->type; deviceType = pem->type;
gwinSetColor(ghc, White); gwinSetColor(ghc, White);
chprintf(gp, "This is detected as a %s device\n\n", chprintf(gp, "This is detected as a %s device\n\n",
deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN")); deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN"));
if (ghNext) if (ghNext)
chprintf(gp, "Press Next or Back to continue.\n"); chprintf(gp, "Press Next or Back to continue.\n");
else if (deviceType == GEVENT_MOUSE) else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Click the mouse button to move on to the next test.\n"); chprintf(gp, "Click the mouse button to move on to the next test.\n");
else else
chprintf(gp, "Press and release your finger to move on to the next test.\n"); chprintf(gp, "Press and release your finger to move on to the next test.\n");
while(1) { while(1) {
pe = geventEventWait(&gl, TIME_INFINITE); pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) { if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe; peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev) if (peb->button == ghPrev)
goto StepClickJitter; goto StepClickJitter;
if (peb->button == ghNext) if (peb->button == ghNext)
break; break;
} }
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe; pem = (GEventMouse *)pe;
if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break; break;
} }
} }
/* /*
* Test: Mouse raw reading jitter * Test: Mouse raw reading jitter
*/ */
StepRawJitter: StepRawJitter:
gwinClear(ghc); gwinClear(ghc);
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n"); chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n");
gwinSetColor(ghc, White); gwinSetColor(ghc, White);
if (deviceType == GEVENT_MOUSE) if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Press and hold the mouse button.\n\n"); chprintf(gp, "Press and hold the mouse button.\n\n");
else else
chprintf(gp, "Press and hold on the surface.\n\n"); chprintf(gp, "Press and hold on the surface.\n\n");
chprintf(gp, "Numbers will display in this window.\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" "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"); "Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n");
if (ghNext) if (ghNext)
chprintf(gp, "Press Next or Back to continue.\n"); chprintf(gp, "Press Next or Back to continue.\n");
else if (deviceType == GEVENT_MOUSE) else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Release the mouse button to move on to the next test.\n"); chprintf(gp, "Release the mouse button to move on to the next test.\n");
else else
chprintf(gp, "Release your finger to move on to the next test.\n"); chprintf(gp, "Release your finger to move on to the next test.\n");
// For this test turn on ALL mouse movement events // For this test turn on ALL mouse movement events
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER); geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER);
while(1) { while(1) {
pe = geventEventWait(&gl, TIME_INFINITE); pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) { if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe; peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev) if (peb->button == ghPrev)
goto StepDeviceType; goto StepDeviceType;
if (peb->button == ghNext) if (peb->button == ghNext)
break; break;
} }
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe; pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, "%u:%u\n", pem->x, pem->y); chprintf(gp, "%u:%u\n", pem->x, pem->y);
if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break; break;
} }
} }
// Reset to just changed movements. // Reset to just changed movements.
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
/* /*
* Test: Calibration * Test: Calibration
*/ */
StepCalibrate: StepCalibrate:
gwinClear(ghc); gwinClear(ghc);
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n"); chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n");
gwinSetColor(ghc, Gray); gwinSetColor(ghc, Gray);
chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n"); chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n");
gwinSetColor(ghc, White); gwinSetColor(ghc, White);
chprintf(gp, "You will be presented with a number of points to touch.\nPress them in turn.\n\n" 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 the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n");
if (ghNext) if (ghNext)
chprintf(gp, "Press Next to start the calibration.\n"); chprintf(gp, "Press Next to start the calibration.\n");
else if (deviceType == GEVENT_MOUSE) else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Click the mouse button to start the calibration.\n"); chprintf(gp, "Click the mouse button to start the calibration.\n");
else else
chprintf(gp, "Press and release your finger to start the calibration.\n"); chprintf(gp, "Press and release your finger to start the calibration.\n");
while(1) { while(1) {
pe = geventEventWait(&gl, TIME_INFINITE); pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) { if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe; peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev) if (peb->button == ghPrev)
goto StepRawJitter; goto StepRawJitter;
if (peb->button == ghNext) if (peb->button == ghNext)
break; break;
} }
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe; pem = (GEventMouse *)pe;
if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break; break;
} }
} }
// Calibrate // Calibrate
ginputCalibrateMouse(0); ginputCalibrateMouse(0);
/* From now on we can use Next and Previous Buttons */ /* From now on we can use Next and Previous Buttons */
if (!ghNext) { if (!ghNext) {
ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, font, GBTN_NORMAL); ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, font, GBTN_NORMAL);
gwinSetButtonText(ghNext, "Next", FALSE); gwinSetButtonText(ghNext, "Next", FALSE);
gsNext = gwinGetButtonSource(ghNext); gsNext = gwinGetButtonSource(ghNext);
geventAttachSource(&gl, gsNext, 0); geventAttachSource(&gl, gsNext, 0);
gwinAttachButtonMouseSource(ghNext, gs); gwinAttachButtonMouseSource(ghNext, gs);
ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL); ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL);
gwinSetButtonText(ghPrev, "Back", FALSE); gwinSetButtonText(ghPrev, "Back", FALSE);
gsPrev = gwinGetButtonSource(ghPrev); gsPrev = gwinGetButtonSource(ghPrev);
geventAttachSource(&gl, gsPrev, 0); geventAttachSource(&gl, gsPrev, 0);
gwinAttachButtonMouseSource(ghPrev, gs); gwinAttachButtonMouseSource(ghPrev, gs);
#if 0 #if 0
{ {
GSourceHandle gsButton1, gsButton2; GSourceHandle gsButton1, gsButton2;
// Attach a couple of hardware toggle buttons to our Next and Back buttons as well. // 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. // 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 // This code depends on your hardware. Turn it on only if you have
// defined a board definition for your toggle driver. Then change // defined a board definition for your toggle driver. Then change
// the next two lines to be correct for your hardware. The values // the next two lines to be correct for your hardware. The values
// below are correct for the Win32 toggle driver. // below are correct for the Win32 toggle driver.
gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1); gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1);
gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2); gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2);
gwinAttachButtonToggleSource(ghNext, gsButton2); gwinAttachButtonToggleSource(ghNext, gsButton2);
gwinAttachButtonToggleSource(ghPrev, gsButton1); gwinAttachButtonToggleSource(ghPrev, gsButton1);
} }
#endif #endif
} }
// Calibration used the whole screen - re-establish our title // Calibration used the whole screen - re-establish our title
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Green, White, justifyLeft); gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Green, White, justifyLeft);
gwinButtonDraw(ghNext); gwinButtonDraw(ghNext);
gwinButtonDraw(ghPrev); gwinButtonDraw(ghPrev);
/* /*
* Test: Mouse movement jitter * Test: Mouse movement jitter
*/ */
StepJitter: StepJitter:
gwinClear(ghc); gwinClear(ghc);
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n"); chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n");
gwinSetColor(ghc, White); gwinSetColor(ghc, White);
if (deviceType == GEVENT_MOUSE) if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n"); chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n");
else else
chprintf(gp, "Press firmly on the surface and move around as if to draw.\n\n"); 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 " 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" "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"); "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"); chprintf(gp, "Press Next or Back to continue.\n\n");
while(1) { while(1) {
pe = geventEventWait(&gl, TIME_INFINITE); pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) { if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe; peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev) if (peb->button == ghPrev)
goto StepCalibrate; goto StepCalibrate;
if (peb->button == ghNext) if (peb->button == ghNext)
break; break;
} }
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe; pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, "."); chprintf(gp, ".");
} }
} }
/* /*
* Test: Polling frequency * Test: Polling frequency
*/ */
StepPolling: StepPolling:
gwinClear(ghc); gwinClear(ghc);
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n"); chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n");
gwinSetColor(ghc, White); 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, "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" chprintf(gp, "A green line will follow your finger.\n"
"Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without " "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" "gaps that are too big.\nDecreasing the value increases CPU usage.\n"
"About 25 (millisecs) normally produces good results." "About 25 (millisecs) normally produces good results."
"This test can be ignored for interrupt driven drivers.\n\n"); "This test can be ignored for interrupt driven drivers.\n\n");
chprintf(gp, "Press Next or Back to continue.\n\n"); chprintf(gp, "Press Next or Back to continue.\n\n");
while(1) { while(1) {
pe = geventEventWait(&gl, TIME_INFINITE); pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) { if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe; peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev) if (peb->button == ghPrev)
goto StepJitter; goto StepJitter;
if (peb->button == ghNext) if (peb->button == ghNext)
break; break;
} }
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe; pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
gdispDrawPixel(pem->x, pem->y, Green); gdispDrawPixel(pem->x, pem->y, Green);
} }
} }
/* /*
* Test: Click Jitter * Test: Click Jitter
*/ */
StepClickJitter: StepClickJitter:
gwinClear(ghc); gwinClear(ghc);
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n"); chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n");
gwinSetColor(ghc, White); gwinSetColor(ghc, White);
chprintf(gp, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n"); 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, "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. " 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" "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_JITTER to the smallest value that this reliably works for.\n"
"Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\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" "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"); "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"); chprintf(gp, "This is the last test but you can press Next or Back to continue.\n\n");
while(1) { while(1) {
pe = geventEventWait(&gl, TIME_INFINITE); pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) { if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe; peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev) if (peb->button == ghPrev)
goto StepPolling; goto StepPolling;
if (peb->button == ghNext) if (peb->button == ghNext)
break; break;
} }
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe; pem = (GEventMouse *)pe;
if ((pem->meta & GMETA_MOUSE_CLICK)) { if ((pem->meta & GMETA_MOUSE_CLICK)) {
gwinSetColor(ghc, Yellow); gwinSetColor(ghc, Yellow);
chprintf(gp, "-"); chprintf(gp, "-");
} }
if ((pem->meta & GMETA_MOUSE_CXTCLICK)) { if ((pem->meta & GMETA_MOUSE_CXTCLICK)) {
gwinSetColor(ghc, Red); gwinSetColor(ghc, Red);
chprintf(gp, "x"); chprintf(gp, "x");
} }
} }
} }
// Can't let this really exit // Can't let this really exit
goto StepDeviceType; goto StepDeviceType;
} }

View File

@ -1,33 +1,33 @@
/** /**
* This file has a different license to the rest of the GFX system. * 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 can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file. * 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 * The only thing you are not permitted to do is to relicense it
* under a different license. * under a different license.
*/ */
#ifndef _GFXCONF_H #ifndef _GFXCONF_H
#define _GFXCONF_H #define _GFXCONF_H
/* GFX sub-systems to turn on */ /* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE #define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE #define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT FALSE #define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE #define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE #define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */ /* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE #define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE #define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT FALSE #define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE TRUE #define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_ELLIPSE FALSE #define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE #define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE #define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE #define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE #define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE #define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE #define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE #define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */ #endif /* _GFXCONF_H */

View File

@ -1,67 +1,67 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "gfx.h" #include "gfx.h"
/* The handles for our two Windows */ /* The handles for our two Windows */
GHandle GW1, GW2; GHandle GW1, GW2;
int main(void) { int main(void) {
halInit(); halInit();
chSysInit(); chSysInit();
coord_t i, j; coord_t i, j;
/* Initialize and clear the display */ /* Initialize and clear the display */
gdispInit(); gdispInit();
gdispClear(Lime); gdispClear(Lime);
/* Create two windows */ /* Create two windows */
GW1 = gwinCreateWindow(NULL, 20, 10, 200, 150); GW1 = gwinCreateWindow(NULL, 20, 10, 200, 150);
GW2 = gwinCreateWindow(NULL, 50, 190, 150, 100); GW2 = gwinCreateWindow(NULL, 50, 190, 150, 100);
/* Set fore- and background colors for both windows */ /* Set fore- and background colors for both windows */
gwinSetColor(GW1, Black); gwinSetColor(GW1, Black);
gwinSetBgColor(GW1, White); gwinSetBgColor(GW1, White);
gwinSetColor(GW2, White); gwinSetColor(GW2, White);
gwinSetBgColor(GW2, Blue); gwinSetBgColor(GW2, Blue);
/* Clear both windows - to set background color */ /* Clear both windows - to set background color */
gwinClear(GW1); gwinClear(GW1);
gwinClear(GW2); gwinClear(GW2);
gwinDrawLine (GW1, 5, 30, 150, 110); gwinDrawLine (GW1, 5, 30, 150, 110);
for(i=5, j=0; i < 200 && j < 150; i+=3, j+=i/20) for(i=5, j=0; i < 200 && j < 150; i+=3, j+=i/20)
gwinDrawPixel (GW1, i, j); gwinDrawPixel (GW1, i, j);
/* /*
* Draw two filled circles at the same coordinate * Draw two filled circles at the same coordinate
* of each window to demonstrate the relative coordinates * of each window to demonstrate the relative coordinates
* of windows * of windows
*/ */
gwinFillCircle(GW1, 20, 20, 15); gwinFillCircle(GW1, 20, 20, 15);
gwinFillCircle(GW2, 20, 20, 15); gwinFillCircle(GW2, 20, 20, 15);
while(TRUE) { while(TRUE) {
chThdSleepMilliseconds(500); chThdSleepMilliseconds(500);
} }
} }

View File

@ -1,43 +1,43 @@
/** /**
* This file has a different license to the rest of the GFX system. * 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 can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file. * 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 * The only thing you are not permitted to do is to relicense it
* under a different license. * under a different license.
*/ */
#ifndef _GFXCONF_H #ifndef _GFXCONF_H
#define _GFXCONF_H #define _GFXCONF_H
/* GFX sub-systems to turn on */ /* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE #define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE #define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT FALSE #define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE #define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE #define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */ /* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE #define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE #define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE #define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE FALSE #define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE #define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE #define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE #define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE #define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE #define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE #define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE #define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE #define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */ /* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL TRUE #define GDISP_INCLUDE_FONT_SMALL TRUE
#define GDISP_INCLUDE_FONT_LARGER FALSE #define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE #define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE #define GDISP_INCLUDE_FONT_UI2 TRUE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
/* Features for the GWIN sub-system. */ /* Features for the GWIN sub-system. */
#define GWIN_NEED_CONSOLE TRUE #define GWIN_NEED_CONSOLE TRUE
#endif /* _GFXCONF_H */ #endif /* _GFXCONF_H */

View File

@ -1,87 +1,87 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "chprintf.h" #include "chprintf.h"
#include "gfx.h" #include "gfx.h"
/* The handles for our three consoles */ /* The handles for our three consoles */
GHandle GW1, GW2, GW3; GHandle GW1, GW2, GW3;
/* The streams for our three consoles */ /* The streams for our three consoles */
BaseSequentialStream *S1, *S2, *S3; BaseSequentialStream *S1, *S2, *S3;
int main(void) { int main(void) {
uint8_t i; uint8_t i;
font_t font1, font2; font_t font1, font2;
halInit(); halInit();
chSysInit(); chSysInit();
/* initialize and clear the display */ /* initialize and clear the display */
gdispInit(); gdispInit();
gdispClear(Black); gdispClear(Black);
font1 = gdispOpenFont("UI2 Double"); font1 = gdispOpenFont("UI2 Double");
font2 = gdispOpenFont("Small"); font2 = gdispOpenFont("Small");
/* create the three console windows and set a font for each */ /* create the three console windows and set a font for each */
GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, font1); GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, font1);
GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), font2); GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), font2);
GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), font2); GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), font2);
/* Set the fore- and background colors for each console */ /* Set the fore- and background colors for each console */
gwinSetColor(GW1, Green); gwinSetColor(GW1, Green);
gwinSetBgColor(GW1, Black); gwinSetBgColor(GW1, Black);
gwinSetColor(GW2, White); gwinSetColor(GW2, White);
gwinSetBgColor(GW2, Blue); gwinSetBgColor(GW2, Blue);
gwinSetColor(GW3, Black); gwinSetColor(GW3, Black);
gwinSetBgColor(GW3, Red); gwinSetBgColor(GW3, Red);
/* clear all console windows - to set background */ /* clear all console windows - to set background */
gwinClear(GW1); gwinClear(GW1);
gwinClear(GW2); gwinClear(GW2);
gwinClear(GW3); gwinClear(GW3);
/* receive the stream pointers of each console */ /* receive the stream pointers of each console */
S1 = gwinGetConsoleStream(GW1); S1 = gwinGetConsoleStream(GW1);
S2 = gwinGetConsoleStream(GW2); S2 = gwinGetConsoleStream(GW2);
S3 = gwinGetConsoleStream(GW3); S3 = gwinGetConsoleStream(GW3);
/* Output some data on the first console */ /* Output some data on the first console */
for(i = 0; i < 10; i++) { for(i = 0; i < 10; i++) {
chprintf(S1, "Hello ChibiOS/GFX!\r\n"); chprintf(S1, "Hello ChibiOS/GFX!\r\n");
} }
/* Output some data on the second console */ /* Output some data on the second console */
for(i = 0; i < 16; i++) { for(i = 0; i < 16; i++) {
chprintf(S2, "Message Nr.: %d\r\n", i+1); chprintf(S2, "Message Nr.: %d\r\n", i+1);
} }
/* Output some data on the third console */ /* Output some data on the third console */
for(i = 0; i < 18; i++) { for(i = 0; i < 18; i++) {
chprintf(S3, "Message Nr.: %d\r\n", i+1); chprintf(S3, "Message Nr.: %d\r\n", i+1);
} }
while(TRUE) { while(TRUE) {
chThdSleepMilliseconds(500); chThdSleepMilliseconds(500);
} }
} }

View File

@ -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 */

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -76,6 +76,7 @@
#define GWIN_NEED_BUTTON FALSE #define GWIN_NEED_BUTTON FALSE
#define GWIN_NEED_CONSOLE FALSE #define GWIN_NEED_CONSOLE FALSE
#define GWIN_NEED_GRAPH FALSE #define GWIN_NEED_GRAPH FALSE
#define GWIN_NEED_SLIDER FALSE
/* Features for the GEVENT subsystem. */ /* Features for the GEVENT subsystem. */
#define GEVENT_ASSERT_NO_RESOURCE FALSE #define GEVENT_ASSERT_NO_RESOURCE FALSE

View File

@ -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); void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
#endif #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 #ifdef __cplusplus
} }
#endif #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/console.h"
#include "gwin/button.h" #include "gwin/button.h"
#include "gwin/graph.h" #include "gwin/graph.h"
#include "gwin/slider.h"
#endif /* GFX_USE_GWIN */ #endif /* GFX_USE_GWIN */

View File

@ -59,6 +59,13 @@
#ifndef GWIN_NEED_GRAPH #ifndef GWIN_NEED_GRAPH
#define GWIN_NEED_GRAPH FALSE #define GWIN_NEED_GRAPH FALSE
#endif #endif
/**
* @brief Should slider functions be included.
* @details Defaults to FALSE
*/
#ifndef GWIN_NEED_SLIDER
#define GWIN_NEED_SLIDER FALSE
#endif
/** /**
* @} * @}
* *

View File

@ -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 */
/** @} */

View File

@ -89,6 +89,12 @@ void gwinDestroyWindow(GHandle gh) {
geventDetachSource(&((GButtonObject *)gh)->listener, 0); geventDetachSource(&((GButtonObject *)gh)->listener, 0);
geventDetachSourceListeners((GSourceHandle)gh); geventDetachSourceListeners((GSourceHandle)gh);
break; break;
#endif
#if GWIN_NEED_SLIDER
case GW_SLIDER:
geventDetachSource(&((GSliderObject *)gh)->listener, 0);
geventDetachSourceListeners((GSourceHandle)gh);
break;
#endif #endif
default: default:
break; break;
@ -285,6 +291,15 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
} }
#endif #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 */ #endif /* GFX_USE_GWIN */
/** @} */ /** @} */

View File

@ -1,5 +1,6 @@
GFXSRC += $(GFXLIB)/src/gwin/gwin.c \ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \
$(GFXLIB)/src/gwin/console.c \ $(GFXLIB)/src/gwin/console.c \
$(GFXLIB)/src/gwin/button.c \ $(GFXLIB)/src/gwin/button.c \
$(GFXLIB)/src/gwin/slider.c \
$(GFXLIB)/src/gwin/graph.c $(GFXLIB)/src/gwin/graph.c

281
src/gwin/slider.c 100644
View File

@ -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 */
/** @} */