Jump to content

JackDunaway

Members
  • Posts

    364
  • Joined

  • Last visited

  • Days Won

    40

Posts posted by JackDunaway

  1. "Seriously.js is a real-time, node-based video compositor for the web" (from the readme on the GitHub repo), and might be of general interest to those into Machine Vision, Imaging, and especially OK GO. How to work this demo: 1) play the video, 2) toggle processing styles with buttons on the bottom of the video, 3) be amazed: http://seriouslyjs.org/

     

    (Lyrics are colorful, perhaps not appropriate for blaring aloud at work or with your impressionable little ones -- turn the volume low, and the video is quite fun for the kids!)

     

    Raw video still, filmed in front of a green screen:

    post-17237-0-09395400-1370531449.png

     

    British Invasion filter, applied real-time with Javascript in your browser:

    post-17237-0-90267900-1370531479.png

     

    (Sorry IE; this demo works in Chrome/Firefox)

  2. After a day of playing with the XTab control, I can say that is looks promising but is too buggy for real world use at this point.  I hope the author continues to improve it.  In the meantime, I would recommend you look elsewhere for a tab solution.

     

    Stay tuned -- perhaps some of these concerns are addressed in unreleased versions and a nudge is all it takes....  :)

  3. Slightly high-jacking this topic, re-sizing items in a tab control in a way that is similar to the resizing of panes is a feature I've been looking for for a while.  To give you an example, for many of my GUIs I have a graph in a tab control, and have the raw data table in another tab.  If tab controls could resize their contents like a pane, my graph and table could automatically re-size with my window (I would put the tab control in a pane and set it to Fit Control to Pane.  For this reason I've put off converting many of my GUIs to being resizable using splitter bars.

    The only way I've been able to do this is by cheating.  I would have a horizontal splitter with only the tabs in the top pane, and the contents of the tabs in the lower pane.

     

    Highest recommendations for checking out XTab by Saphir, available for download through the LabVIEW Tools Network using VIPM.

     

    * It handles resizing of tab contents no prob, since the tab contents are just a VI

    * You can add/remove pages programmatically

    * You can re-order and even pop out tabs into new windows (à la Chrome browser)

    * The toolkit is free

     

    Here's a screencast that shows XTab in action: http://www.dailymotion.com/video/xmtmvf_topaze-tab-navigation_tech#.Ua4DsGRgZyE

    More info on the community: https://decibel.ni.com/content/docs/DOC-21668

  4. Still need an easy way to get those scroll bars back and this still needs to be a VI Server setting!

     

    There are four ways to turns on scroll bars:

     

    1. VI Properties (CTRL+I) >> Window Appearance >> Show vertical/horizontal scroll bar

     

    post-17237-0-07561100-1370334912.png

     

    2. Context Menu of an existing scroll bar:

     

    post-17237-0-10424800-1370334993.png

     

    3. Context Menu of a splitter between two panes:

     

    post-17237-0-85949000-1370335058_thumb.p

     

    4. And as a property node of Pane (also shown, a lesser known fact -- you can show, customize, then hide the Labels on both Splitters and Panes to be more descriptive than Pane, Pane 2, Pane 3, Pane 4...) A mistake I oftentimes make is to search for Pane settings under the Panel class -- Class Browser (CTRL+Shift+B) helps remind.

     

    post-17237-0-44243000-1370335369_thumb.p

  5. My recommendation is to avoid the VI property "Scale all objects on front panel as the window resizes." It almost never does what you want.

     

    For clarity -- and don't let me put words in your mouth! -- but for clarity i think you mean to avoid "Scale all Objects with Pane" (because, it almost never does what you want) -- and you typically *always* want to enable "Scale Objects While Resizing" because hardware is more capable today than it was in the 1900's. :-)

     

    This is typically the setting you'll want for Panes:

     

    post-17237-0-55812600-1370310100.png

    • Like 2
  6. I have been trying to get the VI within a sub panel to re-size dynamically (while the users is actively performing a re-size).

    I have programmed the VI in the sub panel to do real time re-sizing but I cannot get the sub panel to re-size actively when the user re-sizes the front panel that owns the sub panel.  Even if you set the 'Scale all objects on the front panel as the window re-sizes' VI property, the re-size does not happen until the user stops the re-size action.  It will not do it dynamically.

    My solution was to create a vertical and horizontal splitter, then place my sub panel to the right and below the splitters.  I could then get it to resize the sub panel as the user performs the resize action.

     

     

    The whole splitter business shouldn't even be necessary -- if I understand your original request, the features you describe are native. (this demo uses LabVIEW2012 12.0.1F1 32-bit)

     

    Inspect settings on the two VIs attached (Container.vi and Containee.vi -- save them in the same directory) and check the 25sec screencast below to see if it demonstrates the behavior you're trying to achieve:

     

    http://screencast.com/t/84aalWkNw

    Containee.vi

    Container.vi

    • Like 1
  7. Here's my question: If each plug-in is defined by a top-level VI, is it good practice to use the VI Title and the VI Description as the place for the plug-in author to define the menu text and the help text?

     

    I'm currently using precisely this technique (private App method and all) for a commercial product. It has worked great in practice for end-user plugin devs.

     

    The key is approachability for plug-in developers. A "safer" but significantly less approachable alternative is to write this metadata as Tags to the VI. (I investigated and rejected using Tags for this task; it's conceptually far easier to explain Title/Description editing, and does not require custom tooling/APIs to edit data that should be readily editable by devs).

     

    Lowering barriers for plug-in development has far more value than eschewing "the dirty feeling you get from overloading the meaning of fields". Go for it.

  8. The BD is rendered with the Web Safe color palette. Mapping from your 24-bit icon editor to this Web Safe palette appears to be based on RGB least squares rather than an HSV match; for this reason, it's probably best to attempt to design your icons starting with the Web Safe palette, because the matching for dark shades often misses the mark for Hue (as shown in your first post).

     

    This also means converting bitmaps to the Web Safe palette prior to importing into the Icon Editor, since the color matching routine of your image editor is likely to produce better results.

     

    You're in for a treat if you're into pastels, with this palette.

     

    (image search for the Web Safe palette: https://www.google.com/search?q=web+safe+palette&tbm=isch)

  9. LabVIEW's HTTPS support uses most likely OpenSSL for the SSL implementation. OpenSSL comes with it's own list of Root CA and does AFAIK not try to access any platform specific CA stores. As such the only options for self signed server CAs is to either skip the verification of the server certificate or to try to import the self signed certificate into the session. I think the SSL.vi or Config SSL.vi should allow to do that.

     

    Everything works now, here's what I've learned: LabVIEW is using a list of trusted authorities from the file: "%ProgramFiles%National InstrumentsSharednicurlca-bundle.crt"

     

    If your Certificate Signing Authority is not in that list, you will receive Error 363507 - LabVIEW could not verify the authenticity of the server.

     

    In order to avoid this error, either find a new Certificate Signing Authority, or you can specify your own Trusted Certificate Authorities using ConfigSSL.vi (shown in the screenshot below). When you distribute your application, ensure to include this file with the distributable.

     

    When you download your certificate from your CA, through the management console you can probably also download the Root Certificate of the CA -- this is the file that you wire into CA certificate file of ConfigSSL.vi. (This file might even be included as a zipped certificate bundle when you download your cert.) This file will look like the following if opened in a text editor:

     

     

    -----BEGIN CERTIFICATE-----
    MIIFB...LinesAndLinesOfBase64....==
    -----END CERTIFICATE-----

     

    -----BEGIN CERTIFICATE-----
    MIIED...LinesAndLinesOfBase64....==
    -----END CERTIFICATE-----
     

    post-17237-0-26993500-1368221835.png

     

    • Like 2
  10. Here is my position on the topic:

    Scripting is out there and many people are using it to create some amazing tools for assisting LabVIEW development and automating various tasks. I'd like for NI to give us its blessing to create such tools, so that we don't feel like renegade outlaws and can feel comfortable sharing them with others. And, I'd love for NI staff to be able to contribute to the technical discussions around scripting -- the current position from NI seems to be that it doesn't exist. Bottom line, machine readable and writable source code is a prerequisite for creating software engineering tools. And, it would be great for NI to empower the LabVIEW community to create better software engineering tools for LabVIEW. Bottom line: I think that it would be of great value to let the LabVIEW ecosystem create innovative features and tools on the LabVIEW platform. It's a win-win situation.

     

    post-17-1232503776.png?width=400

     

     

    This post is quoted during Jeff Meisel's keynote presentation (@9:39 in the video).

     

    Jeff emphasizes the importance of NI collaborating with the community to build key API access into the LabVIEW platform, and how the efforts of community leaders have paid off in the past several years.

     

    Link to the presentation: http://www.infoq.com/presentations/National-Instruments-API

  11. Upgrade Code, Product Code, and Package Code are three terminologies used by Microsoft Windows Installer (MSI) to identify the three dependencies your application installer is missing -- read more about what they mean here: http://blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx (There are many explanations, this is just one good one)

     

    It sounds like you're on the right track using virtual virgin machines to test your distributable. Quick question -- if you install the distributable on your dev machine, will it run without the three errors about missing dependencies? I'm guessing the answer is yes.

     

    In this case, you can query your dev machine for those three Upgrade Codes to see if they exist as installed products in the registry. This reverse-lookup should point you to the actual name of the product needed, not just a GUID.

     

    Another option is inspection of the MSI (google "free MSI editor"). Using a tool like this, sleuthing for the three Upgrade Codes likely reveals the name of the dependent MSIs.

     

     

    Finally, I would recommend inverting your distribution building process. First, just build an installer with nothing but your application and the LV RTE, and install this on a staging machine. Of course it will fail, but then manually run app-specific driver installers on the staging machine, until you have finally satisfied dependencies of the application. This technique is way more agile than including dependencies into your installer to test, since you don't have to rebuild each iteration.

     

    (Full disclosure -- my company provides products and services with a laser-focus on LabVIEW application deployment)

    • Like 1
  12. Generally, I like what you're suggesting.

     

    I don't have a particular opinion on Variant behavior when deserializing/validating, but I strongly agree for other stringly-typed composite data structures (XML, JSON...).

     

    The reason I don't have a strong opinion about Variant behavior is we're typically talking about intra-application communication; the reason this is so important for XML/JSON is that now we're talking about interoperability beyond an application instance, where strict validation is oftentimes more of a hindrance than an asset.

     

    For those participating to the LabVIEW 2013 Beta, there's a discussion on that forum about this topic -- search for "validation on deserialization" and weigh in.

  13. I'm drooling over this slick physics simulation of a cloth/fishnet curtain in JavaScript. You can interact with the kinematics of the canvas and tweak the source code live in your browser: http://codepen.io/stuffit/pen/KrAwx

     

    Left mouse button dragging moves the curtain; right mouse button dragging cuts through the curtain.

     

    The power and simplicity of the software engineering tech stack shown here is.... beautiful. Inspiring.

     

    (tested in Chrome and IE10; YMMV for <IE10)

     

    post-17237-0-20543700-1366739704.png

    • Like 1
  14. Okay that makes me want to ask a question.  I was using a class in a dialog subVI.  The class value is passed into the subVI to be modified by the user in the pop-up.  I had based my dialog on the JKI string based state machine which has a data initialize state in the while loop.  When I placed my input class control inside the loop and my output class control outside the loop, the VI broke and the error was that re-entrant class couldnot be used that way.  When I got to looking my data accessors which were programmatically created by the IDE were set to re-entrant.  I didn't expect that to be the default behavior.

     

    This is with a less than 2 week old install of LV2012 (not sp1) on a virgin machine.  Thoughts?

     

    (emphasis added above)

     

    Maybe, you're confusing Reentrancy with Dynamic Dispatch?

     

    A Dynamic Dispatch method requires class control input and output to be on the outermost diagram, and will generate the following compiler error if either is placed inside a structure: "Dynamic front panel input and output terminals cannot be placed inside structures. This ensures that they will be read from and written to exactly once so that LabVIEW can guarantee the run-time type safety of the diagram. An exception to this rule is made if the dynamic input terminal is inside a structure node and the VI has zero dynamic output terminals. In that case, the VI is not broken."

  15. Over the past 5 years, each year, approximately:

     

    B -> C -> A -> B -> B

     

    tl;dr -- does not solve sufficiently painful problems efficiently enough.

     

    A few inconveniences that come to mind:

    1. Inability to designate an XControl as a view of an LVOOP class
    2. Inability to expose VI Server API of composed elements, other than through a naked ref getter on the XControl API, or re-implementing a wrapper
    3. Inability to override VI Server API methods/properties of composed elements
    4. Handler in Façade does not actively handle incoming User Events (just VI Server events)
    5. It feels like they were both released and EOL'd the same day (this is just perception, yet it plays a substantial role considering ROI in this technology)

    They're still super cool, and I would not recommend against developing an XControl. (I've developed perhaps a dozen?) It's just one of those tools in the toolbox that's not rusty, yet not often reached for.

    • Like 1
  16. Quick question:  When you say Must Implement, are you using it to mean Must Call or Must Invoke?

     

    In some languages, implements is a keyword associated with Interfaces to indicate the class contains the source code to execute the methods defined by the Interface.  In other words, putting a must implement requirement on a vi implies (to me) that the developer of the target vi has to write the source code that does some bit of arbitrary functionality.  Based on your post above, it seems like you really want to make sure the target vi developer calls some other arbitrary vi on the block diagram of the target vi.  (Must Invoke.)  Is that accurate?

     

    No.

     

    Just as Dynamic Dispatch has 'Must Override' and 'Must Call Parent', a static method could specify 'Must Implement' and 'Must Call Parent'.

     

    Note that 'Must Call Parent' has essentially the same semantics for Static and Dynamic Dispatch. Yet 'Must Implement' might be loosely analogous to a less-stringent 'Must Override'.

     

    Sorry for muddying the waters between 'Must Implement' and 'Must Call Parent' -- i see these going hand in hand in the context of, e.g., the LapDog.Messaging ctors.

  17. Could you push the mask down the stack from the UI layer down into the logic layer? Like, before writing to "masked sensor data" colorbox array indicator, replace masked values in a for loop? Or are there specific reasons to keep the mask at the UI layer?

  18. If you need different connector panes on the input terminals, what you're usually asking for is double dispatching, or the ability to dynamically choose at runtime which vi is called based on two input types instead of just one.

     

    Nope; nowhere near what i was originally looking for.  :lol: The opposite, rather. Static methods, called by an application that statically constructs a child class. It's all very static on purpose -- no dynamic run-time decisions, because the problem domain does not call for dynamic or double dispatching or dependency injection or any other flavor of dynamic run-time ability.

     

    Taking this into the LapDog.Messaging domain:

     

    Consider a process that needs to send a string to another process; it's going to construct the message using LapDog.Messaging.v2.NativeTypes.lvlib:StringMessage.lvclass:Create StringMessage.vi. This problem domain would never require run-time selection of another ctor, whether through dynamic dispatch, double dispatch, etc. -- because the caller needs to send a string.

     

    Now, taking a look at all of the message ctors in LapDog.Messaging.v2.NativeTypes.lvlib, they all call RenameMessage.vi. -- yet I would suggest it's better if they called Message.lvclass:Create Message.vi, their "prototype", the ctor that exists in the parent -- bear with me; this is not a criticism, it's what I see as a great candidate for "Must Implement":

     

    post-17237-0-62497900-1364950888_thumb.p

     

     

    For a moment, consider the calling of this particular function essential to the construction of a Message object for it to be viable within the framework. Further, even though this is just one function, consider it  representative of "the collection of all the essential functions" that must be called in the construction of a Message object. (One very real upgrade we might want to perform in this case is timestamping the message, and we would not want to go into each of the concrete implementations to ensure they call Apply Timestamp.vi)

     

    What I'm suggesting is that each of the concrete Message ctors calls Message.lvclass:Create Message.vi instead of calling Message.lvclass:RenameMessage.vi. With this strategy, we allow the parent to templatize the sequence of essential constructor functions. If Message.lvclass were able to specify 'Must Implement' and 'Must Call Parent Implementation', we formalize the definition of Create StringMessage.vi as implementing -- which is discretely different but having traits in common with overriding -- the functionality of the parent class method Create Message.vi. Further, we guarantee the parent method called in order to perform the essential tasks that construct a well-formed message object.

     

    And we get the unique ConPanes we desire in the concrete implementing method.

     

    I've mentioned previously (post #13), and AQ brought up again (post #132It may not be proper to even specify the function name (i.e. one might have "Write Boolean.vi" and another have "Write Double.vi")), that this "Must Implement" feature is gated by an inheritance relationship defined through a GUID private to the class rather than filenaming conventions of the method; this is evidenced with the desire for StringMessage.lvclass:Create StringMessage.vi to implement Message.lvclass:Create Message.vi yet not have its same filename.

     

    With these features and contracts in place, if a developer decides to subclass LapDog.Messaging.v2.lvlib:Message.lvclass by creating myArbitraryStructureMessage.lvclass, we can be guaranteed that it both implements and calls the parent implementation of the essential ctor Message.lvclass:Create Message.vi, yet is able to give it any name deemed fit with any conpane necessary to construct the specific object.

     

    The prime motivation here is inverting inversion of control; would one call this taking control? :D It's an exercise acknowledging that statically composed applications, when the problem domain allows, is superior to dynamically composed systems, in terms of ease of development and troubleshooting and maintenance. I think it would be handy to have language features such as 'Must Implement' that acknowledge the merits of subclassing without necessarily leveraging dynamic run-time abilities.

     

    Thoughts?

×
×
  • Create New...

Important Information

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