Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility shim does not allow 2 args or an empty window caption #15

Open
DanRathbun opened this issue Sep 30, 2021 · 1 comment
Open

Comments

@DanRathbun
Copy link
Contributor

DanRathbun commented Sep 30, 2021

@thomthom : But features/behaviour in UI.inputbox that was useful and not buggy can of course be adopted here.

Yes, the native UI.inputbox has the ability to pass 1 prompt array argument without a window title.
But it stupidly will not allow 2 args with the 2nd being the window title. (It raises an exception.)

Your code mimicked this. So I reordered the statements in the ArgumentParser to allow anywhere from 1..4 args.
A consumer can now do ...

HtmlUI::inpubox(["Name"], "Who are you?")

It is silly to force coders to stuff empty literal arrays into a method call, ie ...

HtmlUI::inpubox(["Name"], [], "Who are you?")

If there are no defaults, there is no good reason to force the passing of an empty array.
(This is forced inclusion of empty array arguments is a native UI::inputbox quirk.)


In testing this I also found that the argument parser sets the window :title to an empty string to mimic the native UI::inputbox which will display without a window caption. (Ie, the compatibility shim method does not allow the default Sketchup::app_name to be the default window caption.)

But this doesn't work with a Chromium window. If the window title is not set or is an empty string, then the window caption gets set to "inputbox.html".

The solution is to insert a space into an empty :title string if it is left empty (ie, not specified in the compatibility shim arguments.)

@DanRathbun
Copy link
Contributor Author

DanRathbun commented Sep 30, 2021

Just FTR ... the following is the get_options_args method reordered with much annotations added.
I simplified the code a bit as I thought using the arguments hash just complicated the reading of the code.

In this version I stripped out the support for class identifier defaults and the whitespace pad warnings, so as not to confuse this issue. The snippet below is meant to show the annotations I added and how the :title handling code was reorderd a bit to allow for 1 arg with a blank window title and 2 args where the second arg is a title string.

    def get_options_args(*args)
      unless args.size.between?(1,4)
        fail(ArgumentError,'No arguments given. (1..4 expected)',@callstack)
      end

      # Begin with default arguments:
      title    = ''
      prompts  = ensure_array(args, 0)
      defaults = []
      lists    = []

      # Extract the arguments from the args array:

      # The position of the `:title` argument depends upon whether the
      # method was called with `defaults` or `list` array arguments.
      # Start with minimum position 2 (at index 1):
      title_index = 1

      # The defaults to match the prompts:
      if args.size > 1 && args[1].is_a?(Array)
        defaults = ensure_array(args, 1)
        # NOTE: At this point the first 2 args are known arrays.
        # The defaults array can be larger as extras will be ignored.
        # The defaults also can be empty, ie no defaults given.
        # Any shortage of defaults will get nil assigned.

        title_index += 1
      end

      # The lists of options:
      if args.size > 2 && args[2].is_a?(Array)
        # NOTE: Empty string options map to empty arrays:
        lists = args[2].map { |list| list.to_s.split('|') }

        title_index += 1
      end

      # Get the window title if given:
      if args.size > title_index
        title = args[title_index].to_s
      end

      # Convert to window property hash:
      options = {
        inputs: []
      }

      # Title finalization:
      # Empty `:title` results in "inputbox.html" as the window caption.
      # So for a blank window caption there must be at least 1 space.
      options[:title] = title.empty? ? ' ' : title

      # For each prompt, build an input control property hash:
      prompts.each_with_index { |prompt, index|
        # Init this input property hash:
        input = {
          # Label
          label: prompt.to_s,
          value: '',
          options: [],
          type: 'textbox'
        }
        # Default and Value:
        default = defaults[index]
        if default.nil?
          input[:default] = ''
        else
          input[:value]= input[:default]= default
        end
        # Options
        list = lists[index]
        if list && !list.empty?
          input[:type] = 'dropdown'
          # Check if we should leave render control as unchosen:
          if input[:default] != '' && !input[:value].empty? && !list.include?(default)
            input[:value] = ''
          end
          input[:options] = list
        end
        # Push the input property hash into the inputs array:
        options[:inputs] << input
      }
      options
    end

I also added the signature 4 places in the docs.

YARD has a way of doing this one place and the referencing it in other docstrings.
But I don't know who would run YARD on such a small code repo.

    #
    # @overload inputbox(prompts, title = '')
    #   The signature uses all textbox inputs without defaults.
    #   @param [Array<String>] prompts
    #   @param [String] title

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant