[Ohrrpgce] Slice based menus
James Paige
Bob at HamsterRepublic.com
Mon Feb 20 07:59:47 PST 2012
I have been reading this whole thread, and I have to admit, I am totally
confused. I am not sure at all what you are working on. Would you mind
explaining this project to me?
---
James
On Mon, Feb 20, 2012 at 06:19:37AM -0800, Jay Tennant wrote:
> > From: Ralph Versteegen <teeemcee at gmail.com>
> > Sent: Sunday, February 19, 2012 8:40 AM
> >
> > On 20 February 2012 03:21, Jay Tennant <hierandel8 at crazyleafgames.com> wrote:
> > > There's more further down, but separately, is there an equivalent
> > > high performance counter that is non-OS specific? Right now, the
> > > GUI framework uses Window's performance counter via
> > > QueryPerformanceCounter(), though that call is abstracted away
> > > in a virtual override to hide the OS dependency from the rest
> > > of the program. I suppose we could write a simple set of compiler
> > > directives to use the appropriate functions. I could alternatively
> > > just submit the code with the dependency, and let you decide what
> > > to do.
> >
> > In FB, TIMER should be used, as it already abstracts that. Otherwise,
> > we could put OS specific code in our OS specific modules.
>
> Can I call TIMER from c++? I really don't need the high performance
> counter anymore, but I do need a time stamp for the GUI_MOUSE_HOVER
> and GUI_KEY_DOWN repeat delay. I could ignore those for now,
> implementing them later.... actually, I think I'll do that!
>
> Also, this port is taking a lot longer than anticipated. I'm trying to
> remove header dependencies (getting rid of math.h) and the graphical
> rendering. Altering a few class methods to be function calls, and
> moving the input synthesizer outside of the manager. Probably another
> day until it's done. I have a feeling I'm going to have to scrap the
> GUI manager performing the rendering, leaving it to the slice tree.
>
> When this is done, the backends won't have to be changed. The input
> state will be synthesized into messages, and GUI objects should be
> operating normally. But... how is this going to communicate with
> the slice tree?
>
> If it helps, a unique integer id is generated for each GUI object,
> and it is possible to get the state of each object. You can also
> obtain the id of an object by referencing its child index of its
> parent.
>
> > >> From: Ralph Versteegen <teeemcee at gmail.com>
> > >> Sent: Saturday, February 18, 2012 10:26 PM
> > >>
> > >> On 17 February 2012 06:24, Jay Tennant <hierandel8 at crazyleafgames.com> wrote:
> > >> >> From: Ralph Versteegen <teeemcee at gmail.com>
> > >> >> Sent: Thursday, February 16, 2012 5:53 AM
> > >> >>
> > >> >> (Opps, I accidentally didn't send the last message to the mailing list)
> > >> >
> > >> > Oh well. Either way is fine for me, though I'm sure others may like
> > >> > to jump in.
> > >>
> > >> Opps again, I forgot to actually send to the mailing list. Actually
> > >> doing so this time.
> > >>
> > >> >> On 16 February 2012 06:35, Jay Tennant <hierandel8 at crazyleafgames.com> wrote:
> > >> >> >> From: Ralph Versteegen <teeemcee at gmail.com>
> > >> >> >> Sent: Wednesday, February 15, 2012 7:45 AM
> > >> >> >>
> > >> >> >> On 14 February 2012 04:50, Jay Tennant <hierandel8 at crazyleafgames.com> wrote:
> > >> >> >> >> From: Ralph Versteegen <teeemcee at gmail.com>
> > >> >> >> >> Sent: Saturday, February 11, 2012 10:07 PM
> > >> >> >> >>
> > >> >> >> >> On 12 February 2012 06:32, Jay Tennant <hierandel8 at crazyleafgames.com> wrote:
> > >> >> >> >> >> From: Ralph Versteegen <teeemcee at gmail.com>
> > >> >> >> >> >> Sent: Thursday, February 09, 2012 8:58 AM
> > >> >> >> >> >>
> > >> >> >> >> >> I've been struggling to decide how slice based menus should work, so I
> > >> >> >> >> >> need some input. I've been thinking about it for years, but could
> > >> >> >> >> >> never decide where to start (writing this helped a lot though).
> > >> >> >> >> >>
> > >> >> >> >> >> This isn't about making menus draw themselves using slices, but to
> > >> >> >> >> >> allow more complicated menus, like some of the features in these
> > >> >> >> >> >> examples:
> > >> >> >> >> >
> > >> >> >> >> > I had been working on a new GUI system for this, but I lost steam
> > >> >> >> >> > after demonstrating windowing with button and text controls. The GUI
> > >> >> >> >> > is built similar in design to Window's message queuing, but it is
> > >> >> >> >> > not Windows--the GUI engine I was building was native to C++, and
> > >> >> >> >> > used some of the gfx_* functions to create and render the window
> > >> >> >> >> > rectangles.
> > >> >> >> >> >
> > >> >> >> >> > The reason I stopped was I think there was a memory leak in the
> > >> >> >> >> > GUI manager, but I don't really know how to trace memory leaks
> > >> >> >> >> > well aside from stepping through it.
> > >> >> >> >
> > >> >> >> > Come to think of it, I'm not so sure if it was the manager that
> > >> >> >> > was leaking--it may have been some custom windows I had built.
> > >> >> >>
> > >> >> >> I use valgrind for detecting leaks, but of course it's Linux and
> > >> >> >> Darwin only. There are also many memory-debugging libraries which
> > >> >> >> replace malloc/free, but I don't know how many of them can handle
> > >> >> >> new/delete in C++.
> > >> >> >
> > >> >> > Oh ok. I may investigate this further in the near future, dependent
> > >> >> > on time.
> > >> >> >
> > >> >> >> >> > But the messages that were processed included:
> > >> >> >> >> > GUI_HITTEST
> > >> >> >> >> > GUI_CREATE
> > >> >> >> >> > GUI_DESTROY
> > >> >> >> >> > GUI_PAINT
> > >> >> >> >> > GUI_MOVE
> > >> >> >> >> > GUI_SIZE
> > >> >> >> >> > GUI_CLIENT_RESIZE (the OS's window client being resized)
> > >> >> >> >> > GUI_FOCUS
> > >> >> >> >> >
> > >> >> >> >> > GUI_MOUSE_OVER
> > >> >> >> >> > GUI_MOUSE_MOVE
> > >> >> >> >> > GUI_MOUSE_HOVER
> > >> >> >> >> > GUI_MOUSE_LBUTTON_DOWN
> > >> >> >> >> > GUI_MOUSE_LBUTTON_UP
> > >> >> >> >> > GUI_MOUSE_LCLICK
> > >> >> >> >> > GUI_MOUSE_RBUTTON_DOWN
> > >> >> >> >> > GUI_MOUSE_RBUTTON_UP
> > >> >> >> >> > GUI_MOUSE_RCLICK
> > >> >> >> >> > GUI_MOUSE_MBUTTON_DOWN
> > >> >> >> >> > GUI_MOUSE_MBUTTON_UP
> > >> >> >> >> > GUI_MOUSE_MCLICK
> > >> >> >> >> > GUI_KEY_DOWN
> > >> >> >> >> > GUI_KEY_UP
> > >> >> >> >> > GUI_KEY_TOUCH
> > >> >> >> >> > GUI_CHAR
> > >> >> >> >>
> > >> >> >> >> > GUI_IS_MOVABLE_BY_MOUSE
> > >> >> >> >> > GUI_GET_ABS_POSITION
> > >> >> >> >> > GUI_GET_REL_POSITION
> > >> >> >> >> > GUI_GET_SIZE
> > >> >> >> >> > GUI_GET_TEXT
> > >> >> >> >> > GUI_SET_TEXT
> > >> >> >> >> > GUI_GET_ZORDER
> > >> >> >> >> > GUI_SET_ZORDER
> > >> >> >> >> > GUI_GET_TREEDEPTH
> > >> >> >> >> > GUI_GET_CHILDCOUNT
> > >> >> >> >> > GUI_GET_CHILD
> > >> >> >> >> > GUI_GET_PARENT
> > >> >> >> >> > GUI_COMMAND (where this had control-specific commands/notifications, like button being pressed)
> > >> >> >> >>
> > >> >> >> >> I don't understand what any of these messages are for.
> > >> >> >> >
> > >> >> >> > They function very similarly to Window's message handling. For example, upon
> > >> >> >> > window/control creation, the WM_CREATE message is sent to that window's procedure.
> > >> >> >> > In this system, GUI_CREATE is sent to the control's procedure. It's one of the
> > >> >> >> > tenets of window's programming. Is that what you were asking?
> > >> >> >>
> > >> >> >> I should have been clearer: I was only talking about the third group
> > >> >> >> of messages. Although I can guess what most of them do, this seems
> > >> >> >> like taking message passing to an extreme rather than storing a
> > >> >> >> modicum of data on the window objects themselves.
> > >> >> >
> > >> >> > I see. Window's does store that data per window, and I was able to
> > >> >> > mimic that. (Except for the z-order. I only partially worked that out.)
> > >> >> >
> > >> >> > This allowed me to create a window that you could click-and-drag around
> > >> >> > the screen, while keeping all of its child windows (controls) relative
> > >> >> > to it. A custom window we create generally would never need to intercept
> > >> >> > the third set of messages, as I wrote a default message handler for all
> > >> >> > the messages.
> > >> >> >
> > >> >> >> >> > There was a default procedure for all these messages. Is this the direction you
> > >> >> >> >> > were thinking? Is this useful to the engine? I mean, it doesn't have to
> > >> >> >> >> > be used.
> > >> >> >> >>
> > >> >> >> >> The slice based menus I was describing were mainly intended for
> > >> >> >> >> in-game, but I'd also want features like mouse support throughout
> > >> >> >> >> Custom, perhaps by splitting that functionality into a separate module
> > >> >> >> >> somehow, or probably just by making all menus in Custom secretly slice
> > >> >> >> >> based under the hood so the code can be shared. I've been working
> > >> >> >> >> towards that already.
> > >> >> >> >
> > >> >> >> > That sounds great. Side point, are the slices organized like a document?
> > >> >> >>
> > >> >> >> Err... what kind of document?
> > >> >> >
> > >> >> > Like a DOM document? Reason for asking is the GUI manager would be duplicating
> > >> >> > the work, when that could potentially be maintained by the slice manager.
> > >> >> >
> > >> >> > (I realize now that there is no "slice manager", so DOM organizing doesn't
> > >> >> > matter here.)
> > >> >>
> > >> >> See below
> > >> >>
> > >> >> >> >> Here's where I see see any GUI framework as possibly fitting in ("C++
> > >> >> >> >> GUI"), as an alternative to other stuff:
> > >> >> >> >>
> > >> >> >> >>
> > >> >> >> >> GUI | "Application"
> > >> >> >> >> ---------------+---------------+------------------------+--------------------
> > >> >> >> >> | | Basic |
> > >> >> >> >> Display | Rendering | user input | Specialised user
> > >> >> >> >> | | (eg. selecting with | input/top level
> > >> >> >> >> | | mouse, arrow keys) |
> > >> >> >> >>
> > >> >> >> >> +-----------------------------------------------------+ +------------------+
> > >> >> >> >> | Other GUI system |---> editedit runner |
> > >> >> >> >> | (eg. GTK+ based or native) | | rewrite, eg. |
> > >> >> >> >> | +------------------------+ | Python + PyGTK |
> > >> >> >> >> | | +------------------+
> > >> >> >> >> +----------------------------+--->--------------------+
> > >> >> >> >> | | +------------------+
> > >> >> >> >> +------------+ +-----------+ | C++ GUI | | editedit runner, |
> > >> >> >> >> | |---> C++ GUI |---> messaging/control |---> other GUI users |
> > >> >> >> >> | | | rendering | | | | like map editor, |
> > >> >> >> >> | Graphics | +-----------+ +--------------------+ | sprite editor |
> > >> >> >> >> | Backend | | |
> > >> >> >> >> | | +-----------+ +--------------------+--->------------------+
> > >> >> >> >> | |---> Slices |---> Slice-based |
> > >> >> >> >> | | | | | menu system | +------------------+
> > >> >> >> >> +------------+ +-----------+ +--------------------+---> Game, plain |
> > >> >> >> >> | menus |
> > >> >> >> >> +------------------+
> > >> >> >> >
> > >> >> >> > That is an amazing ascii table! How did you do that? Draw out the whole thing?
> > >> >> >> > (Seems too perfect for that...)
> > >> >> >>
> > >> >> >> I used Emacs artist-mode. Emacs probably has a mode for drawing such
> > >> >> >> diagrams easily, but I don't know of it, so I did all the positioning
> > >> >> >> manually.
> > >> >> >>
> > >> >> >> > I am in full agreement. I drew up a chart that describes the pieces
> > >> >> >> > fitting together:
> > >> >> >> > http://www.crazyleafgames.com/OutSourced/ohr_gui1.png
> > >> >> >> >
> > >> >> >> > The message transport from the backend to the engine would be one of the
> > >> >> >> > input or window messages (ie. GUI_KEY_DOWN, GUI_DESTROY, GUI_FOCUS).
> > >> >> >> > If the backend doesn't support events, then the input state could be
> > >> >> >> > polled, and the GUI manager then generates the events.
> > >> >> >>
> > >> >> >> The backend would send "GUI" messages?
> > >> >> >
> > >> >> > Yes. Either taking events it received (like that done in sdl and dx)
> > >> >> > and translating them to GUI_* messages, or synthesizing them from
> > >> >> > input state (like synthesizing fb's input state). I actually already
> > >> >> > wrote a message synthesizer from input state, so that wouldn't be
> > >> >> > hard to translate from c++ to fb.
> > >> >> >
> > >> >> > The GUI messages sent from the backend would be added to a queue
> > >> >> > that the engine could dispatch at its convenience.
> > >> >> >
> > >> >> > The GUI manager would synthesize the messages into further messages,
> > >> >> > such as GUI_MOUSE_MOVE, GUI_MOUSE_LCLICK, etc.
> > >> >> >
> > >> >> > Finally, the windows/controls themselves would process the messages
> > >> >> > that the GUI manager would dispatch.
> > >> >>
> > >> >> Hmm, yes, this does sound useful. I do want to move to the model of
> > >> >> each control handling messages directed at it separately, because I've
> > >> >> seen what happened in the map and sprite editors. The sprite editors
> > >> >> are just terrible for all sorts of reason, but even in the map editor,
> > >> >> where the code is relatively clean, handling all editing modes and all
> > >> >> controls in the same function really makes a mess of things.
> > >> >>
> > >> >> So now I remember what I was thinking before about how such a GUI
> > >> >> framework could be used (rather than just be an option). Here's a
> > >> >> revision of the earlier diagram (so much easier this time). Before,
> > >> >> two arrows going into a box meant "one or the other", but now it means
> > >> >> "both", while arrows marked 'a' and 'b' mean "one or the other".
> > >> >>
> > >> >> GUI | "Application"
> > >> >> ---------------+---------------+------------------------+--------------------
> > >> >> | | Basic |
> > >> >> Display | Rendering | user input | Specialised user
> > >> >> | | (eg. selecting with | input/top level
> > >> >> | | mouse, arrow keys) |
> > >> >>
> > >> >> +-----------------------------------------------------+ +------------------+
> > >> >> | Other GUI system |---> editedit runner |
> > >> >> | (eg. GTK+ based or native) | | rewrite, eg. |
> > >> >> | +------------------------+ | Python + PyGTK |
> > >> >> | | +------------------+
> > >> >> +----------------------------+-a->--------------------+
> > >> >> | | +------------------+
> > >> >> +------------+-----------------b-> GUI messaging | | editedit runner, |
> > >> >> | | | framework |---> other GUI users |
> > >> >> | | +-----------+ | | | like map editor, |
> > >> >> | |---> C++ GUI | +--------------------+ | sprite editor |
> > >> >> | | | rendering | | |
> > >> >> | Graphics | +-----------+--------------------------a-> |
> > >> >> | Backend | | |
> > >> >> | | +-----------+ +--------------------+-b->------------------+
> > >> >> | |---> Slices |---> Slice-based |
> > >> >> | | | | | menu system | +------------------+
> > >> >> +------------+ +-----------+ +--------------------+---> Game, plain |
> > >> >> | menus |
> > >> >> +------------------+
> > >> >
> > >> > Ok, I think I follow--the menu's can be slice- or GUI-messaging- based.
> > >> > These drawings definitely help to organize structure.
> > >>
> > >> No actually the "Gui messaging framework" would be mandatory, the C++
> > >> GUI *rendering* stuff you wrote would be optional, if you wanted to
> > >> try to fit that in. Since that would only affect the visual appearance
> > >> (unless you handled additional messages resulting in additional
> > >> functionality of some sort) it may not be worth the trouble. A native
> > >> GUI widgets option probably would have some additional benefits?
> > >
> > > Heheh, well I almost got it right! The rendering by the GUI manager is
> > > only to send a message to the controls to render themselves--the
> > > message being GUI_PAINT. This gives the "control" control over
> > > rendering itself, which may or may not be useful. Generally, I had
> > > enacted a clip region for drawing each control to prevent it from
> > > drawing outside it's rectangle. For me, such control was useful, as
> > > I could paint the "highlighted" image, the "selected" image, the
> > > "disabled" image (if I had supported that), or rendering some
> > > complex geometry inside it.
> > >
> > > If we can set which slice is enabled (like using the "highlighted",
> > > "selected", "normal", and "disabled" images) for rendering, then
> > > GUI_PAINT could be removed, and rendering delegated towards the
> > > slice tree.
> > >
> > >> >> But I don't want to over-complicate things. Can we start with
> > >> >> something simple, and add features as needed? What's involved aside
> > >> >> from synthesizing messages from input, dispatching them, and hit
> > >> >> testing?
> > >> >
> > >> > Yes, we can start with a reimplementation of one of the editors
> > >> > (like the sprite editor) in a 'spam' experimental screen.
> > >>
> > >> Sounds good.
> > >>
> > >> > But before
> > >> > that can begin, I really need to port the code out of my framework
> > >> > and into one useable by the engine. (I had Surface objects, etc. like
> > >> > the OHR has created almost the same way, but I also had VertexBuffer
> > >> > and IndexBuffer objects etc., so I'll need to remove those entities.)
> > >> >
> > >> > Developing the controls for that should be pretty easy, since I've
> > >> > already written a primitive button and text control.
> > >> >
> > >> > Perhaps the steepest part of this development is writing the control
> > >> > "factories" to create and destroy instances of the controls, which is
> > >> > managed by the GUI manager. I'll detail that after I port the code.
> > >> >
> > >> > Speaking of when to port, I won't get to it until this weekend.
> > >> >
> > >> >> > I know that's a lot of levels of messaging, but I got it running
> > >> >> > quite nicely with pleasing results (exception being the z-order
> > >> >> > could not change. That is because of how I managed the windows--it
> > >> >> > would have been better if organized like a DOM document).
> > >> >> >
> > >> >> >> I'm really not sold on message passing. While I was making changes to
> > >> >> >> gfx_directx I had another look at the new API. I made a couple
> > >> >> >> changes, but otherwise I'm happy with it, except for SendMessage,
> > >> >> >
> > >> >> > Yeah, I don't like SendMessage anymore. I thought it a graceful way
> > >> >> > to respond ala "Not Support!". But I don't see the benefit any longer.
> > >> >> >
> > >> >> >> which doesn't seem like the right interface: plain functions would be
> > >> >> >> simpler for the parts we would actually use, and anonymous key-value
> > >> >> >> string pairs would more flexible for backend-specific stuff which the
> > >> >> >> engine doesn't need to know about. However, that's passing messages in
> > >> >> >> the opposite direction...
> > >> >> >>
> > >> >> >> Also, I'm starting to wonder if it wouldn't be better to statically
> > >> >> >> link gfx_directx!
> > >> >> >
> > >> >> > Hmm. Since it would be Window's users, I don't see why not. If we use
> > >> >> > that Dec. 2004 sdk, there wouldn't be extra runtime requirements. Ok,
> > >> >> > they'd have to be running at least Win98. :P Seriously, though, who still
> > >> >> > uses that 16-year old operating system for gaming?
> > >> >>
> > >> >> You mean Win95? I don't really care about support for that. Someone
> > >> >> mentioned to me in IRC that they were using win98 a month or two ago
> > >> >> (funny, I think I've said that many times), but from the sound of it
> > >> >> their computer was way too slow anyway.
> > >> >
> > >> > I don't think dx9 is officially supported on Win95 (as in, no d3d9.dll),
> > >> > but Win98 supports it. Since we're using basic features of dx9, I
> > >> > think it automatically falls back to dx8.1 hardware if available.
> > >> >
> > >> >> So linking statically would mean that the .exe couldn't run at all on Win95?
> > >> >
> > >> > Yes.
> > >> >
> > >> >> >> > The GUI manager requests slices for each window/control created. The GUI_PAINT
> > >> >> >> > message had been issuing from the GUI manager previously. Does the slice
> > >> >> >> > manager handle rendering? If so, GUI_PAINT is pointless now.
> > >> >> >>
> > >> >> >> Are we talking hypothetically? I'm a bit lost. There is no "slice
> > >> >> >> manager" currently, just a DrawSlice function which draws recursively,
> > >> >> >> plus a bunch of functions for manipulating slices.
> > >> >> >
> > >> >> > Oh, I didn't know that. That completely changes my understanding. I
> > >> >> > guess the GUI manager would need to maintain a document structure,
> > >> >> > ordering draw calls when appropriate.
> > >> >>
> > >> >> I have no javascript experience, so I don't know how a DOM document is
> > >> >> actually organised.
> > >> >
> > >> > Have you dealt with xml? That's the kind of tree-document I'd like to
> > >> > mimic for the GUI manager. I did that, but I didn't write a good way
> > >> > to move the nodes around. So once built, it's stuck (that's the
> > >> > problem with the z-ordering I had).
> > >>
> > >> I've hardly touch xml, but I think I get the idea.
> > >>
> > >> Positioning should be done using the slice tree, so that menu layouts
> > >> can be created in the slice editor. That also solves any z-ordering
> > >> problems. Even if the slices aren't being used for rendering, couldn't
> > >> their sizes and positions be updated to reflect the actual sizes of
> > >> the controls? Basically, I think we should start off with just slices
> > >> for layout/rendering, since they would appear to already be able to do
> > >> everything we need.
> > >
> > > Oh, perfect! That removes the rendering burden, so it becomes strictly
> > > data management. I like the benefit that the slice editor would be able
> > > to edit their appearance.
> > >
> > >> To quote an excellent article [1] I recently read:
> > >> "It's a mistake to try to anticipate use cases you don't actually have
> > >> or else you'll end up overengineering your solution."
> > >>
> > >> [1] http://nathanmarz.com/blog/suffering-oriented-programming.html
> > >
> > > Hehe, I liked that one.
> > >
> > >> >> But the slice tree does have organisation: it's a tree. The slices
> > >> >> corresponding to the menu items of a menu would be the children of the
> > >> >> container slice, for example. The draw order is specified by the tree,
> > >> >> but it's true that a lot of slice manipulation would be required for a
> > >> >> slice-based menu.
> > >> >
> > >> > Hmm. I wonder if it'd be better to manage the surfaces itself then?
> > >> > It could command the drawing and the drawing order when necessary,
> > >> > using gfx_surfaceCopy, etc.
> > >>
> > >> I'm not sure why you're suggesting this, however I would imagine that
> > >> if we had multiple windows (eg. floating toolbars), then the GUI
> > >> framework would be responsible for managing them, preferably totally
> > >> abstracting them away.
> > >
> > > Well, if the slice tree could render the order, then nevermind my
> > > statements.
> > >
> > >> >> Hit-testing should be done by searching the slice tree. Aside from
> > >> >> that and delegating up the tree, I don't imagine message dispatch
> > >> >> would have much to do with slices.
> > >> >
> > >> > Hmm, yes. I think I did a hit-test on every window/control, but it would
> > >> > have been better to check which branch of the tree is successful, then
> > >> > progress through that to find the positive hit-test. Yes, your idea
> > >> > works great! I probably won't implement that in porting the code, though,
> > >> > simply to get it ported faster. But I would like to see that done, since
> > >> > it is a better method!
> > >> >
> > >> >> Of course everything becomes more complicated if you want to provide
> > >> >> an alternative to slices (the C++ widget rendering stuff you wrote).
> > >> >>
> > >> >> >> > GUI manager issues GUI_MOUSE_OVER messages to all windows/controls, and
> > >> >> >> > GUI_KEY_*, GUI_MOUSE_*, GUI_CHAR messages to the focus windows/controls.
>
>
> _______________________________________________
> Ohrrpgce mailing list
> ohrrpgce at lists.motherhamster.org
> http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org
>
More information about the Ohrrpgce
mailing list