All calls to this method are in GMenu2X::initMenu() and they will only
pass valid indices, so the range check was redundant. Also the return
value was never used.
Added an assert to spot any invalid indices from future code.
There are a few exclusive operations for each type. Also we no longer
need the freeWhenDone flag since the class now determines whether the
surface should be freed or not.
In theory a font could be so large that no full row would fit on the
allotted space; in that case showing a partial row is better than
nothing and will avoid bugs where -1 wraps around on unsigned exprs.
Nebuleon spotted a bug in TextManualDialog where the unsigned value
'pages[page].text.size() - rowsPerPage' could wrap around at 0 for
short chapters. I decided to change a bit more than just fixing the
bug though.
This is the convention that most classes stick to. The likely reason
why Dialog didn't stick to the convention was to be able to provide
a default value for this argument, but that feature wasn't very useful
since every caller already had access to the default surface.
Applications with this flag will not have their stdout/stderr
redirected to a log file when logging is enabled. That is a useful
feature also on platforms where we don't micromanage the console.
Currently the launched application is exec-ed from deep within the menu
code. This means a lot of destructors are never run and as a result
for example file descriptors from the menu remain open in the launched
process.
This is a first step to move the launch invocation from a deep call
stack to the top level.
If a text file ends in a newline, the previous line splitting code
would append an empty line at the end, which looked odd. So now we
explicitly check that a newline is only inserted if more characters
follow.
Setting values are now displayed 10 pixels to the right of setting names, as
passed to MenuSetting::draw.
This commit also contains the following cleanups:
* The height of a row is passed to MenuSetting's draw and touchscreen methods.
* MenuSettingRGBA's magic constant (36) to separate the text for a color's
four components is now a named constant.
* MenuSettingRGBA's color preview squares are now rowHeight - 2 pixels tall,
and have a white border surrounded by a black border to help view the color
it contains in both light and dark themes.
* The rectangle behind the selected setting's name is now drawn by that
setting's drawSelected method.
Setting descriptions and help prompts now appear fully even if they are longer
than the screen allows. Translations do not need to worry about allowed text
being wider than the screen in some fonts anymore.
Instead of reading the file line by line and then concatenating those
lines, just load the entire thing in one go. And pay more attention to
error conditions.
The constructors of those classes now accept a string to be wrapped, instead
of a vector to be modified with split lines inserted into its middle.
Along with this conversion, manuals for applications stored in OPK packages
are now transferred into a string without garbage at the end.
This implementation is based on the implementation in TextDialog::preProcess,
with one major difference: it works on the entire input string, copies it much
less as part of its function, and tries to quickly establish a small search
space for the length of the beginning split of each line.
With most standard fonts and sizes, this means up to 9 computations of metrics
per output line.
Multi-line message boxes had the incorrect height.
I also took the opportunity to make named constants out of magic numbers
making up the various message box dimensions.
This reverts commit 0908aa7bb7.
It turns out there are multi-line text messages in use: Nebuleon found
one in the confirmation message when deleting a section.
In commit 950518f3 I changed the component type of RGBAColor from
16-bit to 8-bit integers. Unfortunately, in C++ 8-bit integers are
identical to characters, so this broke the writing of colors to
output streams.
This affects manuals, About GMenu2X, and the Log Viewer.
Instead of trying to compute the width of the entire string, then backing
off one word at a time, TextDialog::preProcess now performs a binary search
on Font::getTextWidth(string) and backs off to the last fitting space, if
there is one, at the last moment.
In Japanese and Chinese text, words are not usually separated by spaces.
Text in these languages is now wrapped when it would reach the edge of the
screen.
I implemented it as four 1-pixel-wide filled rectangles. While this
is not the fastest way to do it, I doubt this will have a significant
impact on overall performance.
Note that the proper way to clip a rectangle outline is to clip the
outline's four lines individually, not clip the rectangle and then
draw a smaller rectangle outline. This means that an optimized drawing
routine would have to be aware of whether clipping occurs, complicating
the code.
I want to remove the dependency on SDL_gfx, since only two functions
from that library are actually used. Also this new blend implementation
is more optimized, especially the 32bpp case, which is the one most
platforms are using.
This is the opposite of the old situation, when the structs were
unraveled.
The definitions for the alternative styles were moved to the header,
so the compiler has more opportunities for optimizing the conversions.
This allows for faster scrolling between section links, in file and directory
selectors, and in manuals, without repeatedly pressing buttons.
The setting's unit is repetitions per second. Its default value is set to
10, and anything between 0 (disabled) and 20 (50 ms) is acceptable.
Grabbing &(instance of GMenu2X).confInt["buttonRepeatRate"] is unsafe, because
the storage for the slot may move as the slot is deleted or added. Instead, a
callback jumps back into the context of an InputManager so the value can be
read from a GMenu2X object's configuration.
A GMenu2X object is also passed to InputManager::init.
Previously, one would check the value in &confInt["someKey"] by passing a
reference to it to evalIntConf. However, because this passing of the reference
went through std::unordered_map::operator[], it created a slot with the named
key and initialised its value with the default constructor of int, which
placed 0 there, if it didn't exist. If the value of 0 was acceptable for the
setting, then 0 as the value selected by the user was indistinguishable from
a slot that had been just created and had to be set to its default.
Now, the std::unordered_map is passed along with the key so that evalIntConf
can check whether the key exists and, if it doesn't exist, set the value to
its default.
Include utilities.h in gmenu2x.h instead of the reverse. One type definition
used by utilities.cpp is moved there (ConfIntHash) and for consistency
ConfStrHash is moved there as well.
When trying to test the previous commit, I couldn't find any place in
the application where strings containing newlines are drawn. So I'm
assuming this is an unnecessary feature, until someone comes up with
a test case proving otherwise.
Yeah, I'm too lazy to review all the code that draws text...
Instead of splitting everything at once, split off one line at a time.
The code could be more compact but I want to avoid using substr on the
very common special case when a string contains no newlines.
Asking FreeType for metrics before asking it for a render, when rendering
would compute the metrics anyway, is wasteful. Now the width of text, for
horizontal alignment purposes, is simply the width of the render.
In well-described fonts, this enables multi-line text (e.g. in manuals) to be
more readable.
The term "height" is also replaced with "line spacing" in Font's code.
This does away with per-link selector directories in link files. It is assumed
that, if a user has access to write files to be launched by an application at
some location, he or she also has access to write files in the previews/
subdirectory under it.
The alpha change is so that:
* some of the background is still visible, which includes the name of the
application for which the selector is being called, its description, and
text in the status bar;
* the preview, if bright, does not obscure the file names too much.
Selector previews are now shown full-screen (320x240) instead of being a
160x160px square on the right.
These issues are fixed:
* loadPNG gave RGBA surfaces unconditionally. Now it gives RGB surfaces if
its second parameter, defaulting to true, is false. This fixes adding per-
surface alpha values, because an RGBA surface ignores its per-surface value.
* Surface::loadImage is updated to receive a third parameter, defaulting to
true, to determine whether alpha is loaded.
* SurfaceCollection::defaultAlpha was never used.
* SurfaceCollection::defaultAlpha defaulted to false, so even if it were used,
it would have loaded images without alpha.
This commit ensures that a fully constructed Font object will not crash
gmenu2x when it is used, even if loading the font or initialising SDL_ttf
altogether has failed. Instead, it will render no text, but icons and
images are still drawn.
The proper way to signal an error would be to throw an exception and fail
to construct the Font object. However, gmenu2x does not use exceptions.
Since 2002-09-03, SDL_ttf performs reference counting on TTF_Init and
TTF_Quit. If two fonts were loaded concurrently via the Font class and
one was destructed, the destructor of the first object would call TTF_Quit,
making the second object unusable. The constructor now calls TTF_Init
unconditionally to prevent this situation.
The reference counting behavior was introduced in this SDL_ttf commit:
http://hg.libsdl.org/SDL_ttf/rev/fc0371908009
This breaks one thing: the "params" option of the links must be
only one parameter (without spaces). The only way to actually
set this option being to edit the config files manually, it is
pretty safe to assume it will never contain two parameters.
The comment of this code indicates that it is needed for
SDL apps to work correctly.
However, I don't see any valid reason for the apps we
launch to be running in a different group.
Removing it didn't make any apparent difference, so unless
I'm proven wrong, it'll stay gone from now on.