ScrollingTextBox and a Context Menu

One gadget on the go, one proposed. The ScrollingTextBox class is the first one. It’s a combination of a MultiLineTextBox and ScrollbarVertical. All of the event wiring up is handled for you, and it presents the same API as the MultiLineTextBox. The two are completely interchangeable. There are a few things I need to do to it before it’s finished, including a resize function, adding in wrapper functions to mimic the scrollbar API and raising events, but it’s coming along. It’s in the SVN repository and is used in the Debug class.

Note that the MultiLineTextBox also supports horizontal scrolling, should you need it. I just haven’t added a horizontal scrollbar to the ScrollingTextBox class, as I’m guessing that vertical scrolling will be considerably more in demand.

Next is the proposed ContextMenu class. A right-mouse menu has been on the feature list since I started Woopsi, and I’ve been planning out how it will work. The ContextMenu will exist as a singleton within the Woopsi instance (putting it there ensures that it’s fairly easy to ensure that it always appears at the top of the gadget stack). Users can open it by clicking one of the shoulder buttons and tapping a gadget. If that gadget wants to use the context menu, it will:

  • Call the ContextMenu::clear() method
  • Add as many ContextMenuItems into the menu as it needs to
  • Set the ContextMenu’s event handler to be the current gadget
  • Show the menu

The menu will automatically hide itself if it loses focus (ie. user clicks elsewhere) or an item is selected. In order to make this work, gadgets need to be able to interrogate the status of the DS’ buttons. I don’t think there’s a supported way to do that yet, so I’ll need to add it in. That should also allow developers to check for multiple keypresses/chording.


Jeff on 2008-04-01 at 03:36 said:

You are presumably going to support UP/DOWN keys as well as screen taps in the menu? And A-for-Accept and B-for-Cancel?

The thing that worries me about having the menu initiated by a Gadget is that the EventLoop processing will need to subvert the overall “active gadget” logic? In my “File Selector”, I avoid this by forcing a completely new screen up so that I don’t affect which gadget is active in the originating screen. It also leaves vbls, etc still working in the background because it runs a captive eventloop.

(Obviously it can be made to work, it just needs a little thought on where you record the ‘previous active gadget’ pointer and how you restore it safely, given that some of the commands on the popup menu might have closed the window containing the gadget that initiated the popup?)

Rather than limiting this to context menus, imagine I waste some of my screen space on a menubar? Each menu item might be “context-sensitive” - think the Edit menu in OSX/Windows apps. The menu bar manager would need to ask the Active Gadget ‘is this a valid menu item for you’ and would disable it appropriately.

The menu classes should be independent of the context in which they were invoked, so that a menubar can be introduced later on, if desired.

Are you planning on hierarchical menus? I wouldn’t, given the size of the screen…

Jeff on 2008-04-01 at 07:35 said:

Hmmm, I just remembered how Amiga menubars worked. If you had a menu that had “tickable” options, then when you snapped the window open, you could toggle the “ticked” state of as many menu items as you wanted. That was different from the MacOS menus where you had to select/release on a toggleable menu to toggle it. I think Windows was the same.

Given the amiga bent in other classes, were you thinking of heading in that direction? Because the abstract menu class that supported both modes of operation might be a bit trickier…

ant on 2008-04-03 at 16:54 said:

Not sure about having built-in keyboard events in the menu. It does make sense, though. Will think about it.

You’re right about the event logic, it’ll need some tinkering to make it work properly without breaking the existing model. Menu bars might actually be a bit more complex; again, it needs some thought. I’ll probably do what I always do and just write it and see what happens.

Yeah, the Amiga was tricky with its menus. If you held down the right mouse button until you found the option you wanted and released the button, that option would get selected and the menu would close. However, if you kept the right mouse button pressed and clicked with the left, the menu would remain open and the option’s action would get added to the message queue. You could select multiple options before releasing the right button and triggering all of the actions.

I don’t think that would work on the DS - there’s no right mouse button. The menu would have to close when an option was clicked.

ant on 2008-04-03 at 22:02 said:

I’ll probably implement both and see which one works best. It’s difficult to judge without having it running.

Jeff on 2008-04-03 at 22:54 said:

It seemed to me like you were treating “left-shoulder-button-plus-click” as a right-click - perhaps the menu can stay open as long as the left shoulder button remains selected. Or at least treat clicks as right instead of left, so to speak.

I have a similiar quandry in the HP emulator - you can actually press multiple buttons on the calculators to invoke a number of self-tests, but the DS doesn’t lend itself to clicking more than one space at once. Fortunately, the multiple-key-chording is only “ON+key” so I’m thinking of treating the shoulder buttons as an alternate “ON” button, one which can remain pressed.

Jeff on 2008-04-04 at 07:26 said:

Its annoying when you have to need empirical evidence to decide which approach to a problem is better.

Having said that, Woopsi has been brilliant for test-it-out development where you knock up a quick app to test a feature, especially with the SDL port. That literally took weeks off the HP emulator.

ant on 2008-04-04 at 07:35 said:

How’s the HP thing going, by the way? I’ve got a port of it on my hacked iPod now, it’s a great little app.

Jeff on 2008-04-04 at 11:26 said:

99% there - its all up on ds-hpcalc.sourceforge.net

I just need to fix the “it writes to the root directory” - I want it to write to “/data” instead.

Then I need to work out how to announce it to the world.

(Really, I’m just distracted by the makefile thing - I really want this thing to build turnkey before the world looks at it)

ant on 2008-04-04 at 18:26 said:

Looks good. I’ve found that if you can get one of the big homebrew sites to announce your release the rest will pick it up. You could post an announcement on the GBADEV forums, or Emuboards.com, or the DCEmu forums - three good sites. Announcements on any of those should get noticed. Of course, I’ll be glad to put up a post about it here, though I don’t know how much exposure that’ll give. I think DCEmu picked the latest Woopsi release up before anyone else - before I’d even posted it on the PALib site, which is where everyone else seemed to get it from - but they might be watching the SourceForge RSS feed instead of the blog.