How to link UI.inputbox data to variables to use in creating geometry?

This is far from complete…but I’m having issues with how to get my input data to a variable to use in my array for points which I am building into a face. Also, I’m trying to get my tool to create trim by selecting edges in a model. How do I create a UI:Notification after the form completes that holds code until the user selects the wanted edges and then can click ok to create the geometry? I’m worried that building my face on a set axis (ex x,z) and will not allow this to happen, hence why the multiline comment is there. If you see anything else wrong, please let me know.

selection=Sketchup.active_model.selection
entities=Sketchup.active_model.entities
materials=Sketchup.active_model.materials
#Input boxes in UI menu which gather measurements for trim
print("Fill in the following information for your trim.")
prompts=["Trim Height", "Trim Thickness:", "Quarter Round:", "R:", "G:", "B:"]
defaults=[5.0,0.5,"No",100.0,100.0,100.0]
list=["","","Yes|No","","",""]
input=UI.inputbox prompts, defaults, list, "Stair Info"
  height,thickness,quarter_round=input
if quarter_round=='Yes'
  quarter_round_width=0.75
  quarter_round_height=0.75
notification=UI::Notification.new(sketchup_extension, "Select the trim path.")
notification.show
def build_trim
  #creating points for the new face
  #pts[number]=[width,depth,height]
  pts=[]
  pts[0]=[0,0,0]
  pts[1]=[0,0,height]
  pts[2]=[width,0,0]
  pts[3]=[width,0,height]
  #Creating the trim material
  interior_trim=materials.add"Interior Trim"
  interior_trim.color=[R,G,B]
  #Creating a face with the array
  face=entities.add_face(pts)
  connected=face.all_connected
  face.material=interior_trim
  #Selecting the line
  path=selection
  face.followme path
  =begin
  To fix issue of not following because face is on a different orientation than selection???
  if on x axis
    def build_trim
      #creating points for the new face
      #pts[number]=[width,depth,height]
      pts=[]
      pts[0]=[0,0,0]
      pts[1]=[0,0,height]
      pts[2]=[width,0,0]
      pts[3]=[width,0,height]
      #Creating a face with the array
      face=entities.add_face(pts)
      connected=face.all_connected
      #Selecting the line
      face.followme(selection)
  elif on z axis
    def build_trim
      #creating points for the new face
      #pts[number]=[width,depth,height]
      pts=[]
      pts[0]=[0,0,0]
      pts[1]=[0,0,height]
      pts[2]=[0,width,0]
      pts[3]=[0,width,height]
      #Creating a face with the array
      face=entities.add_face(pts)
      connected=face.all_connected
      #Selecting the line
      face.followme(selection)
  =end
end

All your code needs to be inside modules. (An outer unique namespace module, and an inner extension submodule.)

Again, use spaces before and after operators for readability, and between method definitions.
(Only methods defined in Kernel and Object should be called without parenthesis around their arguments.)

Also (again) you need to test the results from UI.inputbox and if it evaluates as false then the user cancelled the dialog and your command should cancel.

There is no keyword in Ruby named “elif”.

Don’t use a Notification balloon for this (as you cannot control how long it is visible), use a UI.messagebox if you must.

However, trying to leverage the native Selection Tool is going to be clunky.
Instead, when the user starts your command, check if there is a preselected set of joined edges in the selection, if not display a messagebox and after it returns (ie, the user dismisses it,) just exit the command method.
If there is a nice set of edges in the selection that can be used for a path then continue the command.

Don’t put method definitions inside a conditional if that evaluates at runtime. (You can do so at load time. Ie, I often define a method for the Mac platform and one for Windows inside a conditional ifelse, but only one gets defined.)

If all you need is create a different set of points depending upon axis then that is all that needs to be different, the rest of the “build_trim” method stays the same …


    def build_trim(axis, selection, height, width)
      #creating points for the new face
      pts = get_points(axis, height, width)
      #Creating a face with the array
      face = entities.add_face(pts)
      connected = face.all_connected
      #Selecting the line
      face.followme( selection.grep(Sketchup::Edge) )
    end

    def get_points(axis, height, width)
      case axis
      when X_AXIS
        [ [0,0,0], [0,0,height],
          [width,0,0], [width,0,height] ]
      when Y_AXIS
        [ [0,0,0], [0,0,height],
          [width,0,0], [width,0,height] ]
      when Z_AXIS
        [ [0,0,0], [0,0,height],
          [0,width,0], [0,width,height] ]
      end
    end

(The points above are probably not what you need, I’m just showing the structure of the method.)

X_AXIS, Y_AXIS and Z_AXIS are global vector constants defined in the toplevel ObjectSpace by the SketchUp Ruby API.

1 Like

I have code for a message. Should I use a case/when statement that when ok is selected it executes method build_trim, and when cancel is selected it closes the plugin? If so, how do I tell the code to execute the method and close the plugin?

      result=UI.messagebox(message, MB_OKCANCEL)
      case result
        when result == IDYES
          #executes build_trim
        when result == IDCANCEL
          #kills program
      end

You will not ever get an IDYES return value from a MB_OKCANCEL messagebox.

As I said in the other thread, you put the inputbox code in a command method.
If the user cancels the input box then you just return from the method without doing anything.
Ask more questions in the other thread please. (As you’ve marked this one as solved.)


Just for giggles, the answer to your question of whether to use case/when, is no.
You simply use a conditional in modifier position (either an if or an unless) …

def nifty_command()
  message = "Ready to do something nifty ?"
  choice = UI.messagebox(message, MB_OKCANCEL)
  return unless choice == IDOK
  something_nifty()
end