• Login
sketchucation logo sketchucation
  • Login
🔌 Quick Selection | Try Didier Bur's reworked classic extension that supercharges selections in SketchUp Download

Custom tool creating instances of text labels

Scheduled Pinned Locked Moved Developers' Forum
5 Posts 2 Posters 399 Views 2 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.
  • S Offline
    sepultribe
    last edited by 26 Jul 2015, 10:30

    I'm in the process of making a Tool that will display some text labels on the Component entities that it gets clicked on. The text label contents will be drawn from a soap webservice but that is another subject. What I'm having trouble with is getting the tool to operate on each entity separately. Right now it will only work on 1 entity at a time.

    module SensorNodeInfoPlugin
    class SensorNodeInfoTool
    
      def initialize
        @selection = nil
        @info = nil
        @new_text = nil
        @label_exists = false
      end
    
      def onLButtonDown(flags, x, y, view)
      if @label_exists==false
        pick_helper = view.pick_helper
        pick_helper.do_pick(x, y)
        @selection = pick_helper.best_picked
        @info = @selection.name
        arrow_x = @selection.bounds.corner(7)[0]
        arrow_y = @selection.bounds.corner(7)[1]
        arrow_z = @selection.bounds.corner(7)[2]
        text_x = 20
        text_y = 20
        text_z = 20
        @new_text = Sketchup.active_model.entities.add_text "", [arrow_x, arrow_y, arrow_z], [text_x, text_y, text_z]
        @new_text.text = "Loading #{@info}'s info..."
        @new_text.leader_type = 2
        @new_text.line_weight = 4
        @new_text.arrow_type = 4
        @label_exists=true
        else
        Sketchup.active_model.active_entities.erase_entities @new_text
        @label_exists=false
        end
      end
    
      def draw(view)
    
      end
    
    end # module Sepultribe
    
    # Add the plugin to the menu, only once when the file is loaded.
    unless file_loaded?(__FILE__)
      command = UI;;Command.new("Display Sensor Node Info"){
        Sketchup.active_model.select_tool(SensorNodeInfoTool.new)
      }
      UI.menu("Plugins").add_item(command)
    end
    
    end # SensorNodeInfoPlugin
    

    If I understand correctly there is only one instance of the Tool at all times? I need multiple instances or is there some other way?

    1 Reply Last reply Reply Quote 0
    • T Offline
      TIG Moderator
      last edited by 26 Jul 2015, 12:05

      Find an example Tool - like the Line-Tool script - there are dozens [e.g. My 2dTools scripts] - which take multiple point clicking - for a line instead of adding geometry from the clicked points you just add you label at its clicked point....
      You have a activate() method to set up the tool once, and that then runs a rest() method which starts the processing.
      You can have any Tool running until the user selects another tool etc...
      After the mouse-button-click code is done adding the label you then run the reset() method to set up for the next label...

      TIG

      1 Reply Last reply Reply Quote 0
      • S Offline
        sepultribe
        last edited by 26 Jul 2015, 14:12

        @tig said:

        Find an example Tool - like the Line-Tool script - there are dozens [e.g. My 2dTools scripts] - which take multiple point clicking - for a line instead of adding geometry from the clicked points you just add you label at its clicked point....
        You have a activate() method to set up the tool once, and that then runs a rest() method which starts the processing.
        You can have any Tool running until the user selects another tool etc...
        After the mouse-button-click code is done adding the label you then run the reset() method to set up for the next label...

        Yes but I will need to be able to both create and delete text labels on each component that is clicked(show on 1st LClick, hide on 2nd LClick, and in between update the contents of the text label at specified second intervals). Will that work with the above philosophy or will it need that I create a class to hold references to which text label is attached to which component and detect which one is clicked and delete it? I'm really confused.

        1 Reply Last reply Reply Quote 0
        • T Offline
          TIG Moderator
          last edited by 26 Jul 2015, 14:52

          Here's how I would do it...
          Let's first assume that a component-instance has no label.
          The user clicks on it.
          It is confirmed as a component-instance.
          It is also checked for a special attribute, tid=instance.get_attribute("SensorNodeInfo", "tid", nil), in this case it returns nil as it has no label.

          unless tid
            ### add_label_code
          else
            ### delete_label_code
          end
          

          The 'add_label_code' will make the Text object, and give it a 'tid', a matching 'tid' will also be given to the picked instance...
          ` tid=Time.now.to_f+rand
          instance.set_attribute("SensorNodeInfo", "tid", tid)

          some code to add the Text object - referenced as 'label'

          label.set_attribute("SensorNodeInfo", "tid", tid)`
          Now the instance and its label are pair with a matching [unique] tid attribute.

          The 'delete_label_code' erases any related 'label', by matching its 'tid'.
          The 'label' Text object will have been previously given a unique 'tid' returned in the 'instance' match that was NOT nil, so you need to iterate the instances context to get possible candidates,
          labels_to_go=instance.parent.entities.grep(Sketcup::Text).select{|e| e.get_attribute("SensorNodeInfo", "tid", nil)==tid }
          then
          instance.parent.entities.erase_entities(labels_to_go) if labels_to_go[0]

          TIG

          1 Reply Last reply Reply Quote 0
          • S Offline
            sepultribe
            last edited by 26 Jul 2015, 17:46

            @tig said:

            Here's how I would do it...
            Let's first assume that a component-instance has no label.
            The user clicks on it.
            It is confirmed as a component-instance.
            It is also checked for a special attribute, tid=instance.get_attribute("SensorNodeInfo", "tid", nil), in this case it returns nil as it has no label.

            unless tid
            >   ### add_label_code
            > else
            >   ### delete_label_code
            > end
            

            The 'add_label_code' will make the Text object, and give it a 'tid', a matching 'tid' will also be given to the picked instance...

            ` tid=Time.now.to_f+rand
            instance.set_attribute("SensorNodeInfo", "tid", tid)

            some code to add the Text object - referenced as 'label'

            label.set_attribute("SensorNodeInfo", "tid", tid)`
            Now the instance and its label are pair with a matching [unique] tid attribute.

            The 'delete_label_code' erases any related 'label', by matching its 'tid'.
            The 'label' Text object will have been previously given a unique 'tid' returned in the 'instance' match that was NOT nil, so you need to iterate the instances context to get possible candidates,
            labels_to_go=instance.parent.entities.grep(Sketcup::Text).select{|e| e.get_attribute("SensorNodeInfo", "tid", nil)==tid }
            then
            instance.parent.entities.erase_entities(labels_to_go) if labels_to_go[0]

            Thanks that's very helpful.

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

            Advertisement