I don’t have a lot of time to assist with things, but I’ll toss in some
ideas about how I’d setup widgetting system:
struct widget_skin {
Uint32 background;
Uint32 border[4];
uint32 foreground;
// Any other general widget stuff
};
// General purpose callback for events and other stuff
typedef int (*widgetCallback)( int type, void *widget, int param, void
*udata );
struct widget {
void *wClass; // Reference to some widget class - this allows an easy
cast!
// Tree-style widget referencing
widget *parent; // Widget parent
widget *nextSibling; // Next widget in list
widget *firstChild; // First widget in child list
// Connected widgets are widgets that aren’t directly connected via the
tree, but you still want to have them notified after an event
int nConnected; // Number of connected widgets
widget **connected; // Reference to connected widgets
widget_skin style;
};
Then, of course, you’d have to create a pile of classes for different
widgets. So, if we had a fictional “window” widget, creating it would look
something like
widget *container = sdl_ui_baseWidget( ); // Creates a “null” widget to be
used as a base
widget *firstWindow = sdl_ui_createWindow( container, “Window Title”,
sdl_ui_p2d( x, y ), sdl_ui_size( w, h ) )
widget_window *windowData = (widget_window *)firstWindow;
printf( “%s\r\n”, windowData->title );
Stuff like that is helpful. I don’t know, though. There’s would be a lot
to be implemented, and again, I don’t have a lot of time between work and my
own projects.
Take care,
-AlexOn Sun, Apr 24, 2011 at 10:51 AM, Nathaniel J Fries wrote:
Jared Maddox wrote:
No, this doesn’t really change things. The containers still
do message dispatching to their children, they just send
the location info as arguments to the function instead
of waiting for the children to ask for it.
And yes, there are still containers, because the only idea
that you drop is the idea that widgets can only have a
single parent. Parent/child relationships still exist, they
just aren’t tracked by the children.
Oh, I see. That would be fine, I guess. I still don’t see what it provides.
Quote:
Actually, I was thinking about using the same widget in
two different windows, so that you don’t have to do as
much message dispatching.
Example use: you have a painting-widget, and viewport
widgets to go along with it; each viewport represents a
different view of the image, and when a a change is made to
the image through one viewport it appears in the others as
well.
How would that work if widgets had no handle to their parent?
Also, why does a viewport need to be a widget? A viewport is a mere
rectangle.
However, that does provide me with an idea for a potential canvas widget!
Quote:
Per-widget (note: I don’t actually see much use for this
one, since you’d have to have a new one for every style),
per-style, what? With the minimalist interface you’ve
currently written I can’t see the skinner as being of much
use. Is it supposed to provide the visual element while the
widgets provide the behavior? Is it supposed to draw
’external aspects’ such as a window bar?
Per-widget (well, obviously, instances can be reused between multiple
widgets of the same time).
It provides the visual element, while the widget provides behavior.
The widget will draw stuff unique to its functionality (a text editing
region draws text and a cursor, a button draws it label, a frame draws its
caption, etc) between PreSkin and PostSkin.
PreSkin is for things like drawing backgrounds and outer borders, PostSkin
is for things like drawing inner borders (some of the fancier UI designs
have these) and any other sort of post-rendering visual effect.
Jared Maddox wrote:
Quote:
What is it good for? You could create a CSSSkinner class
that takes a string of CSS code in the constructor, and
provides the Skin(…) interface if you were making a
web browser. If your goal is to be portable but also
look extremely integrated with the system, you could do
that just by using a different texture on each system.
You’d have a SystemLikeSkinner() constructor taking an
"OS ID" or something and loading the appropriate
constructor, then the “Skin” function would do the magic.
‘Magic’ is nice and all, but you need to actually be able
to implement it. If skinners are actually supposed to
affect the way that things look, then you should start by
having them provide ‘components’ for widgets to use. For
example: edge bevels that can be used to indicate raised
or lowered areas. This would allow skinners to provide
styles, by way of one style using different bevels than
another style, including differently sized bevels.
Unless they actually changed the way that widgets function, this type of
thing would be contained to the Skinner class implementation.
That said, there is no reason why we can’t provide some simple skinner
implementations to the user. It merely isn’t a priority now.
Jared Maddox wrote:
Quote:
My more recent explorations of GUIs on SDL have tended to
go in a COM-reimplementation direction (for flexibility),
but I haven’t finished any of those, so simple is good [image: Wink] .
COM is not really desirable from an implementation standpoint.
How so? Too heavy? You’re already using reference counting,
the only reason I ever went further towards COM was that I
intended to allow external ‘widget servers’. Without
external widgets, this is about as COM-like as you have
reason for.[/quote]
I thought you meant… actual COM. Not a COM-like interface.
Yes, it is a bit heavy, but it also is already a bit COM-like.
Interfaces exist primarily for the user to extend functionality.
Reference counting exists to solve a dilemma I’ve run into using other,
non-reference-counting GUI libraries that try to do advanced things for a
"smoother" look. It’s my intention to allow the user to implement such a
thing themselves, if they wish. The solution that one specific GUI library I
was using had was to delete the widget when it was done being “smooth” with
it. But I still wanted the widget for something, and recreating it was a
PITA. Obviously the best solution was to hack the LGPL-licensed library I
was using in my proprietary project. Eh, no thanks. I did wind up just
creating it.
Jared Maddox wrote:
Quote:
Good. This is one of those widgets that takes forever to
implement.
But remember – assume as little as possible about how
the user wants to implement or use things. The user
might want syntax highlighting on this widget.
Like for coloring a keyword a different color than a
comment? Certainly (well, probably) not in the first
version, but maybe afterwards.
Yes. It’d be nice to do things like italics and bold and stuff, too.
I’m still thinking about the best way to do this.
Jarred Maddox wrote:
Quote:
The user might not want to use SDL_TTF for fonts, he
might have a totally B/A bitmap font or something. He
might even want to use system fonts. These are things
that the user should be able to do without much effort.
I’m not going to say that it’s without much effort, but
the last time I did this the class didn’t natively support
any character sets, you had to provide it with functions
for things like figuring out the byte length of a
character, and whether you could break at a certain point
(only relevant if you turn on word-wrap, but you need A
function regardless).
I’d just provide support for UTF-8, since SDL already does this.
Jarred Maddox wrote:
One more note: the containers should have another widget
that acts as a background. It’s ‘draw’ function should be
called after PreSkin, but before the for loop. This allows
arbitrary backgrounds, including of other container
widgets.
That is the purpose of PreSkin.
EM3 Nathaniel Fries, U.S. Navy
http://natefries.net/
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org