Skip to content

ofxButton: distinguish button from Toggle visually with circle vs square#8144

Merged
ofTheo merged 2 commits intoopenframeworks:masterfrom
artificiel:roundbutton
Oct 16, 2024
Merged

ofxButton: distinguish button from Toggle visually with circle vs square#8144
ofTheo merged 2 commits intoopenframeworks:masterfrom
artificiel:roundbutton

Conversation

@artificiel
Copy link
Copy Markdown
Contributor

It is a bit confusing that the visual representation of an ofxButton is the same as the ofxToggle, as it is not possible to pre-determine that the widget will behave differently without clicking it. Even once clicked, it looks like an active toggle so you only know if if it's going to "stick" or not upon release.

This changes the representation of the Button to a rounded rectangle, completely filled when clicked (much like buttons do, in most environments). it is close enough to the original square to not disturb the visual ambiance of a populated ofxPanel, but still conveys it's operational status clearly.

It does not affect usage or API, nor adds methods or memory requirements as it simply implement it's own generateDraw over the one inherited by ofxToggle, by copying the ofxToggle::generatedDraw integrally and changing a few draw calls -- no changes in code logic).

ex.mov

@roymacdonald
Copy link
Copy Markdown
Contributor

I agree. This seems like a good idea. Although I think it is a good idea to optimize its drawing by caching the geometries instead of having to generate each time. I can guess that this would be beneficial for low power systems such as a raspberrypi. And the button does not change its size, only where it gets drawn, so it is quite easy to generate once and then just draw.

@artificiel
Copy link
Copy Markdown
Contributor Author

i agree with the caching but this code is a simply copy-paste from the ofxToggle with 3 changes lines (the method is otherwise inherited as-is from ofxToggle) -- the principle you describe should be implemented within ofxToggle (and perhaps others, for instance the text region of all elements?). but that is a much deeper dive and seems risky/out-of-scope versus a simple tweak of what is currently in place?

@roymacdonald
Copy link
Copy Markdown
Contributor

i agree with the caching but this code is a simply copy-paste from the ofxToggle with 3 changes lines (the method is otherwise inherited as-is from ofxToggle) -
sure, but the difference is that for a square you draw 4 vertices while for a rounded rect or circle you end up drawing a lot more.

There is already caching for the text, and some of the geometries. I digged into it a while ago, so I can't tell from the top of my head. I can check how to optimize this

@artificiel
Copy link
Copy Markdown
Contributor Author

ah but i just verified and this generateDraw() is only called when the geometry or name changes (or whatever bumps needsRedraw). so maybe it is the caching you're thinking of.

void ofxBaseGui::draw(){
setEvents(ofEvents());
if(needsRedraw){
generateDraw();
needsRedraw = false;
}
currentFrame = ofGetFrameNum();
render();
}

@roymacdonald
Copy link
Copy Markdown
Contributor

I was actually recalling what goes on here which is used in ofxSlider but not in ofxToggle (which I guess it should, as it currently uses an ofPath). Drawing an ofPath is more expensive than drawing an ofMesh, as the ofPath will teselate, generate a mesh, and then draw. Drawing a circle is more expensive than drawing a square. But, maybe I am getting to picky.

@artificiel
Copy link
Copy Markdown
Contributor Author

tesselate() is called within draw(), but the tessellation is cached at the ofPath level (until bNeedsTessellation, and there is a similar check with bNeedsPolylinesGeneration):

void ofPath::tessellate(){
generatePolylinesFromCommands();
if(!bNeedsTessellation || polylines.empty() || std::all_of(polylines.begin(), polylines.end(), [](const ofPolyline & p) {return p.getVertices().empty();})) return;
if(bFill){
tessellator.tessellateToMesh( polylines, windingMode, cachedTessellation);
}
if(hasOutline() && windingMode!=OF_POLY_WINDING_ODD){
tessellator.tessellateToPolylines( polylines, windingMode, tessellatedContour);
}
bNeedsTessellation = false;
}

so unless the user drags ofxPanel around, the mesh is is not refreshed.

@ofTheo ofTheo merged commit 034204f into openframeworks:master Oct 16, 2024
@artificiel artificiel deleted the roundbutton branch November 6, 2024 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants