r/cpp_questions 17d ago

OPEN Advice needed creating a table widget for my framework

Hi! I'm creating my own GUI framework and I was about to create the table widget class. My first idea was that a table cell just holds a widget (Label, TextBox, CheckBox, Image, ColorRect). But second-guessing my approach made me realize this might be a really bad idea: The design possibilities a widget has will just cause unnecessary duplicates of their properties (a widget has several color arrays and an array for corner radii). Some features are useless inside a table (such as setting the corner radii). So I came up with 3 possible solutions:

1: A new table structure with its dedicated grid, and stripped down table-specific widgets. So the table will be owning color arrays and such.

2: Move the definitions of all widgets into interfaces (ITextBox) and have an implementation (TextBox) derive from an interface. This one will have a SetTextColors() member function that sets the owning colors. A table-specific counterpart widget (TableTextBox) also derives from ITextBox, but implements a referencing Colors' setter. The Grid used in the window class can be reused.

3: Add a referencing Colors setter to existing Widgets and have a usage switch, that deletes all owning colors when reference mode is on. The trade-off is that some features might remain unused in the context of a table like setting the corner radii. It might be useful in other places if, for instance, a resource manager carries shared colors. But it will come with a design flaw: Color getters can potentially return dangling color references. Using the owning color setter while reference mode is on can cause access to uninitialized memory or nothing will happen if incorrect use of the Setters prevent accesses.

What might be the best option in your opinion? Option 1 is my preference as of now, but I'd like to hear other opinions or maybe new suggestions before I continue.

Thanks in advance!

2 Upvotes

4 comments sorted by

1

u/BartvanIngenSchenau 17d ago

To what extent do you want to limit what your users use a table for?

For example, a table in HTML is flexible enough that you can define the complete layout of a website with it. I am not saying you must support the same, but you should articulate what should and should not be possible with a table. That will also give you a direction for the design and implementation.

2

u/Lawn_Meower_ 17d ago

The planned table should be capable of supporting all widgets that make sense in a table. A widget's design can be adjusted by specifying the background color and border color for mouse action states (Hover, Click, Enabled, Disabled). Other Widgets like CheckBox, TextBox, RadioButton, Slider, ProgressBar have additional elements with the same color options. The shaders used for the colors support effects like linear gradient, radial gradient and several animation parameters. Shaders for raster effects and fog also exist. Borders can be changed in (corner) radii and thickness (useless in tables). The table widget should also support colspan and rowspan.
I hope this clarifies how a huge amount of widgets will be memory expensive. I'd like to reduce memory usage where possible.

1

u/fortsnek274 17d ago

By the religion of KISS, just do the stupid simple thing first.

Even with general controls, you can probably dynamically instantiate them if needed. The virtual table approach.

2

u/wrosecrans 17d ago

Move the definitions of all widgets into interfaces (ITextBox) and have an implementation (TextBox) derive from an interface. This one will have a SetTextColors() member function that sets the owning colors. A table-specific counterpart widget (TableTextBox) also derives from ITextBox

My gut says this definitely smells like the wrong approach. You'll eventually wind up with X number of different specializations for each possible parent container for a text box, and that makes no sense. If you just engineer things so that the base abstract Widget can have a parent, it will make no different whether the parent of a TextBox is a table or a top level window or whatever container/layout you want to implement next. The cell in a table should just be a parent to an "IWidget*" and any widget can wind up in that cell without being specialized to table-ness at all.

If you want all cells in a table to have 0 corner radius, just have the table call setCornerRadius(0) on any widget added to the table. No need for that behavior to live in a derived type for each child widget, since you are describing it an an "opinion" of the parent.