Previously, IconButton instances to be added to button boxes were
allocated with new, but never freed with delete.
unique_ptr makes sure the buttons will be freed along with the button
box that owns them, or when code calls ButtonBox::clear.
The destructor of ButtonBox has been made redundant by this change, so
it's gone.
Put the drawButton calls left-to-right.
Avoid duplicate code.
The order was changed: "Select" is now always first, to be consistent
with other dialogs.
Instead of correcting the returned coordinate with "- 10" externally,
omit the white space inside the methods.
Note that Font::getTextWidth, which was used until recently, considers
an empty string to have width 1, so 3 + getTextWidth("") + 6 == 10.
There is a difference in how buttons that have neither a label nor an
icon are positioned in the new code, but that is a situation that
should not occur in practice. Plus I'd argue that the new behavior is
actually better in that case.
This was only called form ButtonBox, so I moved the code there.
I still think a paint method shouldn't be repositioning widgets, but
that's something for a later cleanup.
Use emplace_back when a new string is put into a vector.
Removed unused variables.
When searching section names, compare C++ string to C string, so we
don't need to construct a C++ string for the second string just for
the search.
When comparing full strings, operator== will do nicely.
When comparing the first char, "s[0] == c" is more efficient if we know
the string cannot be empty.
Since this surface is created by initBG instead of loaded from skin
search paths, it didn't really fit in SurfaceCollection. After removing
it, one of SurfaceCollection's methods could be removed as well.
This avoids having to do separate getTextWidth calls in several places.
More getTextWidth calls could be saved by splitting the rendering of
the font to an off-screen buffer from the final composition onto the
destination surface: the routines that draw text inside a box have to
compute the width before they can draw the box and currently the box
has to be drawn before the text.
Instead, make the caller perform the lookup. This simplifies the
interface of loadImage and it removes the dependency from
OffscreenSurface on SurfaceCollection.
In theory the timer could expire between the button press that starts
the application launch and the moment the PowerSaver destructor runs.
And I think this does in fact happen occasionally thanks to the CPU
hogging SD controller driver on the GCW Zero, leading to an application
launching with a blanked screen.
The instance-on-demand didn't really work, since we needed explicit
control over this object's destruction to ensure the timer is stopped
when launching an application. And trying to combine getInstance() with
explicit external delete was just ugly.
Use nullptr instead of NULL, evaluate pointer as bool where possible.
Declare the timer callback as a friend function so the methods it uses
can stay private.
Initialize screenState to false; was uninitialized which means that
an initially blanked screen might not be unblanked.
Force screen enable in constructor instead of when timeout is set.
Add removeScreenTimer method.
Include C++-ified versions of the C headers.
This is a BSD extension also present in glibc and uClibc. Not all libc
implementations and not all file systems support it, so we keep the
stat-based code as a fallback.
In the STL, 'at' will perform range checking while operator[] will not.
Since GMenu2X doesn't use exceptions, range checking is not possible,
so 'at' and operator[] were identical.
Previously, if a user installed a new version of an OPK with the same
name as one that had a link configuration file, GMenu2X could request
a file for an application whose new version required no files to
launch.
In practice, this transition would occur only once per OPK application,
when its developer decided to use a custom browser after having used
GMenu2X's file browser. This bug would then show GMenu2X's file browser
to request a file that would not even be passed to the application.
Thanks to Nebuleon for analyzing the problem and the above description.
Browsing the user's wallpaper directory will simply add no new files
to the list of wallpapers available if the directory doesn't exist.
WallpaperDialog::exec doesn't need to care about that.
Because wallpapers are files, not directories, also don't return
directories in the result. The code that makes the wallpapers list
calls FileLister::getFiles and ignores directories anyway.
Browsing the user's translations directory will simply add no new files
to the list of translations available if the directory doesn't exist.
GMenu2X::showSettings() doesn't need to care about that.
Because translations are files, not directories, also don't return
directories in the result. The code that makes the translations list
calls FileLister::getFiles and ignores directories anyway.
A file existence check is already performed, atomically with respect to
the filesystem, by ifstream's constructor. The result of this check is
available using ifstream::is_open().
0 is the default clock value, which doesn't get written to link files
if it's not changed. The clock was previously uninitialised before
reading link files, so it would get written with a random value if
there was none before.
When scanning multiple directories in succession, it's possible that
in some of them no matches are found. Avoid moving all pre-existing
entries back and forth in that case.
Also use move instead of copy for transferring the pre-existing
entries from the vector to the set.
The special case is not necessary for correctness. It would help
performance in theory, but it seems very unlikely that any code would
request a directory scan when it interested in neither the subdirs nor
the files in that directory.
Instead of splitting the filter for every file in FileLister::browse,
the filter is split immediately in FileLister::setFilter, improving
performance.
getFilter is removed because it was unused. This also removes the need
to update the return type to 'const std::vector&' in the method and
rewrite its callers.
Configuration of the FileLister is now left to the subclasses of
BrowseDialog, as the construction of a FileLister and its configuration
(to show or hide directories and files) have been separated.
This allows deleting the destructors of BrowseDialog's subclasses,
which existed solely to delete a FileLister object constructed by
each subclass.
The allocation of a BrowseDialog now also implies allocating enough
space for its FileLister, so remove the check for fl being nullptr in
BrowseDialog::exec().
The constructor now has zero arguments. showDirectories and showFiles
are now set using setter methods.
FileLister::browse is now the sole way to start a scan for files and
directories, replacing the initial path in the constructor and the
setPath method. It allows merging results from multiple directories
as before.
This is all to make explicit how many times the costly task of browsing
a directory is actually carried out.
Instead of showing 'R:', 'G:', 'B:' and 'A:', which take up a lot of space
and can overlap in standard fonts, the selection rectangle surrounding the
number is red, green, blue or gray, and the text is shorter.
This will allow the labels for the skin colors to be longer for translations
as well, given that their values are shown less wide.
Instead of checking which input configuration file exists among 2
choices, then asking InputManager to load that file, InputManager
itself now performs the resolution based on whether ifstream::is_open
returns true for each choice.
The existence of modifications to the skin configuration in the home
directory is now checked with ifstream::is_open, and the system's skin
configuration is used if that returns false.
A file existence check is already performed, atomically with respect to
the filesystem, by ifstream's constructor. The result of this check is
available using ifstream::is_open().
This operation is not so slow that it really needs caching. Also
reducing the delay before showing a directory will have more impact
on the user experience than a slightly faster paint.