fred Posted February 20, 2014 Report Posted February 20, 2014 Hi,I'm implementing an on-screen keypad with buttons and I've stumbled on a problem. I have 12 buttons ([0..9] and a few control) and I want to register them with the same callback. At the callback I want to find out which button was pressed, but I'm unable to figure it out. In my callback I get a (void)* param and a Gevent; as far as I can tell all the button source can't be determined with the Gevent functions.My second thought was to add a custom variable to the Button on initialisation which can then be querried from the Gevent, but which of them are used internally and which are available for custom data?I'd like to add that I implemented it without buttons (use screen locations as in the Notepad example and get "button" events by filtering the touch coordinates) but I've abandoned that approach because the code turned out rather messy.regards,Fred
Joel Bodenmann Posted February 20, 2014 Report Posted February 20, 2014 You should be able to retrieve the button information from the gevent structure that you get passed in your callback:void _callback(void* param, GEvent *pe) { ... ((GEventGWinButton *)pe)->button ...}It's exactly the same as you do when handling the returned GEvent from geventEventWait() within the main(). Note that I did not try this code and it comes completely out of my mind. I'm on the bus.I hope that helps a bit.~ Tectu
Joel Bodenmann Posted February 21, 2014 Report Posted February 21, 2014 Please but me know whether it worked or not. ~ Tectu
fred Posted February 24, 2014 Author Report Posted February 24, 2014 Hi,works like a charm, here's some code if anyone wants to try it://Keypad settings#define KEYPAD_X 550 //keypad left border#define KEYPAD_Y 100 //keypad top#define KEYPAD_WIDTH 225 //#define KEYPAD_HEIGHT 300 //#define GLOBALVALUE_X 550#define GLOBALVALUE_Y 60#define GLOBALVALUE_WIDTH 225#define GLOBALVALUE_HEIGHT 40 //variables needed://globals keypadGButtonObject keypadGlobalsButton[12];GHandle keypadGlobalsButtonHandle[12];GSourceHandle keypadGlobalsButtonSource[12];char* keypadGlobalsStrings[12] = {"1","2","3","4","5","6","7","8","9","BACK","0","CLR"};GListener keypadGlobalsCB;//the variable we're editingstatic uint32_t globalEditValue = 0;font_t fontLarger;void printGlobalVar(void){ char globalValueText[12]; chprintftostring(globalValueText, "%u", globalEditValue); gdispFillStringBox(GLOBALVALUE_X, GLOBALVALUE_Y, GLOBALVALUE_WIDTH, GLOBALVALUE_HEIGHT, globalValueText, fontLarger, Yellow, DarkGreen, justifyCenter); gdispDrawBox(GLOBALVALUE_X, GLOBALVALUE_Y, GLOBALVALUE_WIDTH, GLOBALVALUE_HEIGHT, Green);}//The shared button handlervoid keypadGlobalsButtonHandler(void *param, GEvent *pe){ GHandle pressed = ((GEventGWinButton *)pe)->button; uint8_t i = 0; for(i = 0; i < 12; i++){ if(pressed == keypadGlobalsButtonHandle[i]){ break; } } if(i == 9){//backspace .. divide by 10 globalEditValue /= 10; }else if(i == 11){//clear globalEditValue = 0; }else if(i < 9){//x = 1..9, y(n+1) = 10*y(n) + x globalEditValue = 10 * globalEditValue + i + 1; }else if(i == 10){//x = 0, y(n+1) = 10*y(n) globalEditValue *= 10; } printGlobalVar();}//alloc of the buttonsvoid createGlobalsKeypadButtons(void){ uint8_t x, y, i = 0; fontLarger = gdispOpenFont("Larger Double"); geventListenerInit(&keypadGlobalsCB); keypadGlobalsCB.callback = &keypadGlobalsButtonHandler; //draw keypad: 0..9, backsp, "." and assign button for(y = 0; y < 4; y++){ for(x = 0; x < 3; x++){ keypadGlobalsButtonHandle[i] = gwinCreateButton(&keypadGlobalsButton[i], KEYPAD_X + x * 75 + 3, KEYPAD_Y + y * 75 + 3, 70, 70, fontLarger, GBTN_NORMAL); gwinSetButtonText(keypadGlobalsButtonHandle[i], keypadGlobalsStrings[i], FALSE); keypadGlobalsButtonSource[i] = gwinGetButtonSource(keypadGlobalsButtonHandle[i]); geventAttachSource(&keypadGlobalsCB, keypadGlobalsButtonSource[i], 0);//attach listener gwinAttachButtonMouse(keypadGlobalsButtonHandle[i], 0); i++; } }}//buttons de-activationvoid disableGlobalsKeypad(void){ uint8_t i = 0; GButtonObject *gb; for(i = 0; i < 12; i++){ if(keypadGlobalsButtonHandle[i] != NULL){ gb = &keypadGlobalsButton[i]; gb->gwin.enabled = FALSE; } }}//buttons activationvoid enableGlobalsKeypad(uint8_t draw){ uint8_t i = 0; GButtonObject *gb; if(draw == TRUE){//start with a lightgrey square background gdispFillArea(KEYPAD_X, KEYPAD_Y, KEYPAD_WIDTH, KEYPAD_HEIGHT, LightGray); } for(i = 0; i < 12; i++){ if(keypadGlobalsButtonHandle[i] != NULL){ gb = &keypadGlobalsButton[i]; gb->gwin.enabled = TRUE; if(draw == TRUE){ gwinButtonDraw(keypadGlobalsButtonHandle[i]); } } }}In your init code call createGlobalsKeypadButtons(); followed by disableGlobalsKeypad();The buttons are allocated, listening and calling the callback but they're not drawn - disableGlobalsKeypad() disables them altogether without destroying them. When you're ready to draw them you clear the screen and call enableGlobalsKeypad(TRUE);BTW, everything is called xxxGlobalsxxx because I use this to edit and update global variables during runtime. If you have many buttons, don't forget to adjust GEVENT_MAX_SOURCE_LISTENERS.regards,Fred
Joel Bodenmann Posted February 24, 2014 Report Posted February 24, 2014 Glad to hear that it works. Do you actually write a dedicated widget for the keypad? It would be nice if you'd contribute it so we can include it into the official repository.~ Tectu
fred Posted February 24, 2014 Author Report Posted February 24, 2014 I'm thinking about that, I'm currently implementing a second keypad to edit the RTC time/date and it would be nice to be able to reuse the code. But it's proving difficult to cover these two examples with the same code. I think I'll implement them seperately and see how they can be brought together in a widget.
Joel Bodenmann Posted February 24, 2014 Report Posted February 24, 2014 What were the kinds of problems that you faced?~ Tectu
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now