ImpulseAdventure / GUIslice

GUIslice drag & drop embedded GUI in C for touchscreen TFT on Arduino, Raspberry Pi, ARM, ESP8266 / ESP32 / M5stack using Adafruit-GFX / TFT_eSPI / UTFT / SDL
https://www.impulseadventure.com/elec/guislice-gui.html
MIT License
1.12k stars 204 forks source link

Creating Element Alias for Toggle Button - Compile Error #511

Open ee-boi opened 1 year ago

ee-boi commented 1 year ago

Describe the bug

I am trying to add an element alias to reuse a toggle button from one page to another. I followed the tips & tricks page instructions here, and the alias line I entered in the GUIslice.h include file is:

gslc_ElemAdd(&m_gui, E_PG_RUN2, gslc_GetElemFromRef(&m_gui, m_pElemToggle1), GSLC_ELEMREF_DEFAULT);

but I am getting the below error while compiling.

Device hardware

Expected behavior

Should compile fine? Not sure why it is complaining about an int conversion.

Initialization messages

In file included from include/GUISLICE_REV2_GSLC.h:18,
                 from src/main.cpp:15:
include/GUISLICE_REV2_GSLC.h: In function 'void InitGUIslice_gen()':
.pio/libdeps/adafruit_metro_m0/GUIslice/src/GUIslice.h:453:53: error: invalid conversion from 'int' to 'gslc_teElemRefFlags' [-fpermissive]
  453 | #define GSLC_ELEMREF_DEFAULT  (GSLC_ELEMREF_SRC_RAM | GSLC_ELEMREF_VISIBLE)
      |                               ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
      |                                                     |
      |                                                     int
include/GUISLICE_REV2_GSLC.h:663:80: note: in expansion of macro 'GSLC_ELEMREF_DEFAULT'
  663 |   gslc_ElemAdd(&m_gui, E_PG_RUN2, gslc_GetElemFromRef(&m_gui, m_pElemToggle1), GSLC_ELEMREF_DEFAULT);
      |                                                                                ^~~~~~~~~~~~~~~~~~~~
In file included from include/GUISLICE_REV2_GSLC.h:18,
                 from src/main.cpp:15:
.pio/libdeps/adafruit_metro_m0/GUIslice/src/GUIslice.h:3471:102: note:   initializing argument 4 of 'gslc_tsElemRef* gslc_ElemAdd(gslc_tsGui*, int16_t, gslc_tsElem*, gslc_teElemRefFlags)'
 3471 | gslc_tsElemRef* gslc_ElemAdd(gslc_tsGui* pGui,int16_t nPageId,gslc_tsElem* pElem,gslc_teElemRefFlags eFlags);
      |                                                                                  ~~~~~~~~~~~~~~~~~~~~^~~~~~
src/main.cpp: In function 'bool CbCheckbox(void*, void*, int16_t, bool)':

Additional info

All help is appreciated, hopefully I am not taking advantage of your good will @Pconti31. I also have a few more issues/questions but I figured I will go one at a time for now.

Pconti31 commented 1 year ago

@ee-boi GUIslice was written quite a long time ago in computer language age. As time passes the people who modify languages like C, C++, Java etc... are on a never ending quest to make the compilers better but also harder and harder to use...

I think in this case it wants you to acknowledge that the GUIslice's

typedef enum gslc_teTxtFlags

is not an int but a enum which of course it a lie since it is in fact under the covers an int. A good thing all of hard work put into C compiler support isn't going to waste...

I suggest bowing to the Compiler gods and tell them you want a enum gslc_teTxtFlags like so:

gslc_ElemAdd(&m_gui, E_PG_RUN2, gslc_GetElemFromRef(&m_gui, m_pElemToggle1), 
(gslc_teTxtFlags)(GSLC_ELEMREF_SRC_RAM | GSLC_ELEMREF_VISIBLE));

If it works post so other people can benefit. Paul--

ee-boi commented 1 year ago

@Pconti31 your wisdom knows no bounds! I have bowed to the (sometimes) merciful compiler gods and seem to have found a solution, albeit a slight alteration to what you posted:

gslc_ElemAdd(&m_gui, E_PG_SETUP2, gslc_GetElemFromRef(&m_gui, m_pElemRunPrgm_Toggle_RPG1), 
    (gslc_teElemRefFlags)(GSLC_ELEMREF_SRC_RAM | GSLC_ELEMREF_VISIBLE));

swapping out gslc_teTxtFlags for gslc_teElemRefFlags compiles fine and as tested does put a working alias of (in my case a toggle button) on secondary page. For folks at home following along:

  1. to make an alias add gslc_ElemAdd(&m_gui, **PAGE_ENUM_HERE**, gslc_GetElemFromRef(&m_gui, **m_pElemREFERENCE_HERE**), (gslc_teElemRefFlags)(GSLC_ELEMREF_SRC_RAM | GSLC_ELEMREF_VISIBLE)); in the /include/YOUR_GSLC.h file
  2. update number of elements for the page by 1 for each alias in the /include/YOUR_GSLC.h file

Closing this out. Once again @Pconti31 appreciate your time, wisdom and help.

ee-boi commented 1 year ago

Well I may have closed this prematurely. It works...with some caveats....

Two issues I have noticed using the aliases (at least in this way)

  1. A call to gslc_ElemSetTxtStr() does not update an aliased text field until the page is reloaded/refreshed (i.e. update the text string for non-aliased text field, nothing happens, switch to another page, then switch back and the alias is updated)
  2. A call to gslc_ElemSetCol() does not update an aliased box with a new color (even if the page is changed back and forth forcing a refresh)

I am thinking these two issues are related? And also could be by design?

Let me know if more information needs to be shared.

Pconti31 commented 1 year ago

@ee-boi The guislice api is more of Calvin's area (I'm the Builder implementor).

If you read over my comments from the
issue 225 that caused alias Tip to be created you would have noticed I tried to convince the issue creator not to use aliases. It just seems like bad UI design to me.

Ignoring that lets assume you just make a call to gslc_ElemSetTxtStr() and its the alias, assuming you then reach gslc_Update() that current page is not updated with the new text? yes? that is odd...

In that case I would first try to add this call right after doing the gslc_ElemeSetTxtStr() this will invalidate the current page and cause it fields to be update. Although that should have happened anyways.

        gslc_InvalidateRgnPage(m_pGui,&m_asPage[gslc_GetPageCur(m_pGui)]);

If that doesn't work try the page the alias is sitting on (lets say for example it the Main page) and use its ENUM in the call :

 gslc_InvalidateRgnPage(m_pGui,E_PAGE_MAIN);

As for color changes the only issue I 'm aware of is if the element you are trying to change was defined using a _P call like gslc_ElemSetTxtStr_P() since that would mean its all stored in flash and can't be modified at runtime or you are using the wrong elementref.

If none of this works I'm afraid that at last you have exhausted my knowledge of guislice and will need to either abandon aliases or wait for Calvin's @ImpulseAdventure support.

Paul--

ee-boi commented 1 year ago

@Pconti31 hmm neither seemed to work. The second example, as it was placed in my main.cpp file, didn't even seem to recognize the E_PG_MAIN (obviously I used the enum I created, of course). Also none of the elements I am trying to alias, and subsequently update, are in Flash.

Thought I could get away with further reducing RAM usage and # of calls to more than one element update function. Oh well, I won't waste anymore time on it for now, the toggle button works fine and that is good enough for me for now. Text string updates and color changes do not work until the page is manually refreshed (i.e. switching pages back and forth).

I do hope Calvin can take a look at it someday, I personally think having aliases could be useful.

Pconti31 commented 1 year ago

@ee-boi Once again I am willing to investigate further only if you create a sample project say, with two pages, and at least a button on the main page that jumps to page 2, a text field on main the you alias to a text field on page 2. another button on main that has code that changes the text and color of your alias field and a button on page 2 that goes back to main . Assuming that fails post a zip of entire sample project folder.

Even if I can't figure out a work-around it will give Calvin something to look at when he gets a chance. Paul--