Greetings on my first post! This is a cross-post from the other forum, at Norman’s suggestion,
This is a bit of an open-ended question. I would have liked to ask something more concrete, but this is what I have.
Oregon Research Electronics, which is basically me, manufactures a small number of scientific instruments ([http://www.orelecctronics.net ). The instruments all use a terminal-based menu system to configure them for use. We are working on a major product upgrade and envision that to use a very similar menu system (inherits from earlier models) with menu variants depending on the product version. The device identifies itself, by model and serial number, in the first lines of the menu.
I’ve taken several stabs at creating a GUI to replace the terminal. They have worked but I’m less than thrilled with the results. Even worse, it would have to be rewritten when the new products come along.
To somewhat solve the obsolescence issue, I’ve been thinking of “version files”, maybe xml, that could be added after the GUI was written. This could solve the problem of parsing the different variants. And, I think that there will be a maximum of perhaps 6 or so window formats needed to deal with each of menu items.
But, I am lost, at this point, on how to organize and display the topic windows in a way that is driven by the xml file for that product variant. Presently, I’ve been using tab panels and page panels to organize things into a sort of hierarchical arrangement. I’m not convinced, right now, that that is the most flexible or appropriate way to do it.
So… I’m looking for suggestions about how to organize and display various menu topics that is flexible toward future versions.
Oregon Research Electronics
Configuring an app that can load a menu from a runtime config file is pretty simple.
Really the trick is what would those menu handlers invoke ?
Would that vary from model to model ?
If so then the app has to already have the code in it UNLESS you also want to somehow extend the app in some ways using Xojo Script that also get sent along ?
What exactly don’t you like in your interface? Have you done a workflow analysis with your customers?
Can you make us a video of your app so that we can see the interface and what a user normally does with it?
Here is what the menu looks like. After connecting USB and sending ctrl-R, the unit responds with
Then “?”+EOL gives
I expect all future menus to follow this basic scheme.
By the way, this really shows the lack of a “code format” option that lists typically in a fixed pitch font, such as courier. I originally copied and pasted fixed-pitch text and the editor totally messed it up. That forced going back to use images. Sorry to be picky, but not so good.
There are just a few interaction formats:
(1) read-only (infomation) May be single line or multi-line lists (future)
(2) Single number entry with fixed number range
(3) Two inter-related number entries (Period and Duration - Duration cannot exceed Period)
(4) Complex number entry (such as time and date)
(5) Text entry (Label)
(6) Binary entries (YES/NO or ON/OFF)
(7) It is possible that another format will be added in the new product, though not clear what it will be
As for what I don’t like, the big one is having to rewrite the GUI for new menus. Here is an example. You can see the top-level tab panel. The radio buttons select the page panel within the tab panel.
Thanks for taking a look at this and thinking about it. It is genuinely appreciated.
Oregon Research Electronics
2012 I’ve had a similiar problem to solve. Not only different menu options but also different translations should be implemented in different controls (drop down menus, buttons, window and caption texts etc). Back in those days I solved it with an direct database access. Instead of XML everything was in a database. Today i would do the same but via JSON-Webservice in front of the database…
check out my video: https://vimeo.com/44154031
SO to answer your question: Yes this is possible with XOJO… I would say this is one of the main advantages of XOJO, you may reuse and keep your classes between different platforms.
Please explain in plain english what your gizmo is doing. NO jargon. Make a list of tasks and subtasks.
This device is a data logging accelerometer. Picture insutu:
Its internal tasks include:
(1) Sample management for acceleration sensor
(2) Maintaining date and time
(3) Writing to microSD card
(4) Providing terminal interface with associated menu via USB and virtual serial port
(5) User interface with several LEDs and several magnetically operated switches
The GUI tasks are:
(1) Mimic terminal by detecting USB connection to device and “logging in”
(2) Present current status & configuration state to user
(3) Allow user to change the configuration state
(4) Transfer configuration changes to the unit.
Items (1) and (4) work well. Items (2) and (3) work, but require regular rewriting as new products become available.
Thank you very much
Oregon Research Electronics
THIS could be hard to hand in such a generic way that th main app requires no tweaks / fixes etc when a new device comes along
Now making it so a new device is just adding some new code to deal with tit is one thing
Rewriting existing code should ideally not be required
But this is of course said without having seen any of the existing code or knowing anything about the devices etc
I have control over the menu system for the new device. So, I control what appears in the menu. I hope that means that there won’t be any new menu line styles that are not in my current list. The challenges include (1) parsing the new menu entries, (2) displaying an appropriate panel that includes the necessary support text and value displays (3) allowing the user to change the value, usually within line-specific limits, such as numeric between 0 and 255, (4) providing the update message to the device that contains the necessary key words and value in the required format.
What I have been trying to wrap my head around is, maybe to use a metaphor, a bit lit dynamic menus. That is, how to add an arbitrary number of panels (maybe in overlying categores, as my image above, shows) with one of several predefined layouts, and populated with menu-line dependent text, values (read from the unit and maybe edited by the user). I think that I know how to write an xml file that contains the needed information. What I am not sure is how to populate the window with the appropriate panels.
the menus can definitely be done dynamically
my worry is more item #4
do the devices use a common api programming interface etc or is this possibly custom ?
if its custom per device the existing code cant know about the new device
BUT the existing code can be made to easily handle having a new device in a way that its not rocket science and wouldnt break existing devices (do you ever deploy new software to old devices ?)
I think there’s room to do what you want but I’d have to understand some of this a whole lot better than I do now to be more sure
It is custom of my design, It is very consistent across menu items. Key letter, optional space, “value” which may be numeric or string, depending on the menu item, followed by EOL. Future may require up to two key letters and may require the space (to make back compatible with single key letters).
Thats it. Always.
I meant the hardware more than anything
If the code to set up each device is largely unique then I dont see how you could get away from altering the code to support a new device
However, there may be alternatives
It is unique per model. At this point, there are two models, with a third one coming. That one may have a few variants, that will all use subsets of the menu of the primary model. BUT, I don’t know that for absolute certainty, so I am trying to figure out how to give it more flexibility than it now has. Now = rewrite for any new model or variant.
The menu is quite frankly the least of my worries
Some where I even have a sample of loading a menu from an xml file
That part, setting up the menu itself, is dead easy
Hooking it to the right routines to handle the menus isnt entirely hard either
The real trick is how to handle each new model from the code those menu items attaches to
But that too should not require rewriting - usually just adding a class to handle the new model and making sure that the menus can call the right item in that new class
Does that sound sort of plausible to you ?
Overall, what is the issue you’re trying to solve? It seems like you don’t want to modify the GUI app whenever a new device model is introduced. But how often would this be? Do you anticipate a lot of new models? You say there’s currently only two with a third coming soon. Building a complicated self-configuring GUI seems like a lot of work for one or two new models a year. And I assume you’ll have to distribute the configuration “code” to existing customers anyway, correct? So integrating an auto-update system would make it easy to distribute new versions of the GUI just as well.
That said, I think it would be possible to do what you’re asking (if I’m understanding it all correctly) with ContainerControls and changing your tab & radio buttons to Popups (dropdowns). The popups could be fed from your “data” file (I would use a SQLite db) so you could add or even change those choices without touching the GUI. You would need to design ContainerControls (which are basically frameless windows that can be embedded in Windows or other ContainerControls) that have a set number/layout of controls to fit each particular situation. The db lists which ContainerControl(s) to use for each combination of popup selections for each device model (probably at least two related tables). Then use a common method on each ContainerControl that gathers the data from the controls and outputs the proper “data string” that needs to be sent to the device.
Is that in the ballpark of what you had in mind?
Sounds quite reasonable.
I think that Iwill try mocking up a prototype. May not use xml as I have to relearn how deal with that. At this point, I see xml as simply a way to organize the information. What I need to mock up is the construction of a set of dynamic panes. This might be fun.
Thank you, very much, for your help and suggestions. I might have stumbled through this, on my own, but your advice has really helped establish a much clearer path.
If you don’t have a new version of your hardware then I wouldn’t worry about supporting new features on the fly.
ContainerControls are your friend. Make all controls on the containers private. Then define the interface between the window and the containers.
In my app I use something called StackViews to have areas that can be opened and closed like this:
Thank you Beatrix…
Clearly, I need to get more familiar with ContainerControls. What is the benefit of private controls?
Oregon Research Electronics
If you have public controls then you can say
But what happens if you rename your control to OtherControl or you add new controls? Then you have to change something. If you have private controls then you have to define a behaviour that is independent of the control names.