Closed davexre closed 1 month ago
Edit to note - it's really GEM_adafruit_gfx.cpp that needs to change, in my case... And to note that sprite width is fixed at 8 pixels, looks like - at least, when we draw the Sprite for an item line, it starts drawing at _agfx.width() - 8
, rather than something like _agfx.width - arrow.Right[1].width
. This also means that scaled sprites always display at 8px wide, here, too (even though the scaled versions are 16px wide).
(my workaround here will just be to make my substitute sprite 8 pixels wide... simple enough!)
In Adafruit GFX version of GEM there is a method to scale text and icons by scale factor menu.setTextSize(2);
. Icons can be scaled up to 2x times only though. What scale factor of 2 does is essentially treats each group of 2x2 pixels as one virtual pixel for text, while graphic bitmaps are displayed properly with 1 to 1 pixel ratio. There are enlarged 12x16 version of icons present in GEM_adafruit_gfx.cpp.
It mostly designed to work with default font, but it appearance may seem blocky (due to 2x pixel ratio). But consider trying this method, may be it will be sufficient for your needs?
If not, there are indeed no method to change icons without editing source code. However, since scaled bitmaps are already present in code (see link above), it should is possible to reuse them with relatively minor adjustments. Try changing this line from byte variant = _textSize > 1 ? 1 : 0;
to byte variant = 1;
. That way enlarged versions of icons will be drawn regardless of scale factor set via menu.setTextSize()
method (and it will be possible to use custom font for menu items w/o scaling this font itself).
I'll give it a go, setting variant manually. I did try setting textSize higher - but it does indeed get super blocky once it's big enough for the display. If I have to swap some sprites, it's not the worst thing in the world - I just have to be careful later, if I update the library (I'll make a patch file and just re-apply it later, if that's the case).
Sometimes have to remind it to myself, that now there is a way to modify (or extend) GEM functionality without the need to edit source code files! For that you will have to activate Advanced Mode, as described here and here. Then it will be possible to override inner methods of GEM.
In case of setting variant
variable value manually it will look something like this:
class GEMProxy : public GEM_adafruit_gfx {
public:
using GEM_adafruit_gfx::GEM_adafruit_gfx;
void drawSprite(int16_t x, int16_t y, const Splash sprite[], uint16_t color) override {
byte variant = 1;
_agfx.drawBitmap(x, y, sprite[variant].image, sprite[variant].width, sprite[variant].height, color);
}
};
GEMProxy menu(tft, GEM_POINTER_ROW, GEM_ITEMS_COUNT_AUTO);
(Haven't tried this code myself - let me know if it will work for you).
A minor change makes it functional - drawSprite
should return void.
That does draw the sprites at a much better size, yeah. It still has the same problem I mentioned before, where the sprites on the right side are not drawn wide enough, because they're drawn too far to the right. For example, when we draw the Right Arrow for GEM_ITEM_LINK
, the sprint starts 8 pixels from the right edge of the screenm regardless of sprite width (https://github.com/Spirik/GEM/blob/8beda181e0d70099a7f5438579b15961287012a7/src/GEM_adafruit_gfx.cpp#L511).
I can't just override _textSize
to multiple that fixed 8
by 2, because that messes w/ the font and various other things.
I looked at overriding printMenuItem
, which is marked as GEM_VIRTUAL
, but looks like it accesses some protected fields in GEMItem, and would require modification of GEMItem.cpp to add my override object as a friend class there, too. It's missing a few things (the sprites) defined in GEM_adafruit_gfx.cpp, but those could be copied over pretty easily.
The last approach I can try there is to modify the drawSprite
override to look at the sprite that's being drawn, and try to guess where it's suppose to start on the X axis, and modify appropriately? ie, if it's rightArrow, make sure it starts 16 pixels inside the edge of the screen, instead of 8?
Really, I think I'm back at modifying GEM_adafruit_gfx.cpp
, at least for now. If I were to make a feature suggestion out of this, it would maybe be to make it easier to force sprite sizes to match font size, when using a larger font without changing setTextSize()
?
I think I got it. I've implemented property _spriteSize
in addition to _textSize
with corresponding method ::setSpriteSize()
. That allows to set sprite magnification level (up to 2x) independently of text.
By default, calling menu.setTextSize(2)
will set both _textSize
and _spriteSize
to 2 (the same result as in current public version of GEM). To set only _spriteSize
call menu.setSpriteSize(2)
.
This version is not yet published, however here is PR #102 (and separate branch with updated code). Please, consider checking it out, if you'll get a chance.
That looks like it'll work, yeah. I'll give that a shot in just a bit!
Seems to work perfectly. Thanks, @Spirik !
Glad to hear! I will create public release tomorrow.
Switched to 1.5.4 - working perfectly! Thanks again for the help!
Awesome! Closing issue.
Just making sure I'm not missing something - the sprites for things like
leftArrow
,rightArrow
, andselectArrows
are fixed at 6x8 pixels?My C++ is a little rusty - but I'm thinking that since the sprites are defined as constants, outside of the GEM class (I think they have to be that way, because they have to be
PROGMEM
?), the only way I can replace them is by editing GEM.cpp (and then not upgrading GEM - or reapplying the changes when I upgrade)? ThePROGMEM
requirement means they can't be replaced on the fly, either.I'm using a font that's 14x24 pixels (Adafruit GFX FreeMono12pt7b) - the existing sprites are really small on the screen, so I'd like to replace them with a bigger version of the same sprite.