Module: MSPhysics::ControlPanel

Defined in:
RubyExtension/MSPhysics/control_panel.rb

Overview

Since:

  • 1.0.0

Constant Summary collapse

USE_HTML_DIALOG =

Since:

  • 1.0.0

::Sketchup.version.to_i > 16 ? true : false
TITLE =

Since:

  • 1.0.0

'MSPhysics Control Panel'
FADE_DURATION =

Since:

  • 1.0.0

2.0
FADE_DELAY =

Since:

  • 1.0.0

2.0
MIN_OPACITY =

Since:

  • 1.0.0

10
MAX_OPACITY =

Since:

  • 1.0.0

250

Class Method Summary collapse

Class Method Details

.add_slider(name, default_value = 0, min = 0, max = 1, step = 0.01) ⇒ Boolean

Create a range slider.

Parameters:

  • name (String)

    Slider name.

  • default_value (Numeric) (defaults to: 0)

    Starting value.

  • min (Numeric) (defaults to: 0)

    Minimum value.

  • max (Numeric) (defaults to: 1)

    Maximum value.

  • step (Numeric) (defaults to: 0.01)

    Snap step.

Returns:

  • (Boolean)

    success

Since:

  • 1.0.0



236
237
238
239
240
241
242
243
244
245
246
247
# File 'RubyExtension/MSPhysics/control_panel.rb', line 236

def add_slider(name, default_value = 0, min = 0, max = 1, step = 0.01)
  cname = name.to_s.gsub(/[\\\"\'\v\n\t\r\f]/, '')
  return false if @sliders[cname] != nil
  @sliders[cname] = {
    :default_value => default_value.to_f,
    :min => min.to_f,
    :max => max.to_f,
    :step => step.to_f < 1.0e-3 ? 1.0e-3 : step.to_f
  }
  generate_slider_html(name)
  true
end

.bring_to_frontObject

Activate the control panel window.

Since:

  • 1.0.0



217
218
219
# File 'RubyExtension/MSPhysics/control_panel.rb', line 217

def bring_to_front
  @dialog.bring_to_front if @dialog
end

.closeObject

Close the control panel

Since:

  • 1.0.0



179
180
181
# File 'RubyExtension/MSPhysics/control_panel.rb', line 179

def close
  @dialog.close if @dialog
end

.compute_text_size(text, opts = {}) ⇒ Array?

Note:

The control panel must be open for the values to be generated properly.

Compute size of a text in pixels.

Parameters:

  • text (String)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :font (String) — default: "Ariel"

    Text font.

  • :size (Integer) — default: 11

    Font size in pixels.

  • :bold (Boolean) — default: false

    Whether to have the text bold.

  • :italic (Boolean) — default: false

    Whether to have the text italicized.

Returns:

  • (Array, nil)

    An array of two values if successful

Since:

  • 1.0.0



318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'RubyExtension/MSPhysics/control_panel.rb', line 318

def compute_text_size(text, opts = {})
  return false if @dialog.nil? || !@init_called
  text = text.to_s
  font = opts.has_key?(:font) ? opts[:font].to_s : "Ariel"
  size = opts.has_key?(:size) ? opts[:size].to_i : 11
  bold = opts.has_key?(:bold) ? (opts[:bold] ? true : false) : false
  italic = opts.has_key?(:italic) ? (opts[:italic] ? true : false) : false
  cmd = "compute_text_size(#{text.inspect}, #{font.inspect}, #{size}, #{bold}, #{italic})"
  execute_js(cmd)
  temp = @test_result
  @test_result = nil
  return temp
end

.execute_js(code) ⇒ Object

Execute JavaScript in the control panel.

Parameters:

  • code (String)

Since:

  • 1.0.0



223
224
225
226
227
# File 'RubyExtension/MSPhysics/control_panel.rb', line 223

def execute_js(code)
  if @dialog && @init_called
    @dialog.execute_script(code)
  end
end

.get_slider_value(name) ⇒ Numeric?

Get slider value.

Parameters:

  • name (String)

    Slider name.

Returns:

  • (Numeric, nil)

    Slider value or nil if slider with the given name doesn’t exist.

Since:

  • 1.0.0



279
280
281
282
283
284
285
286
# File 'RubyExtension/MSPhysics/control_panel.rb', line 279

def get_slider_value(name)
  return if @dialog.nil? || !@init_called
  cname = name.to_s.gsub(/[\\\"\'\v\n\t\r\f]/, '')
  data = @sliders[cname]
  return unless data
  res = @dialog.get_element_value("lcrs-" + cname)
  res.empty? ? data[:default_value] : res.to_f
end

.handleInteger?

Acquire handle to the control panel.

Returns:

  • (Integer, nil)

Since:

  • 1.0.0



26
27
28
# File 'RubyExtension/MSPhysics/control_panel.rb', line 26

def handle
  @handle
end

.hideObject

Note:

Windows only!

Hide the control panel window.

Since:

  • 1.0.0



199
200
201
202
203
# File 'RubyExtension/MSPhysics/control_panel.rb', line 199

def hide
  if AMS::IS_PLATFORM_WINDOWS && @handle
    AMS::Window.show(@handle, 0)
  end
end

.openObject

Open control panel.

Since:

  • 1.0.0



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'RubyExtension/MSPhysics/control_panel.rb', line 31

def open
  return if @dialog

  iws = [300, 300]
  if USE_HTML_DIALOG
    @dialog = ::UI::HtmlDialog.new({
      :dialog_title => TITLE,
      :preferences_key => TITLE,
      :scrollable => false,
      :resizable => true,
      :width => iws.x,
      :height => iws.y,
      :left => 800,
      :top => 600,
      :min_width => 50,
      :min_height => 50,
      :max_width => -1,
      :max_height => -1,
      :style => ::UI::HtmlDialog::STYLE_DIALOG
    })
  else
    @dialog = ::UI::WebDialog.new(TITLE, false, TITLE, iws.x, iws.y, 800, 600, true)
  end

  # Callbacks
  @dialog.add_action_callback('init') { |acs, params|
    unless @init_called
      @init_called = true
      ui_scale = ::Sketchup.version.to_i > 16 ? ::UI.scale_factor : 1.0
      ds = eval(params)
      for i in ds.size
        data[i] *= ui_scale
      end
      #@border_size = [iws.x - ds.x, iws.y - ds.y]
      if AMS::IS_PLATFORM_WINDOWS && @handle
        ws = AMS::Window.get_size(@handle)
        cr = AMS::Window.get_client_rect(@handle)
        cs = [cr[2] - cr[0], cr[3] - cr[1]]
        @border_size = [ws.x - cs.x, ws.y - cs.y]
      else
        @border_size = [2, 24]
      end
    end
    @sliders.each { |name, data|
      generate_slider_html(name, false)
    }
    execute_js("update_size();")
  }

  @dialog.add_action_callback('size_changed') { |acs, params|
    @size = eval(params)
    update_placement
  }

  @dialog.add_action_callback('mouse_enter') { |acs, params|
    @mouse_over = true
    @fade_time = 0.0 unless @fade_time
    @fade_wait_time = nil
  }

  @dialog.add_action_callback('mouse_leave') { |acs, params|
    @mouse_over = false
    unless @fade_time
      @fade_time = FADE_DURATION
      @fade_wait_time = 0.0
    end
    AMS::Sketchup.activate if AMS::IS_PLATFORM_WINDOWS
  }

  @dialog.add_action_callback('update_note') { |acs, params|
    next unless AMS::IS_PLATFORM_WINDOWS
    cmd = ""
    if AMS::Sketchup.is_main_window_active?
      cmd << "$('#note1').css('display', 'none');"
      cmd << "$('#note2').css('display', 'none');"
      cmd << "$('#note3').fadeIn(750);"
    elsif AMS::Window.is_active?(@handle)
      cmd << "$('#note1').css('display', 'none');"
      cmd << "$('#note3').css('display', 'none');"
      cmd << "$('#note2').fadeIn(750);"
    else
      cmd << "$('#note2').css('display', 'none');"
      cmd << "$('#note3').css('display', 'none');"
      cmd << "$('#note1').fadeIn(750);"
    end
    execute_js(cmd)
  }
  @dialog.add_action_callback('test_result') { |acs, params|
    @test_result = eval(params)
  }

  # Set content
  dir = ::File.dirname(__FILE__)
  dir.force_encoding('UTF-8') unless AMS::IS_RUBY_VERSION_18
  url = ::File.join(dir, 'html/control_panel.html')
  @dialog.set_file(url)

  # Show dialog
  if AMS::IS_PLATFORM_WINDOWS || USE_HTML_DIALOG
    @dialog.show
  else
    @dialog.show_modal
  end

  # Assign the on_close callback. Important: This must be called after
  # showing dialog in order to work on Mac OS X.
  do_on_close = Proc.new {
    if AMS::IS_PLATFORM_WINDOWS
      AMS::Sketchup.include_dialog(@handle)
      AMS::Sketchup.remove_observer(self)
    end
    execute_js('blur_input(); uninit();')
    @dialog = nil
    @handle = nil
    @mouse_over = false
    @init_called = false
    true
  }
  if USE_HTML_DIALOG
    @dialog.set_can_close() { do_on_close.call }
  else
    @dialog.set_on_close() { do_on_close.call }
  end

  # Find dialog window handle
  @handle = AMS::IS_PLATFORM_WINDOWS ? AMS::Sketchup.find_window_by_caption(TITLE) : nil
  if @handle
    # Add observer
    AMS::Sketchup.add_observer(self)
    # Remove dialog caption and borders
    layered = AMS::System.get_windows_version < 6.0 ? 0 : 0x00080000
    style_ex = 0x00010000 | layered # WS_EX_CONTROLPARENT | WS_EX_LAYERED
    #style = 0x54000000 # WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
    style = 0x94000000 # WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS
    AMS::Window.lock_update(@handle)
    AMS::Window.set_long(@handle, -20, style_ex)
    AMS::Window.set_long(@handle, -16, style)
    AMS::Window.lock_update(nil)
    AMS::Window.set_pos(@handle, 0, 0, 0, 0, 0, 0x0267)
    AMS::Window.set_layered_attributes(@handle, 0, MAX_OPACITY, 2)
    AMS::Sketchup.ignore_dialog(@handle)
    AMS::Sketchup.activate
    @fade_time = FADE_DURATION
    @fade_wait_time = 0.0
  end
end

.open?Boolean

Determine whether control panel is open.

Returns:

  • (Boolean)

Since:

  • 1.0.0



185
186
187
# File 'RubyExtension/MSPhysics/control_panel.rb', line 185

def open?
  @dialog ? true : false
end

.remove_slider(name) ⇒ Boolean

Destroy a range slider.

Parameters:

  • name (String)

    Slider name.

Returns:

  • (Boolean)

    success

Since:

  • 1.0.0



252
253
254
255
256
257
# File 'RubyExtension/MSPhysics/control_panel.rb', line 252

def remove_slider(name)
  return false if @sliders[name.to_s].nil?
  degenerate_slider_html(name.to_s)
  @sliders.delete(name.to_s)
  true
end

.remove_slidersInteger

Destroy all range sliders.

Returns:

  • (Integer)

    Number of sliders removed.

Since:

  • 1.0.0



261
262
263
264
265
266
# File 'RubyExtension/MSPhysics/control_panel.rb', line 261

def remove_sliders
  size = @sliders.size
  @sliders.clear
  execute_js("remove_sliders(); update_size();")
  size
end

.set_slider_value(name, value) ⇒ Boolean

Set slider value.

Parameters:

  • name (String)

    Slider name.

  • value (Numeric)

Returns:

  • (Boolean)

    success

Since:

  • 1.0.0



292
293
294
295
296
297
298
299
300
# File 'RubyExtension/MSPhysics/control_panel.rb', line 292

def set_slider_value(name, value)
  return false if @dialog.nil? || !@init_called
  cname = name.to_s.gsub(/[\\\"\'\v\n\t\r\f]/, '')
  data = @sliders[cname]
  return false if data.nil? || @dialog.get_element_value("lcrs-" + cname).empty?
  cmd = "sliders[\"#{cname}\"].setValue(#{value.to_f}); update_slider(\"#{cname}\");"
  execute_js(cmd)
  true
end

.showObject

Note:

Windows only!

Show the control panel window.

Since:

  • 1.0.0



191
192
193
194
195
# File 'RubyExtension/MSPhysics/control_panel.rb', line 191

def show
  if AMS::IS_PLATFORM_WINDOWS && @handle
    AMS::Window.show(@handle, 8)
  end
end

.slider_exists?(name) ⇒ Boolean

Determine whether a range slider with a particular name already exists.

Parameters:

  • name (String)

Returns:

  • (Boolean)

Since:

  • 1.0.0



271
272
273
# File 'RubyExtension/MSPhysics/control_panel.rb', line 271

def slider_exists?(name)
  @sliders[name] ? true : false
end

.sliders_countInteger

Get the number of sliders in the control panel.

Returns:

  • (Integer)

Since:

  • 1.0.0



304
305
306
# File 'RubyExtension/MSPhysics/control_panel.rb', line 304

def sliders_count
  @sliders.size
end

.visible?Boolean

Determine whether the control panel window is visible.

Returns:

  • (Boolean)

Since:

  • 1.0.0



207
208
209
210
211
212
213
214
# File 'RubyExtension/MSPhysics/control_panel.rb', line 207

def visible?
  return false unless @dialog
  if AMS::IS_PLATFORM_WINDOWS && @handle
    AMS::Window.is_visible?(@handle)
  else
    true
  end
end