Dockable html dialog

I was almost getting it, then found out theres 2 problems:

  1. I can’t rlly trigger the docking time since “onLButtonUp” observer doesn’t seem to work while above an htmldialog.
    I could try “onMouseMove” but may flood the API buffer or something?

  2. I can’t get htmldialog position coords:
    #<NoMethodError: undefined method `get_position’ for #UI::HtmlDialog:0x00023f47e31d08>

(“.get_position” works on SU2021.1 above, I need SU17 above)

feels like:
R

Suggestions?

Code:

module Taxsola
	module Tax_Engineering

		class Dock_Observer
			def onLButtonUp(flags, x, y, view)
puts ("LButton Up at [#{x},#{y}]") #Debug
				Tax_Engineering.update_html_dock()
			end
		end


		def self.dockable_html

			#Default HTML dialog size
			@@Default_Html_Width = 200
			@@Default_Html_Height = 200

		@@Dock_Dialog = UI::HtmlDialog.new({
		  :dialog_title => "Dockable html dialog",
		  :preferences_key => "com.sample.plugin",
		  :resizable => false,
		  :style => UI::HtmlDialog::STYLE_DIALOG
		})
		(html = "
		<!DOCTYPE html>
		<html>
			<head></head>
			<body>
				<h4>
					A<br>
					dockable<br>
					html<br>
					dialog<br>
				</h4>
			</body>
		</html>")

			@@Dock_Dialog.set_html(html)
			@@Dock_Dialog.set_position(100, 50)
			@@Dock_Dialog.set_size(@@Default_Html_Width, @@Default_Html_Height)
			@@Dock_Dialog.show

			model = Sketchup.active_model
			view = model.active_view

			#ADD OBSERVER
			@Dock = model.select_tool Dock_Observer.new
			view.add_observer (@Dock)

			@@Dock_Dialog.set_on_closed { view.remove_observer(@Dock) } #REMOVE OBSERVER
		end


		def self.update_html_dock
			model = Sketchup.active_model
			view = model.active_view

			@ViewPort_Coord = view.corner(0) #Get coords of viewport corner #0: top left, 1: top right, 2: bottom left, 3: bottom right.
puts("Viewport at:" + @ViewPort_Coord.to_s) #Debug
			@ViewPort_height = view.vpheight #Get viewport height

puts(@@Dock_Dialog.get_position) #Debug (error: '.get_position' method works on SU2021.1 above)
			@Html_L_pos, @Html_T_pos = @@Dock_Dialog.get_position
			@X_dist = (@Html_L_pos - @ViewPort_Coord)
			@Y_dist = (@Html_T_pos - @ViewPort_Coord)
			@html_dist = Math.sqrt((@X_dist*@X_dist) + (@Y_dist*@Y_dist))

			if (@html_dist < 100)
				@@Dock_Dialog.set_position(@ViewPort_Coord)
				@@Dock_Dialog.set_size(@@Default_Html_Width, @ViewPort_height)
			else
				@@Dock_Dialog.set_size( @@Default_Html_Width, @@Default_Html_Height)
			end
		end

		self.dockable_html

	end
end

Thanks :v:

HTML and Web dialogs do not dock in the panel trays (on Windows platform.)

There is an open feature request for this:

onLButtonUp is a Tool interface callback, not an observer callback.

There is no point in attaching an instance of your Dock_Observer to the view object as the view only has 1 callback:

Also note that there is an open bug issue regarding this:

1 Like

Thanks

Cool! +1 for this feature. Gonna take a better look on it soon.

Thanks, you pro!
Deleted, rlly useless line. Im not used to observers; just got an example as preset somewhere. Need to study docs a bit more.

yeah… I noticed that :confused:

but I got some improvements…

To get dialog coord, I used “window.screenLeft” on js instead of “get_position” on ruby. (should work SU17 above)

Cons:

  • Used “onMouseMove” observer on ruby and “onmousemove” on html/css
    So now its flooding buffer twice, I guess :l
  • As you said, doesn’t work outside viewport;
  • The titlebars keeps flickering since its always updating (think I can disable it with a status variable, gonna try);
  • Dialog doesn’t fit perfectly, so doesn’t look like a well finished UI :confused:
  • It may have some issues when multiple dialogs are open (not tested)

But even so I think it can be useful since user can still use as a side pannel while tweaking the model or something.

The main problem now is that “view.corner(0)” (top left) always return [0,0] local coords so I can’t use it as reference for positioning the dialog on screen.
I used a fixed value that fit my toolbar setup.

Is there a way to get the viewport’s global coords? (up left)

Code:

module Taxsola
	module Tax_Engineering

		class Dock_Observer
			def onMouseMove(flags, x, y, view) #old onLButtonUp
				Tax_Engineering.update_html_dock()
			end
		end


		def self.dockable_html

			model = Sketchup.active_model
			view = model.active_view

			@Viewport_X = 0
			@Viewport_PlusX = -6

			@Viewport_Y = 285 #User relative value. It must be the viewport global screen coord
			@Viewport_PlusY = 8

			#Default HTML dialog size
			@@Default_Html_Width = 200
			@@Default_Html_Height = 200
			@Titlebar_Offset = 31


		@@Dock_Dialog = UI::HtmlDialog.new({
		  :dialog_title => "Dockable html dialog",
		  :preferences_key => "com.sample.plugin",
		  :resizable => false,
		  :style => UI::HtmlDialog::STYLE_DIALOG
		})
		(html = "
		<!DOCTYPE html>
		<html onmousemove='get_coords()'>
			<head>
				<script>function get_coords() { sketchup.SendCoords(window.screenLeft, window.screenTop); }</script>
			</head>

			<body>
				<h4>
					AAA<br>
					dockable<br>
					html<br>
					dialog<br>
				</h4>
			</body>
		</html>")

			@@Dock_Dialog.set_html(html)
			@@Dock_Dialog.set_size(@@Default_Html_Width, @@Default_Html_Height)
			@@Dock_Dialog.set_position( (@Viewport_X + @Viewport_PlusX), (@Viewport_Y-@Titlebar_Offset))
			@@Dock_Dialog.show

			#OBSERVER SET UP
			@Dock = model.select_tool Dock_Observer.new
			@@Dock_Dialog.set_on_closed { view.remove_observer(@Dock) } #REMOVE OBSERVER


			@@Dock_Dialog.add_action_callback("SendCoords"){|action_context, htmlL, htmlT|

				model = Sketchup.active_model
				view = model.active_view

				@Html_L_pos = htmlL
				@Html_T_pos = htmlT
				@X_dist = (@Html_L_pos - @Viewport_X)
				@Y_dist = ((@Html_T_pos) - @Viewport_Y)
				@html_dist = Math.sqrt((@X_dist*@X_dist) + (@Y_dist*@Y_dist))

				if (@html_dist < 100)
					@@Dock_Dialog.set_position( (@Viewport_X + @Viewport_PlusX), (@Viewport_Y-@Titlebar_Offset))
					@ViewPort_height = view.vpheight
					@@Dock_Dialog.set_size(@@Default_Html_Width, (@ViewPort_height + @Viewport_PlusY))
				else
					@@Dock_Dialog.set_size( @@Default_Html_Width, @@Default_Html_Height)
				end
			}
		end


		def self.update_html_dock
			@@Dock_Dialog.execute_script("get_coords()")
		end


		self.dockable_html


	end
end

Nevermind, better to wait for that built in class/property to make it properly.
Its too glitchy, uses more space and compromises performance.
User can still put it mannually there if he wants to.

1 Like

This is not exposed in the API.

On Windows platofrom you could use Windows SDK calls via the Fiddle class.

I’ve been asking for docking dialogs continuously for 5 years. I think that until that feature is implemented extensions will always seem like a tacked on feature. I’ve been pestering @eneroth3 and @thomthom. They both understand the need, but apparently it’s something that is not trivial to implement.

You can see some of my attempts and discussion in this thread.

3 Likes

Thanks, gonna study that class

Agreed :l

1 Like

It’s something we really want. But it’s deeply tangled into the UI framework and logic of SketchUp itself. And we’re currently looking at some significant overhaul so there’s a lot of moving pieces right now.

2 Likes

Thanks for your response. I’m looking forward to seeing what the ‘significant overhaul’ includes. :crossed_fingers: