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.

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.

2 Likes

Thanks, gonna study that class

Agreed :l

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.

1 Like

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