Jump to content

An Extensible, Object-Oriented Alternative to XControls


The Q

Recommended Posts

On 4/12/2019 at 7:00 PM, The Q said:

Now on to the sluggish behavior problem.  Can you reach the examples in the Example Finder?  In the Example Finder search for QControls and test each of those out and let me know if it is all of them or just the Tree Selector one.  This will help me narrow the problem down.

@X___, I'm sorry this has been a bad experience for you but thank you for your patience and for being a troubleshooter for me.  With your help we can make this event better.

No issues with the examples.

Link to comment
On 4/12/2019 at 6:56 PM, The Q said:

I'm working hard to try to understand the problems.

I'm currently stepping through the wizard code node-by-node trying to see the path problems you are seeing. 

One thing I see is when you start the new dialog when a project is not open or the project is not saved, the default folder it picks first is the [LabVIEW Default Data Directory]\QControls\[QControl Name]\[QControl Name].lvclass normally this is in the [User Documents]\LabVIEW Data\QControls\[QControl Name]\[QControl Name].lvclass.  This is why you are seeing the "LabVIEW\QControls" coming up as default.  If the wizard is started when a saved project is open then the default path is relative to the project: [Project Path]\[QControl Name]\[QControl Name].lvclass

At the VI you showed above, nothing has been created yet.  It has just constructed the path as the destination of the new QControl class and the indicator for the final path shows you where it thinks it ought to be saved.  However, something very wrong is happening for you if it is keeping the "LabVIEW\QControls" in the path.  At this point it should be the have a folder using the class name and the class. 

The destination should be showing you the class name and folder like this:

image.png.2219e81a4619d9dd0f1170fdd71609fe.png

The error down stream occurs when the path is checked to exist already.  The full path with the new class should not exist yet.  But if your path is just folders that do exist it will pass the error at the check here:

image.png.e6b04b76e27a07609aa83f6320f84e28.png
 

So, now why is it not showing the class name and folder?  Does the QControl Name tab let you past without typing the new name?  If the name is blank I could see this being the cause but the Next button should be disabled until you type something in.  (I found an error I should catch as it does let you just type a space and that would be bad too.)  If you do specify a name, I wonder why it is not being passed correctly.  I can see now that the way it is being passed is not robust enough and that will need to be fixed.

After it starts the scripting, if it fails, it does have to be started over.  This could probably be more elegant but if it does error while scripting there is no cleanup code to remove what was partially created.  Maybe I should add this in the future.

I think I understand what I was doing wrong: I was doing those tests (at least some of them) starting from an unsaved new project. You may want to check for that or strongly warn users against trying to use an unsaved project (you probably do, but even though I read the Getting Started Guide, I can't remember having registered this info).

This being said, the sluggishness remains...

Edited by X___
Link to comment
On 4/11/2019 at 9:51 AM, X___ said:

Sounds like getting rid of the checkboxes would kill two birds with one stone...

In retrospect, I believe this would be a nice UI tool to define (contextual) menus: starting from a pre-populated template, unchecking boxes would simply remove that item (or sub-menu) from the final control menu.

Link to comment

@The Q In the manual, you write (7.3 Methods):

Quote

Unfortunately, classes do not have the option of accessing methods through the Invoke Node. Therefore, Methods must be public and are only accessible by using the VI on the block diagram of the QControl Class’ owning VI.

I don't see any example of a public method in the examples coming with the toolkit, so I am trying to figure out the intended use.

My understanding is that if I want to add a method to a QControl (say, "Add Element"), I need to provide a VI which the user needs to use wherever they want to call that method, rather than having the convenience of using an Invoke Node and connecting the QControl refnum to it (which would be neat, as this would provide a built-in list of methods). Do I get the idea right?

It sounds like a polymorphic VI for those methods could do the trick of providing a list of methods, and using VIs not shown as Icons would bring us close to an Invoke Node:

1136709193_PolymorphicVInotasIcon.png.eef4345dd31a149c3042975e3706150c.png

The VI above has nothing to do with QControls, it's just borrowed from my own approach to the same problem (of native control enhancement), but it shows what I mean.

If that makes sense, I wonder whether this is something that could be added to the Wizard? Something like "New Method from template" that would add a VI to (or create if there is none) a polymorphic VI and let the user define the number of parameters to use for that specific control (or fix that to one, I could live with either option)...

Edited by X___
Link to comment
19 minutes ago, X___ said:

My understanding is that if I want to add a method to a QControl (say, "Add Element"), I need to provide a VI which the user needs to use wherever they want to call that method, rather than having the convenience of using an Invoke Node and connecting the QControl refnum to it (which would be neat, as this would provide a built-in list of methods). Do I get the idea right?

It sounds like a polymorphic VI for those methods could do the trick of providing a list of methods, and using VIs not shown as Icons would bring us close to an Invoke Node

That is true.  I have thought about using the "Not shown as Icons" to get the same look as a Invoke Node or even creating an Xnode (but I have never created one of those before).  A polymorphic would give you a list of the VIs included in it but not the ones inherited from the class hierarchy which are available too.  A cool tool that does give you all of the methods available is MGI's Class Method Browser (MGI's Website | LabVIEW Tools Network).

Quote

I wonder whether this is something that could be added to the Wizard? Something like "New Method from template" that would add a VI to (or create if there is none) a polymorphic VI and let the user define the number of parameters to use for that specific control (or fix that to one, I could live with either option)...

I do need to add some more templates and scripting.  One of which would be to help make Properties from the items in the State Data.  New Method templates could be helpful too.

Link to comment
Quote

I think I understand what I was doing wrong: I was doing those tests (at least some of them) starting from an unsaved new project. 

I tried to make it so you could do it from a new project but it always had problems (that is why I warn against it in the tutorial, it wouldn't work every time).  I'm going to put some time into making this better.

Link to comment

Unless I am mistaken, the composite control approach of using a cluster will potentially cause problems if such a control happens to be partially overlapping another control (on a VI panel). I tried to "dislocate" the large scrollbar QControl to emulate a moving subcomponent, and put a String control underneath the transparent part of the cluster (separate control) as illustrated below:

1703189285_DislocatedScrollbar.png.f093d45e0b0da3dcd46c5c01fe676a76.png

Sure enough, this String control is inaccessible at runtime.

Unless I am missing something, that's a caveat users may want to consider before embarking into complex control design...

 
Link to comment

True with any controls.  Just make sure the z-order makes sense.  In your case you probably want the string control in front of the cluster holding the scrollbar, instead of having the string in the cluster with it. 

Link to comment

Sure, but there are cases like this (vertical "scrollbar" over horizontal "scrollbar", but this works also for the opposite situation):

738367886_Overlapping(empty)real-estate.png.208f166c18eed47a34f482f708bff22e.png

You can "interlace" two XY Graphs and move their "accessory" panels and not have any problems using either one, no matter which one is on top or in the back:

1798171932_InterlacedXYGraphs.png.69405c1f7abf8b136aec1c8d0e9bfaf2.png

 

It's just something to keep in mind before being bitten late in the development process.

Link to comment

Well I guess you could pass the reference to each button and the slider individually into the constructor VI without them being in the cluster.  You would have to add the references to the QControl class through a manual bundle in the constructor and edit the Event Handler accordingly. 

If that is the case I would recommend starting a new QControl and inheriting from Slider and then passing in the slider reference as normal. Then pass the references for the buttons as extra inputs with manual bundle.  That way each button and slider can be positioned separately.

Link to comment

I'm way above my head here, but are you saying that in principle the "clustering" of multiple control is just a convenience trick or is that bringing advantages (such as access to class properties via property nodes) that would be lost otherwise (defining a facade with multiple controls NOT bundled into a cluster)?

Of course, what's missing for this to be even practical, is more flexible way of grouping objects in LabVIEW (that is, one that allows moving things within a group).

Just to put my questions in context, I have developed a simple (well, relatively) way of adding a tip strip to graphs so that long plot names can be read without having the legend size explode. I was  contemplating migrating it to a QControl, but the layout of a Graph (due to its accessory panels) can be quite random, and if everything (graph and tip strip) is put into a cluster, the problem I was raising above would potentially ruin the day in some UI cases.

 

Link to comment

For my particular (ultra-simple) application, that would be an overkill, as I already handle that with a custom-made handler.

For the general case, that could certainly be a way to handle multi-component objects.

But my question is whether what @The Q is describing above is something that can be done within the wizard (picking one of the controls of the multi-component control as the starting class and doing the weight lifting to add the references to the other controls).

Link to comment
On 4/23/2019 at 6:23 AM, shoneill said:

You might want to get in touch with Wiebe for that....

just forgot to add that my comment about the lack of flexible grouping in LV referred to edit time behavior, which Wiebe's tool doesn't cover.

Basically, we need to be able to group objects so as to be able to grab them and move them around as a whole (at edit time), but also be able to grab one inside the group and reposition it (ability which most graphical software provide; not sure about NXG). Essentially what one can do for members of a cluster, without the drawback I was illustrating above.

Link to comment
1 hour ago, X___ said:

just forgot to add that my comment about the lack of flexible grouping in LV referred to edit time behavior, which Wiebe's tool doesn't cover.

Basically, we need to be able to group objects so as to be able to grab them and move them around as a whole (at edit time), but also be able to grab one inside the group and reposition it (ability which most graphical software provide; not sure about NXG). Essentially what one can do for members of a cluster, without the drawback I was illustrating above.

Um. Can't we?

If you select the objects on the front panel and press the "Reorder" button in the toolbar. There is a "Group" option. That will group the selected controls and you can move them around as one unit.

Maybe I'm just misunderstanding what you are asking.

Edited by ShaunR
Link to comment
1 hour ago, ShaunR said:

Um. Can't we?

If you select the objects on the front panel and press the "Reorder" button in the toolbar. There is a "Group" option. That will group the selected controls and you can move them around as one unit.

Maybe I'm just misunderstanding what you are asking.

Sure. But then you cannot move the elements independently. Unless you ungroup, move, regroup.

A modular object (such as a Graph) should be moveable as a whole, but its components should ideally be moveable individually. I have no idea how NI does that with their native controls, but this is obviously feasible. This is for instance something that was completely destroyed in XControls (an XControlled-Graph is frozen solid if I recall my now forgotten attempts to expand Graphs, unless you rebuild the whole independent component grabing and moving, as I was told by NI).

Link to comment
On 4/23/2019 at 5:12 PM, X___ said:

But my question is whether what @The Q is describing above is something that can be done within the wizard (picking one of the controls of the multi-component control as the starting class and doing the weight lifting to add the references to the other controls

@X___,

Sorry, other than what @ShaunR is suggesting, there really isn't a way to group like that at edit time.

What I was suggesting was how to control multiple controls in a QControl, which would be run-time behavior.

Link to comment
18 hours ago, X___ said:

Sure. But then you cannot move the elements independently. Unless you ungroup, move, regroup.

A modular object (such as a Graph) should be moveable as a whole, but its components should ideally be moveable individually. I have no idea how NI does that with their native controls, but this is obviously feasible. This is for instance something that was completely destroyed in XControls (an XControlled-Graph is frozen solid if I recall my now forgotten attempts to expand Graphs, unless you rebuild the whole independent component grabing and moving, as I was told by NI).

Something can't be in a peer group and not be in a peer group at the same time. This is how the LV diagram "Group" works.

What NI has is a parent-child grouping which is something different.  Not saying this couldn't be an interesting idea, just that it's not comparing apples with apples.

Link to comment
On 4/17/2019 at 7:41 PM, X___ said:

My understanding is that if I want to add a method to a QControl (say, "Add Element"), I need to provide a VI which the user needs to use wherever they want to call that method, rather than having the convenience of using an Invoke Node and connecting the QControl refnum to it (which would be neat, as this would provide a built-in list of methods). Do I get the idea right?

LV 2019 augments the right-click menus for class wires/terminals to provide a method list you can drop, which should alleviate this issue. I found a way to make the right-click menu plug-in able to add the graphical palette menus and then built a right-click plug-in that builds the method palette on the fly if the class doesn't already have its own default palette.

  • Like 2
Link to comment
19 hours ago, X___ said:

I have no idea how NI does that with their native controls, but this is obviously feasible.

With our built-in controls, the problem is solved at the moment of selection. If the main part is selected (e.g. the LED part of a Boolean control) then all of the related parts are also selected. If a secondary part is selected (e.g. the label of the Boolean control) then only that part is selected. Thereafter, the rules of the selection list work as normal -- when you drag one item in a selection, all selected items move with it. This is what allows you to select the label of several different controls at once.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.