02-08-2013 12:18 PM - edited 02-08-2013 12:18 PM
I'm trying to show the user a list of items (representing remote clients) of varying number. In principle this would be possible simply with an array of clusters. But there are several small things I would like but can't do using this approach, in turn making the user interface not as user friendly as I'd like it to be (maybe I'm missing something, but Labview isn't really that great and/or easy for the developer when it comes to the capabilities to user interfaces compared to other programming languages).
I would like to show some of the items with a different background color (it shows a state of that item). But if I change the color of a cluster per property node, of course the color of all the clusters in the array change.
(let's say the list has room to show 5 items at the same time): If there are less than 5 items, I would like the rest of the space to be completely empty and not show greyed out uninitialized clusters (this could confuse the user). If there are more than 5 items, I'd like there to be a vertical scrollbar so the user can scroll through the items.
How would I handle a button press in one of the clusters (e. g. to show details of the selected item somewhere else)?
Here is an example to get the idea. It's a screenshot of Firefox's Addon manager, one of the results of an image search for "list ui". Ignore the icons, fonts and sorting, but the rest pretty much shows what I'd like to do (buttons within items, different coloring, scrollbar).
02-08-2013 12:54 PM
You can make the controls inside the cluster transparent and place a large colorbox in the background. The color is the value.
02-09-2013 11:01 AM
You could go with Altenbach's suggestion of adding a color box and use a property node to change the number of rows in the array control to hide elements, but that won't really help you if you want to do further customization for each cluster (such as disabling elements in a specific cluster) and the array control has an annoying property where the scrollbar always allows you to see an additional uninitialized element.
Another alternative to that idea is to create a bunch of subpanels and use them to simulate an array of clusters. Essentially, you run a list of N VIs (possibly dynamically created reentrant copies of the same VI) and use their references to put them into the subpanels, which are stacked vertically. Then, you use a separate scrollbar control to control which VIs are shown in the subpanels. You will only need enough subpanels to fit in the height of the control, but you create more than you need (once you have the code which controls them, handling them is easy, so creating more is cheap). You then use events to communicate (events like "stop" or "something was selected").
It sounds like this is something which could be turned into an XControl and would then be fairly simple to use.
02-09-2013 11:21 AM
You can also find some discussion about this type of a UI here - https://decibel.ni.com/content/thread/15045?tstart=0
Darren said there that he will try to remove the passwords on the VIs for LV 2013, so you can try joining the beta program to see if that happened.
02-10-2013 01:50 PM - edited 02-10-2013 01:50 PM
Good to see I'm not the only one missing a feature like that (and not just having missed something). Not so good to see that the current solutions are almost "hacks" (getting images of hidden controls and showing them somewhere else o_O).
Guess I have to wait until a newer version of Labview has this ability. Really weird when something that's nothing more than a "listbox.add(element)" in another language suddenly becomes such an effort (damn, I guess it wouldn't take me more than 10 minutes to mock something like this up in such lowly things as HTML and JS 😉 ).
02-10-2013 03:15 PM - edited 02-10-2013 03:18 PM
While modern UI frameworks have certain abilities that are sorely missing from LV, I'm fairly sure that it wouldn't be listbox.add(element) in most of them. A standard listbox is one thing, but I'm sure that someone had to write special framework code at some point to create the Firefox listbox in your example. Also, the hidden control image hack you refer to is only one way of solving a problem which is not the one you asked about.
@cober wrote:
Guess I have to wait until a newer version of Labview has this ability.
LV is a programming language. If there's something you're missing and is important to you, then you write it yourself. You already have some pointers. Personally, I can't say that I ever really needed it, but it doesn't strike me as a very complicated project. Like you, I think I could mock something up in 10 minutes, although that would only be a basic proof of concept.
Alternatively, if you happen to have a .NET control which implements this, you can probably use it in LV and then call the listbox.add(element) method on it.
02-10-2013 03:51 PM
And incidentally, if all you want are different background colors and buttons in each element, you can simply go with Altenbach's suggestion, which works just fine. If you want to know which button was clicked, simply register for the value change event for the array and compare the OldVal and NewVal terminals. The changed element will be false.
02-10-2013 03:51 PM
And incidentally, if all you want are different background colors and buttons in each element, you can simply go with Altenbach's suggestion, which works just fine. If you want to know which button was clicked, simply register for the value change event for the array and compare the OldVal and NewVal terminals. The changed element will be false.
02-11-2013 01:17 PM - edited 02-11-2013 01:18 PM
Ok, it bugged me enough that I started experimenting. What I came up with is in the attachments. The blockdiagram is nothing beautiful to look at (used no subVIs and auto cleanup did it's own to make the blockdiagram larger than it should be).
The solution works if the list elements are all of the same type (so no custom and/or dynamically createable listelements). For those who can't/don't want to open the files: one typedef'd cluster defines the list elements to show. Then there's a cluster that contains as many of the list elements as you want to be able to show in the list at the same time. This cluster of clusters is just for display. And finally an array that will contain the actual list elements.
For the "fake" listbox you then do the following:
Using autosizing, resize the container cluster using "arrange vertically" once, but set it back to "none" immediately. I also removed the border of the cluster by customizing the control.
Resize the array to show the same number of elements as are contained in the container cluster. Disable the index display, but enable the vertical scrollbar.
The container cluster should now have exactly the same size as the array, except for the scroll bar added to the array. Place the container cluster over the array, so only the scrollbar of the array will stick out under it.
The rest is some event handling: on mousemove (+previous mousedown) over the array (which can only be the scrollbar, because the rest is obscured), check if the indexVals-property of the array has changed. If yes, get the listitems from the array starting from the indexes and write them into the clusters in the container cluster. At this point the properties of the listelement clusters and/or their subelements can also be changed (disable, grey out, color, ...). If there are less elements in the array than there are listitem clusters in the container cluster, the listitem clusters can be made invisible. The container cluster will stay the same size (that's why you need to set autosizing to "none" after getting the right size) and, because it has a background color, occlude the uninitialized array elements giving the illusion of "beyond the end" of the list.
Pros:
• it works reasonably
Cons:
• Sluggish, the iterative updating of the values/properties of the listitems and their subelements is often visible, especially if there are changes in disabled status or colors (didn't test much else).
• Sometimes, while still holding down the mouse button, scrolling stops to work. I don't know why, but I have to drag the scrollbar again. Funny thing is though, the same sometimes happens to me on the startup screen of labview, that shows the recent files.
• you always have to scroll a whole element up or down. For the user it would be more pleasing to have a continous scroll (it would be way easier to tell how much you scrolled that way).
02-11-2013 01:38 PM
Use the panel property "DeferPanelUpdates" set T befor your loop set F after your loop. The loop will run very effeciently and all changes will apply at the same time.