sincerely
Singaporean
If you have not done so, read this full tutorial on how to use SGEXTN to build an application.
See here for the previous part of the tutorial.
In the previous part, we wrote code to save user defined preset options for our application.
Next we will be implementing the UI page that allows users to select and use presets.
This will need a new UI page, so we will create a new class, SGCLPPresetsSelectionPage. By now you should already know how to do this.
As usual, we will declare these stuff
static SGWBackground* instance; static SGWBackground* initialise(); static void activate();
Remember to forward declare the SGWBackground class instead of including the header file. Also remember to add the source file into the CMakeLists.txt
For this page, we can have a scroll view filling almost the entire screen, leaving a bit of space for a cancel button at the bottom of the page. The buttons to select presets would be listed in order inside the scroll view.
Since we will need to add stuff into the scroll view, we will need to store a pointer to it also. We also need to declare a function for the cancel button that disables the UI page.
static SGWWidget* listBackground; static void cancelPresetSelection();
We then can implement SGCLPPresetsSelectionPage::initialise, SGCLPPresetsSelectionPage::activate, and SGCLPPresetsSelectionPage::cancelPresetSelection.
SGWBackground* SGCLPPresetsSelectionPage::initialise(){ SGWBackground* bg = new SGWPageBackground(SGWWidget::parentWidget, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); SGCLPPresetsSelectionPage::listBackground = new SGWScrollView(bg, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f); new SGWTextButton(bg, "cancel", &SGCLPPresetsSelectionPage::cancelPresetSelection, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f); return bg; } void SGCLPPresetsSelectionPage::activate(){ SGWBackground::enable(SGCLPPresetsSelectionPage::instance, &SGCLPPresetsSelectionPage::initialise, nullptr); } void SGCLPPresetsSelectionPage::cancelPresetSelection(){ SGWBackground::disable(SGCLPPresetsSelectionPage::instance); }
After that we can modify the code that creates the "use preset" button in SGCLPOptionsPage::initialise to make the button run SGCLPPresetsSelectionPage::activate. You should already know how to do this.
Note that currently the height of the scroll view is always a w-distance ⁽㈳㈴㈳㈮㈱㈨㈠㈫ ㈧㈤㈱㈤⁾ of (0.0, 0.0), which always resolves to 0 pixels. This will be dynamically determined when the buttons are actually placed into the scroll view.
Testing shows that the page appears when the "use preset" button is pressed, and when the "cancel" button inside the page is pressed, it disappears as expected.
Next we can actually add the buttons to choose a preset.
To do that, we simply look through the list of files in the folder and for every file, we make a button for it. We then resize the scroll view appropriately and put all the buttons inside.
When a button is clicked, it has to run a callback function ⁽㈳㈴㈳㈮㈱㈨㈠㈫ ㈧㈤㈱㈤⁾ that sets the presets to whatever stored in the file. This means we need the path to the file.
This can be done by storing the path in SGWButton::attachedString, which is automatically passed to SGWButton::clickFunctionWithString when the button is clicked.
We can define the function
static void useSavedPreset(const SGXString& filePath);
Then we modify the implementation of SGCLPPresetsSelectionPage::initialise and write the implementation of SGCLPPresetsSelectionPage::useSavedPreset as below.
SGWBackground* SGCLPPresetsSelectionPage::initialise(){ SGWBackground* bg = new SGWPageBackground(SGWWidget::parentWidget, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); SGWScrollView* scrollView = new SGWScrollView(bg, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f); SGCLPPresetsSelectionPage::listBackground = scrollView; new SGWTextButton(bg, "cancel", &SGCLPPresetsSelectionPage::cancelPresetSelection, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f); SGLArray<SGXString> filesList = SGXFileSystem::getFilesListWithExtension(SGXFileSystem::userDataFilePath, "sg"); (*scrollView).setI0(static_cast<float>(filesList.length())); for(int i=0; i<filesList.length(); i++){ SGWButton* button = new SGWTextButton(scrollView, SGXFileSystem::getFileNameNoExtension(filesList.at(i)), nullptr, 0.0f, 0.0f, 0.0f, static_cast<float>(i), 1.0f, 0.0f, 0.0f, 1.0f); (*button).attachedString = filesList.at(i); (*button).clickFunctionWithString = &SGCLPPresetsSelectionPage::useSavedPreset; } return bg; } void SGCLPPresetsSelectionPage::useSavedPreset(const SGXString &filePath){ SGXFile file(filePath, SGXFile::ReadOnly); SGCLPOptionsPage::chosenForegroundColour = file.readColourRGBA(); SGCLPOptionsPage::chosenBackgroundColour = file.readColourRGBA(); int patternIndex = file.readInt(); if(patternIndex == 1){SGCLPOptionsPage::chosenPattern = SGCLPOptionsPage::Circle;} else if(patternIndex == 2){SGCLPOptionsPage::chosenPattern = SGCLPOptionsPage::Polygon;} else if(patternIndex == 3){SGCLPOptionsPage::chosenPattern = SGCLPOptionsPage::Star;} else{SGCLPOptionsPage::chosenPattern = SGCLPOptionsPage::Fractal;} SGCLPOptionsPage::chosenVertexCount = file.readInt(); SGWBackground::disable(SGCLPPresetsSelectionPage::instance); SGWBackground::disable(SGCLPOptionsPage::instance); SGCLPDisplayPage::activate(); }
Since we have not actually really built the display page yet, it is impossible to confirm if this actually works. However we do observe that when a preset is selected, both the preset selection page and the options page turn off, while the display page turns on. This is expected behaviour, so we will assume everything is good for now.
With another major feature completed, we can perform a clang-tidy scan and commit the changes to GitHub. By now you should know how to do this.
See here for the next part of the tutorial.
©2025 05524F.sg (Singapore)