Jump to content

[LVTN] JGCODE Preferences Dialog Library


jgcode

Recommended Posts

index.php?app=downloads&module=display&section=screenshot&id=204

Name: JGCODE Preferences Dialog Library

Submitter: jgcode

Submitted: 30 Jan 2012

File Updated: 11 Feb 2012

Category: LabVIEW Tools Network Certified

LabVIEW Version: 2009

License Type: BSD (Most common)

This package is Open Source

The Library contains supporting VIs that integrate with the LabVIEW Preferences Dialog to simplify file IO using OpenG VIs.

Thanks to Yair/tst for help with refactoring :)

Installation locations:

<templates>\JGCODE\Preferences Page Dialog.vit - template for creating new pages

<examples>\JGCODE\preferences_dialog - example application and instructions

The following VIs are called dynamically so that linking is maintained:

<resource>\dialog\PreferencesDialog\PreferenceDialog.vi

<resource>\dialog\PreferencesDialog\optionsFrame_GetErrorReportQueue.vi

<resource>\dialog\PreferencesDialog\optionsFrame_GetPageReadyNotifier.vi

<resource>\dialog\PreferencesDialog\PreferencePages\SharedPrefPage_SubVIs\SetCursorBusy.vi

<resource>\dialog\PreferencesDialog\PreferencePages\SharedPrefPage_SubVIs\SetCursorNormal.vi

<resource>\dialog\PreferencesDialog\PreferencePages\SharedPrefPage_SubVIs\SetOkDisable.vi

<resource>\dialog\PreferencesDialog\PreferencePages\SharedPrefPage_SubVIs\SetOkEnable.vi

<resource>\dialog\PreferencesDialog\PreferencePages\SharedPrefPage_SubVIs\SetPanelCloseStateDisable.vi

<resource>\dialog\PreferencesDialog\PreferencePages\SharedPrefPage_SubVIs\SetPanelCloseStateEnable.vi

This Package depends on these other packages:

oglib_appcontrol >= 4.1.0.7

oglib_array >= 4.1.0.13

oglib_file >= 4.0.0.20

oglib_variantconfig >= 4.0.0.5

Click here to download this file

  • Like 2
Link to comment

In the first video you mention that the framework code is duplicated in every VI because of problems with dynamically registering events in subVIs. Can you go into any more detail on that? Maybe it's something which can be resolved.

Yer that would be nice.

Supporting the Pane: Pane Size and the Panel Close? events with dynamic registration (as would be the case if it was made into a re-entrant, reusable engine) means the FP needs to be in memory however, there is no (well, not that I know of as it's all locked) feedback as to the state of the FP as it is inserted and removed from the subpanel.

If there was then you could un/register for those events correctly.

The Panel Close probably doesn't matter - it was in <resource> template so I included it - because of the OpenG VIs, there is no real great need to test each Page as it is the same code.

The Pane: Pane Size is handy to show or hide the scrollbars - so this is required.

When it is statically registered I the above concerns can be ignored.

It would be much nicer code if it was refactored into an engine - which is what I was hoping for.

The two workarounds off the top of my head are:

  • A simple event loop on the Page listening for the Pane Resize and passing it to the engine - but that would require 2 way comms (msg + to shutdown loop)
  • Possibly polling could work - but is not that great sounding

Hopefully there is a fix someone can suggest :)

Link to comment

If the framework only runs the page VIs when they are put into the SP (and I'm assuming that's the case), then maybe you can try a trick - I'm assuming the Page Ready Notifier you send at the end of the Setup state tells the framework that you're done and you're ready to put the VI into the SP. What if before you do that, you open the FP (maybe hidden), then register the event, then close the FP again and only then send the notification?

  • Like 1
Link to comment

If the framework only runs the page VIs when they are put into the SP (and I'm assuming that's the case), then maybe you can try a trick - I'm assuming the Page Ready Notifier you send at the end of the Setup state tells the framework that you're done and you're ready to put the VI into the SP. What if before you do that, you open the FP (maybe hidden), then register the event, then close the FP again and only then send the notification?

The only reason I didn't try that is I assumed that taking the FP out of memory would invalidate those events?

I will give it a go.

Here is the Dual Loop approach - it works.

All the meat is in the engine, the stuff on the Page is pretty basic (in comparison).

post-10325-0-04982100-1327847694_thumb.p

<edit>

Sweet!!

It works - great suggestion :worshippy:

The code now looks how I originally intended - reusable!

post-10325-0-38016300-1327848207_thumb.p

</edit>

  • Like 1
Link to comment

The This VI reference is probably also redundant - you can get it inside the subVI.

Ditto with the get config file.

This is sweet. Huge improvement on the original. Nice work.

One question. Does it need the openG tools intalled on the users machine? (i.e what about distribution of the developers toolkit that these settings apply too)

Edited by ShaunR
Link to comment

Ditto with the get config file

No as that will be application specific - so you want to pass that in as an argument.

.

One question. Does it need the openG tools intalled on the users machine?

Yes, as per the VIPM info screen in the OP there are some dependent packages.

I originally considered including the OpenG VIs in with the dist, I could still do this, but normally don't for APIs (as opposed to tools).

.

(i.e what about distribution of the developers toolkit that these settings apply too)

Not sure what you are referring to here - can you go into detail? Thx.

Awesome!

Thanks Jon. I took a look at the framework when it was first "released" in 2010(?), but there was too much to do to get it working nicely.

Glad you like it too!

Aside: does any body else use the MGI read/write VIs instead of the OpenG ones? I switched to the MGI ones a few years ago (for some reason that eludes me right now).

I went back and forth with these and OpenG and I pretty much used OpenG exclusively for last couple of years.

MGI is faster but they write as a string blob (looks like ini, but behaves different), OpenG is "slower" but they write as keys - I use quotes because for small data speed is not an issue at all.

If you have a clustersarous then yes, it will be slower.

The other thing is you are not streaming data to disk with these things, so the speed difference has never been an issue for me.

The biggest advantage for me is that you can add, leave, delete etc... data per key - MGI removes the entire blob.

One use case where this is advantageous is in supporting different versions of files, and having keys persist.

The other (which is important to me) is if you have a class and it persists its data to disk, you can create a Child class and write the additional data (parent + child) to the same section (assuming that data has different key names), with MGI you cannot, it will overrite the entire section.

Link to comment

Ok looks awesome here is the new package with the above fixes.

Very simple to create and maintain a Page - just drop your control and indicators on the BD

The Page Template

post-10325-0-87269100-1327853802_thumb.p

The Page Engine (reuse subVI)

post-10325-0-51982700-1327852863_thumb.p

The new Package

post-10325-0-51250700-1327853805_thumb.p

jgcode_lib_preferences_dialog-1.0.0.16.vip

I have also exposed the Filter Names (optional) input so you can filter out controls/indicator that you may be using for screen effects etc...

This video (no sound) shows it in action (obviously you wouldn't not save a piece of data, but you get the point) :)

<!-- copy and paste. Modify height and width if desired. --> <object id="scPlayer" width="1275" height="733" type="application/x-shockwave-flash" data="http://content.screencast.com/users/jgcode/folders/LabVIEW/media/2973dfad-70cd-453a-8ad2-5e795d0ced7f/jingswfplayer.swf" > <param name="movie" value="http://content.screencast.com/users/jgcode/folders/LabVIEW/media/2973dfad-70cd-453a-8ad2-5e795d0ced7f/jingswfplayer.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#FFFFFF" /> <param name="flashVars" value="thumb=http://content.screencast.com/users/jgcode/folders/LabVIEW/media/2973dfad-70cd-453a-8ad2-5e795d0ced7f/FirstFrame.jpg&containerwidth=1275&containerheight=733&content=http://content.screencast.com/users/jgcode/folders/LabVIEW/media/2973dfad-70cd-453a-8ad2-5e795d0ced7f/Preferences%20Dialog%203.swf&blurover=false" /> <param name="allowFullScreen" value="true" /> <param name="scale" value="showall" /> <param name="allowScriptAccess" value="always" /> <param name="base" value="http://content.screencast.com/users/jgcode/folders/LabVIEW/media/2973dfad-70cd-453a-8ad2-5e795d0ced7f/" /> Unable to display content. Adobe Flash is required.</object>

Link to comment

I have tried a simple app, and when I run it my new preference page gets run as its own VI and not within a subpanel of the Preferences framework, as shown in pic.

It seems to run hidden as well (although sometimes seems to open). Actually once I have had the Preferences framework VI open, but then got error (1144?) saying cannot insert VI into subpanel as it is already open. I think this occurs after running my main VI when the preference page FP was open but not running.

Any ideas what I am doing wrong? The preference page is just opened from a template and then saved.

Hi Neil

As the Framework inserts Pages into a subpanel you cannot have the Page FP in memory as this will cause as error

This is standard with using subpanels - so try closing the Page then running the Dialog VI and see if you still get issues.

Are you using the latest version of the package - 1.0.0.16?

I have that version working fine here and it also includes some niceties for running the page by itself for debugging.

Although that should be needed as all you have to do is drag and drop control onto the front panel now - yay! :P.

As for anything else, I am not sure - do you want to post your code, I am happy to have a go running it?

Cheers!

Link to comment

Yes, as per the VIPM info screen in the OP there are some dependent packages.

Thats a pity since I don't use VIPM or the tools:(

Not sure what you are referring to here - can you go into detail? Thx.

Nevermind. I think I got the wrong end of the stick. I thought it was adding a page to the LabVIEW preferences (from the LabVIEW toolbar).

Still sweet though.

Link to comment

index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=6273

One additional comment: I'm personally not a fan of providing the name of something in more than one place. If ignoring controls on the front panel is common (and I'm guessing it actually isn't very common), then I would prefer if the template included a for loop which iterates over every control reference given to it and extracts its Label.Text property to use as the filtering array.

Of course, since the default is to have no control, this code could be in a disable structure, or you could feed it one of the built-in controls, which I assume is meaningless, since it filters them anyway.

Link to comment

What I did with PassaMak was that the engine would exclude any controls where the caption wasn't visible (it too used the label as a tag). The user then just showed the label instead of the caption for that "ignored" control/indicator. But as Yair said, it isn't common and it doesn't really make any difference if you do add all controls since who expects a control on a preferences dialogue not to remember what you put in it?

Link to comment

One additional comment: I'm personally not a fan of providing the name of something in more than one place. If ignoring controls on the front panel is common (and I'm guessing it actually isn't very common), then I would prefer if the template included a for loop which iterates over every control reference given to it and extracts its Label.Text property to use as the filtering array.

Of course, since the default is to have no control, this code could be in a disable structure, or you could feed it one of the built-in controls, which I assume is meaningless, since it filters them anyway.

The interface is a string array, so the user can populate it however they want (I would do it like the above too).

However, I am happy with the template as this is really an edge use case I exposed.

I actually use it to filter the default template controls etc... (otherwise LabVIEW crashed when it tried to write the tag refs to disk using OpenG :)) but this is all done internally in the engine.

...it doesn't really make any difference if you do add all controls since who expects a control on a preferences dialogue not to remember what you put in it?

One example I can think of is that it may have to do with localisation?

Using an Indicator to display a piece of text (e.g. like a decoration/title that's constant) as opposed to using Free Text.

Link to comment

Jon,

Dummy project is attached. I recreated it this evening.

In the JG CODE pallette there are only three VIs right? I downloaded the latest package (.20?), but cannot find any examples.

Am I doing something stupid?

Thanks I will have a look

The examples should be at the location described in the VIPM Info (screenshot above) - are they not there?

Now with the engine encapsulated there are only two main VIs you will use, plus I included the dynamic call to the Pref Dialog in case someone wanted to make their own wrapper.

Link to comment

Hi Neil

The problem you are experiencing is that you are not providing a valid config path/location.

I have just used a meaningless placeholder in the template and running it generates any error which is causing the issue.

post-10325-0-27747000-1327963708.png

Nevertheless, I will look into handling this case better.

Thanks for posting the code.

Link to comment

I have had a look at this - I can definitely make improvements regarding errors.

However, the Framework pops up errors on close, so regardless of where the error occurs in the Engine's state machine, the FP of the Page is still going to show (when I do the fix).

In the case of the invalid config with a basic Page (i.e. one generated from a template) it means the user will waste time changing data, then it won't save, then they will get an error at the end.

So I recommend prechecking that information before launching the dialog.

This is pretty much the only error due to external reasons that the engine will have to worry about (file io).

I could add it to the Preferences Dialog.vi, in that it could perform certain checks and if valid then launch dialog, if not then create and error.

Looking at the OpenG Valid Path.vi that would have passed the file path as ok in the above example so that doesn't really help - so I will need to look at this further.

Also I envisage that you could run the Engine in parallel with other code if you wanted to do stuff other than just save data to disk e.g. validate data etc...

You could do something that would look similar to in terms of parallelism (ignore the user event ref into the engine, the rendezvous etc... this image comes from a different context, but it was quick to post):

post-10325-0-04982100-1327847694_thumb.png

In this case you could handle the errors at the time they occur relative to that screen etc... in your own code

Link to comment

Ok v21 is up in the LAVA-CR

I updated the error handling in the Engine based on the feedback above in an attempt to make it more robust.

Additionally I added a Precheck Config File Path VI as a utility VI (and exposed it in the palette)

You can use your own, but it should eliminate most issues:

post-10325-0-25395600-1328004176_thumb.p

The VI ensures the path is not empty; is not relative; and the folder where it is gonna be, has been created:

post-10325-0-87535300-1328004173_thumb.p

Additionally I added the suggest method to filter to the example and removed the string array altogether from the template.vit.

post-10325-0-51159200-1328004167_thumb.p

My next task is to see if I can get this to build (rather than just be a tool in the IDE) - and handle relinking issues to <resource>.

I have added provisions in this code for this - but I contact the relevant authorities to see what I can do :)

Link to comment

:thumbup1::beer_mug:

Great works, thanks for pointing out the PEBKAC error :-)

Installed the new version, and the examples are there also.

Quite keen to give this a whirl in my next application, so if you need any help testing it out just let me know.

Thanks!

I appreciate the (testing) gesture - I will be sure to hit you up!

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.