sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [Code] Material.names to Webdialog.

    Scheduled Pinned Locked Moved Developers' Forum
    55 Posts 4 Posters 686 Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • thomthomT Offline
      thomthom
      last edited by

      @dan rathbun said:

      JSON.parse( string )

      Support chart: http://caniuse.com/json
      All the way back to IE8. (I'd not worry about older IE versions any more - no unless you're doing commercial development and know a significant share of your potential users are stuck with the damned filth.)

      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • Dan RathbunD Offline
        Dan Rathbun
        last edited by

        @thomthom said:

        So, unless you are sending crazy amount of data, hundreds of hundreds of megabyte then there should be no need to send the data via a hidden INPUT field. The INPUT field is only required when you send data from the WebDialog to Ruby.

        Just adding that ... technically... you do not actually send this large data to Ruby, instead you notify the Ruby-side that the data is ready, ... and then you read it from the Ruby-side using the dialog.get_element_value() method.

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          @thomthom said:

          Support chart: http://caniuse.com/json
          All the way back to IE8. (I'd not worry about older IE versions any more - no unless you're doing commercial development and know a significant share of your potential users are stuck with the damned filth.)

          OH! Nice page to bookmark!

          @unknownuser said:

          Note: Requires document to be in IE8+ standards mode to work in IE8.

          Lesson always use a %(#8000BF)[<DOCTYPE>] tag!

          If a customer must use IE7, you can always supply the JSON code. (There is an old topic where ThomThom and I discussed this JSON compatibility issue in detail.)

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            @dan rathbun said:

            @thomthom said:

            So, unless you are sending crazy amount of data, hundreds of hundreds of megabyte then there should be no need to send the data via a hidden INPUT field. The INPUT field is only required when you send data from the WebDialog to Ruby.

            Just adding that ... technically... you do not actually send this large data to Ruby, instead you notify the Ruby-side that the data is ready, ... and then you read it from the Ruby-side using the dialog.get_element_value() method.

            Yes, though what I was testing now was sending data from Ruby to WebDialog. I wasn't sure if there was a size limit there.

            Thomas Thomassen — SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by

              @dan rathbun said:

              Lesson always use a %(#8000BF)[<DOCTYPE>] tag!

              And META tag to trigger IE "edge" mode.

              Thomas Thomassen — SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                @thomthom said:

                Limit to the number of SCRIPT elements? I've not heard of that. Got a link to that thread?

                I cannot find it anymore as MS overhauled MSDN (and alot of content disappeared!)

                I may be confused with those loaded as resources via %(#8000BF)[<LINK>] tags:
                http://technullogy.wordpress.com/2010/03/05/internet-explorer-limits-css-and-script-resources-to-30/

                But I thought I saw a message at the bottom of one of the pages, that had to do with dynamically adding elements. I checked the %(#8000BF)[appendChild()] and %(#8000BF)[createElement()] pages, but there is little there now. (They cleaned house!)

                Anyway.. we are going off topic... if you clean them up, you'll never hit any limit if there is one.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • JD HillJ Offline
                  JD Hill
                  last edited by

                  Just a note on the original topic, it reminded me of once when a user sent me a problem scene that was screwing up my webdialog. The problem turned out being that one of his material names had a leading control character -- unit separator, which is not printable, but which you can enter into a SU material name by hitting ALT+031. I don't recall precisely in what way that was tripping things up, but thought I'd mention it anyway.

                  Developer - Bella Render

                  1 Reply Last reply Reply Quote 0
                  • jolranJ Offline
                    jolran
                    last edited by

                    OK! a lot of new stuff to digest. This forum is great.

                    It seems like I do a lot of things in almost the right way, or the wrong way. 😄

                    I wasent sure in wich direction there was a message size limit. So to defend against that I interpreted from some topic that you could insert arrays or such in hidden inputfields.
                    Sending layers, materials and component names it can easily become over 2000 characters. But in reality I won't reach that large amounts like during some tests here from Thomthom.

                    Dan.
                    JSON.parse( string ) sound like a better solution then. As long as I accept the user has IE8 +. For Mac that will not be an issue?
                    I believe that the user is probably working with SU on his or her major workstation which should be up do date.
                    Still have to figure out how to nest JSON or rather "hashes ready" for JSON in ruby first. Maybe use the method Thomthom already provided if it will work for that purpose.
                    There is bunch of info regarding " require 'json' ". But that module is not avilable in Sketchup I suppose..

                    Regarding "code cleanup after script" I saw that thread, and put Thomthoms JQ body-detach script in the "$doc.ready" function. Don't know if theres the right place to put it, but I sure did 😄
                    Maybe it should be done in a callback 😕

                    So just to make clear, I can forget about hidden inputfields and just send the data from SU exect.script to a global array in JS then? Like Thomthoms in this topic provided" materials.rb" do.

                    JD Hill. Thanks.

                    Sounds a bit like the issue I had before, I was also conserned about the end user going heywild on the keybord with names and such.
                    I suppose you havent had a look at Thomthoms script? Or maybe you are already doing something similar.
                    Well anyway, it's cleverly using 1 string stored as .text for display in webdialog and keeping the original SUmaterial.name stored as value. So one send the value to SU from JS.
                    In case of materials in SU, display.name is used, but I dont think there is nothing stopping you from doing some escaping on that string either, cause it wont affect the value. If one can put anything one like as value or not I havent got a clue..

                    1 Reply Last reply Reply Quote 0
                    • thomthomT Offline
                      thomthom
                      last edited by

                      @jolran said:

                      Regarding "code cleanup after script" I saw that thread, and put Thomthoms JQ body-detach script in the "$doc.ready" function. Don't know if theres the right place to put it, but I sure did 😄
                      Maybe it should be done in a callback 😕

                      What I did to simplify communication was to set up wrappers. I wrote a method that would allow me to send the function name and then a set of arbitrary arguments which would be automatically formatted into a string for execute_script.
                      http://www.thomthom.net/software/sketchup/tt_lib2/doc/TT/GUI/Window.html#call_script-instance_method
                      I can call webdialog.call_script( 'foobar', 'Hello', 5, [1,2,3] );
                      That takes care of formatting and escaping the string.
                      I even extended it a bit further so I'm actually calling a JS proxy function that calls the desired function and returns the return value back to Ruby. So I can do stuff like this:

                      JavaScript

                      <span class="syntaxdefault"><br /></span><span class="syntaxkeyword">function&nbsp;</span><span class="syntaxdefault">multiply</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">a</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">b&nbsp;</span><span class="syntaxkeyword">)<br />{<br />&nbsp;&nbsp;return&nbsp;</span><span class="syntaxdefault">a&nbsp;</span><span class="syntaxkeyword">*&nbsp;</span><span class="syntaxdefault">b</span><span class="syntaxkeyword">;<br />}<br />&nbsp;</span><span class="syntaxdefault"></span>
                      

                      Ruby

                      <span class="syntaxdefault"><br />result&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">webdialog</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call_script</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxstring">'multiply'</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">5&nbsp;</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">puts&nbsp;result<br /></span><span class="syntaxcomment">#&nbsp;=>&nbsp;15<br />&nbsp;</span><span class="syntaxdefault"></span>
                      

                      @jolran said:

                      So just to make clear, I can forget about hidden inputfields and just send the data from SU exect.script to a global array in JS then? Like Thomthoms in this topic provided" materials.rb" do.

                      The proxy JS function I mentioned in the previous example also cleans up the SCRIPT elements. I automated all the common things you do into wrapper functions and made it a convention to call JS functions from Ruby.

                      Thomas Thomassen — SketchUp Monkey & Coding addict
                      List of my plugins and link to the CookieWare fund

                      1 Reply Last reply Reply Quote 0
                      • jolranJ Offline
                        jolran
                        last edited by

                        Thomthom, thanks.

                        I have been poking around in TTlib. But sometimes the picture is so big I can't see the details 😄

                        Also I totally forgot to check out your thomthom.net docs. Bunch of info there.

                        With your explanations here I might understand the code better.
                        Will give it a try.

                        1 Reply Last reply Reply Quote 0
                        • thomthomT Offline
                          thomthom
                          last edited by

                          @jolran said:

                          I have been poking around in TTlib. But sometimes the picture is so big I can't see the details 😄

                          Also I totally forgot to check out your thomthom.net docs. Bunch of info there.

                          With your explanations here I might understand the code better.
                          Will give it a try.

                          Yea, the library is quite big. And I haven't commented it well enough. True that. But hopefully you can make use of the concept.

                          My library is built around populating the webdialog with Ruby classes - letting me develop UIs using just Ruby. But along with that blog entry I might see if I can decouple my bridge framework.

                          Thomas Thomassen — SketchUp Monkey & Coding addict
                          List of my plugins and link to the CookieWare fund

                          1 Reply Last reply Reply Quote 0
                          • jolranJ Offline
                            jolran
                            last edited by

                            @unknownuser said:

                            My library is built around populating the webdialog with Ruby classes - letting me develop UIs using just Ruby.
                            I see, must be convenient doing like that in the long run.
                            For me just now I only need to send in some lists and values to my dialog and hit an OK buttons and start Ruby.

                            So the strategy right now is to nest a hash=>json object with list of material, layers, components and default values for inputboxes. And send through a function like you do in materials.rb.

                            @unknownuser said:

                            But along with that blog entry I might see if I can decouple my bridge framework.

                            Do you mean a bridge light? Sounds interrseting.
                            It seems there is no easy way to get around that webdialogs have to be complicated. Looks like there are many things that can go wrong. And the step from SU's inputbox is quite large.

                            http://sketchucation.com/forums/viewtopic.php?f=180&t=35969#p316774
                            This topic covers alot about JSON in Sketchup, BTW. Might mention it if someone enters here looking for info bout the subject.

                            1 Reply Last reply Reply Quote 0
                            • thomthomT Offline
                              thomthom
                              last edited by

                              Untested, but should let you nest Hash objects.

                              <span class="syntaxdefault"><br />&nbsp;&nbsp;</span><span class="syntaxcomment">#&nbsp;Very&nbsp;simplified&nbsp;method&nbsp;just&nbsp;for&nbsp;this&nbsp;example's&nbsp;purpose.<br />&nbsp;&nbsp;</span><span class="syntaxdefault">def&nbsp;self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">hash_to_json</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">hash</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">pretty_print&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">false&nbsp;</span><span class="syntaxkeyword">)<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;</span><span class="syntaxdefault">pretty_print<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nl&nbsp;&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">"\n"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">tab&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">"&nbsp;&nbsp;"<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">nl&nbsp;&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">tab&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">""<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;json&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxstring">"{#{nl}"<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">items&nbsp;</span><span class="syntaxkeyword">=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;</span><span class="syntaxdefault">key</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">value&nbsp;in&nbsp;hash<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">value</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(&nbsp;</span><span class="syntaxdefault">Hash&nbsp;</span><span class="syntaxkeyword">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">value_hash&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">hash_to_json</span><span class="syntaxkeyword">(&nbsp;</span><span class="syntaxdefault">value</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">pretty_print&nbsp;</span><span class="syntaxkeyword">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">items&nbsp;</span><span class="syntaxkeyword"><<&nbsp;</span><span class="syntaxstring">"#{tab}#{key.inspect};&nbsp;#{value_hash}"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">items&nbsp;</span><span class="syntaxkeyword"><<&nbsp;</span><span class="syntaxstring">"#{tab}#{key.inspect};&nbsp;#{value.inspect}"<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end<br />&nbsp;&nbsp;&nbsp;&nbsp;json&nbsp;</span><span class="syntaxkeyword"><<&nbsp;</span><span class="syntaxdefault">items</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">join</span><span class="syntaxkeyword">(</span><span class="syntaxstring">",#{nl}"</span><span class="syntaxkeyword">)<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">json&nbsp;</span><span class="syntaxkeyword"><<&nbsp;</span><span class="syntaxstring">"#{nl}}#{nl}"<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">json<br />&nbsp;&nbsp;end<br /></span>
                              

                              Thomas Thomassen — SketchUp Monkey & Coding addict
                              List of my plugins and link to the CookieWare fund

                              1 Reply Last reply Reply Quote 0
                              • thomthomT Offline
                                thomthom
                                last edited by

                                @dan rathbun said:

                                You can sort the arrays before you convert the data hash to JSON:
                                data["materials"].sort!

                                I'd sort it in the WebDialog - as per my example - because SketchUp Ruby only knows ASCII while the WebDialog can handle UTF-8.

                                Thomas Thomassen — SketchUp Monkey & Coding addict
                                List of my plugins and link to the CookieWare fund

                                1 Reply Last reply Reply Quote 0
                                • jolranJ Offline
                                  jolran
                                  last edited by

                                  Ahh! Very nice.
                                  2 methods I can try before corking up 😄

                                  Dan, havent seen that one before. Started doing standard hash, but this looks interesting indeed. Learning lots here.

                                  Thomthom, so the code is basically just repeating until it doesent find a hash? I was trying to do something similar but it did not work for me. Some ":" came out as "=>". Will try and let you know how it works.
                                  BTW it says # Very simplified method just for this example's purpose.
                                  I suppose you have more convoluted for this purpose?

                                  Thanks to both of you!

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by

                                    @thomthom said:

                                    I'd sort it in the WebDialog - as per my example - because SketchUp Ruby only knows ASCII while the WebDialog can handle UTF-8.

                                    Good Point!! .. I agree.

                                    👍

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • Dan RathbunD Offline
                                      Dan Rathbun
                                      last edited by

                                      @jolran said:

                                      So the strategy right now is to nest a hash=>json object with list of material, layers, components and default values for inputboxes.

                                      That is the easy part, just build a Ruby Hash:

                                      data = Hash[
                                        "materials", [],
                                        "layers", [],
                                        "components", [],
                                        "defaults", []
                                      ]
                                      

                                      (Above, I use the Hash class constructor method [], which is an even number of comma separated params of form [ key, val, key, val, ... ].)

                                      Then load the arrays like:

                                      Sketchup.active_model.materials.each {|matl|
                                        data["materials"] << matl.name
                                      }
                                      

                                      You can sort the arrays before you convert the data hash to JSON:
                                      data["materials"].sort!
                                      Whoops... don't do, see next post!

                                      💭

                                      I'm not here much anymore.

                                      1 Reply Last reply Reply Quote 0
                                      • thomthomT Offline
                                        thomthom
                                        last edited by

                                        @jolran said:

                                        Thomthom, so the code is basically just repeating until it doesent find a hash?

                                        It's a re-cursing method. Every Hash object should be converted into a JS friendly JSON string. Allowing you to nest Hash objects.

                                        Thomas Thomassen — SketchUp Monkey & Coding addict
                                        List of my plugins and link to the CookieWare fund

                                        1 Reply Last reply Reply Quote 0
                                        • jolranJ Offline
                                          jolran
                                          last edited by

                                          Yeah, ok. I did not manage to make it work with nested hashes.
                                          Got some backslashes "/" and wierd results.
                                          Your method most likely works, but I might have scre#¤ewd things up making the nested hashes in ruby. Also got somewhat lost in the code during the process.

                                          So I took one step back to get some control over the situation and decided not to use nested JSON. In spite of yours and Dans efforts 😳 Sorry.

                                          Instead I make 4 separate JSONlists using your 1st converter.
                                          Send them in the execute_script function(). Rewrote some JS so I could reuse your loops.
                                          It might be safer doing it that way anyway?
                                          Don't have to eval or parse the JSON, just use the sort_by_value(json) function you provided, Thomthom.

                                          It works, but might need some optimizing.
                                          Can post some code later..

                                          Happy new year BTW!

                                          1 Reply Last reply Reply Quote 0
                                          • thomthomT Offline
                                            thomthom
                                            last edited by

                                            I'll look at the re-cursing later.

                                            Though, I think I've solved it in TT_Lib2 - the JSON ruby class I wrote.
                                            json.rb

                                            It relies on javascript.rb

                                            But you should be able to just take those two files and not have to reply on anything else.

                                            In reality the JSON class is just an ordered Hash. (You can iterate the items in the same order you inserted them.) It's the to_s that does the work of converting to a JavaScript compatible string with the help of the TT::Javascript module.

                                            The TT::Javascript.to_js includes some extra stuff that converts Geom::Point3d and Geom::Vector3d into Javascript object. (Point3d and Vector3d classes needs to be defined on the JS side.) For your purposes that can be removed.

                                            Thomas Thomassen — SketchUp Monkey & Coding addict
                                            List of my plugins and link to the CookieWare fund

                                            1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 3
                                            • 2 / 3
                                            • First post
                                              Last post
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement