Notifications
Clear all

[Closed] Replacement for Vertical Scroll

Yes but I never saw that any scrolling works like this in max.
Thanks for the nice examples, Mike.

if you develop any tools for max (or maya, or anything else) never try to make it looks or behaves differently than the main tool. the best custom tools look as built-in.

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

I know that is better to create GUI in some external softvare to look gook and works without bugs, but this is not the point here. And you recently started very informative topic an appropriate UI style.
This is just experimental works. I try to explore possibilities of some .net objects here in max.
At least can you do some “magic touch” to the code to works even more smoothly.
Thanks for your guidance, Denis.

your solution is already looks straightforward for me. i can post my (not finished yet) version. and you will see how our versions are close.
i don’t really like a solution to hide the scrollbar when noting to scroll. i don’t like this behavior in some .net controls as well. i think that to leave it just ‘filled’ makes more sense

Klunk suggested to hide scrollbar when size of form not overlap buttons. I agree to leave scrollbar visible because already looks thin and non-distracting.
Most important thing for me here is “click and drag” functionality over the buttons. Mouse Wheel scrolling is not what I’m looking for.

Another reason why I started this topic is because many scripters build own tools without taking into account the size of tool dialog ei. window form. Sometime the height can be greater than
screen size or width can covers most of the working space. I hope that the authors of these tools
agree with me.
http://www.scriptspot.com/3ds-max/scripts/cleaner
http://www.scriptspot.com/3ds-max/scripts/polyfx-v2-1-update
Anyway this can be fixed in many different ways like organizing some sections using FloatDialog with rollouts, using tabs etc. Worst case scenario will be docking.
Frankly I prefer more using .net form with minimalistic look especially when it comes to projects with many controls ei. in case when you need to join many tools into the one big tool – “All In One” solution. This requires most of the work but in the end worth it.
Denis once said than users can sometime scares of tools that look different of standard max tools, which is true of most cases, but scrips like I posted as example can be also scary and difficult to use although it has very good usage

Klunk suggested to hide scrollbar when size of form not overlap buttons. I agree to leave scrollbar visible because already looks thin and non-distracting.

no I never I just said it jumped when the window was big enough not to need one.

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Sorry for the misunderstanding. My bad

now it’s finished (at least at the point where i want to stop :))


try(form.close()) catch() 
(
	dotcolor = dotnetclass "System.Drawing.Color"
	
	global form = dotnetobject "MaxCustomControls.Maxform"
	form.Text = "VScroll"
	form.ShowInTaskbar = off
	form.DockPadding.All = 2

	form.StartPosition = form.StartPosition.Manual
	form.Size = dotnetobject "System.Drawing.Size" 200 300
	form.Location = dotnetobject "System.Drawing.Point" 800 200

	p = dotnetobject "UserControl"	
	p.Dock = p.Dock.Fill

	barWidth = 7 
	barMinHeight = 7

	global sb = dotnetobject "UserControl"
	sb.Backcolor = sb.Backcolor.Black
	sb.width = barWidth
	sb.DockPadding.All = 1 
	sb.Dock = sb.Dock.Right

	global tt = dotnetobject "Button"
	tt.Name = "Thumb"
	tt.Backcolor = tt.Backcolor.Dimgray
	tt.FlatStyle = tt.FlatStyle.Flat
	tt.FlatAppearance.BorderSize = 1
	controlops.setselectable tt off
	tt.width = 8
	tt.MinimumSize = dotnetobject "System.Drawing.Size" barWidth barMinHeight
	tt.Location = dotnetobject "System.Drawing.Point" 0 0
	sb.controls.add tt

	bc = dotnetobject "UserControl"
	bc.Enabled = off
	bc.Dock = bc.Dock.Fill
	bc.Backcolor = bc.Backcolor.FromArgb 40 40 40 
	sb.controls.add bc

	global pp = dotnetobject "UserControl"
	pp.Dock = pp.Dock.Fill
	
	cc = dotnetobject "UserControl"
	cc.Padding = dotnetobject "Padding" 0 0 1 0
	cc.AutoSize = on
	bts = for k=25 to 1 by -1 collect
	(
		bt = dotnetobject "Button" 
		bt.BackColor = dotcolor.Transparent
		bt.Dock = bt.Dock.Top
		bt.Text = k as string
		bt
	)
	cc.controls.addrange bts

	pp.controls.add cc

	p.controls.addrange #(pp, sb)
	sb.tag = cc

	form.controls.add p
	sb.MaximumSize = tt.MaximumSize = (dotnetobject "System.Drawing.Size" barWidth cc.PreferredSize.Height)
	
	tt.tag = #(0,0,0)

	fn onSizeChanged s e =
	(
		c = s.controls.item[0]
		v = s.tag.Height - s.Height + s.tag.Location.Y as float
		
		if v > 0 then
		(
			h = (s.Height as float)/s.tag.PreferredSize.Height*s.Height 
			c.Location.Y = (s.tag.Location.Y as float)/(s.Height - s.tag.Height)*(s.Height - h)
		)
		else
		(
			s.tag.Location.Y = amin 0 (s.tag.Location.Y - v)
			h = (s.Height as float)/s.tag.PreferredSize.Height*s.Height
		)
		h = amax c.MinimumSize.Height ((h + 0.5) as integer)
		if c.Location.Y + h > s.Height do c.Location.Y = amax 0 (s.Height - h)
		c.Height = h
	)
	fn onPanelSizeChanged s e = (s.controls.item[0].Width = s.Width)
	fn onMouseDown s e =
	(
		if e.Button == e.Button.Left do s.tag = #(e.y, 0, 1)
	)
	fn onMouseMove s e = 
	(
		if e.Button == e.Button.Left and e.y != s.tag[1] do
		(
			p = s.parent.tag
			y = s.Location.y + e.y - s.tag[1]
			y = amin (s.parent.Height - s.Height) (amax 0 y)
			s.tag = #(s.tag[1], y, 0)
			if y != s.Location.y do 
			(
				p.Location.Y = (y as float)/(s.parent.Height - s.Height)*(s.parent.Height - p.Height)
				s.Location.Y = y
			)
		)
	)
	dotnet.addEventHandler tt "MouseDown" onMouseDown
	dotnet.addEventHandler tt "MouseMove" onMouseMove
	dotnet.addEventHandler sb "SizeChanged" onSizeChanged
	dotnet.addEventHandler pp "SizeChanged" onPanelSizeChanged
	
	onPanelSizeChanged pp undefined
	onSizeChanged sb undefined	
	
	form.ShowModeless()
)

2 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

31 line cause error. Check this line


controlops.setselectable tt off

(@denist)
Joined: 11 months ago

Posts: 0

no… you check this line!
if you don’t have this function, just comment it…

but before… try to get why i do this thing…

Why don’t you say that earlier I not have that fn and what represent if is not a secret.
Scrolling works smoothly. You stoped with this but what about other two conditions “click and drag” and “mouse wheel”?

the button in the flat style draws extra frame when it is focused. the only way to disable it is set the button be never selectable.

“click and drag” and “mouse wheel”… not really interested. it’s just an opposite of what i already solved

5 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

That’s why I decide to use .net label as scrollbar.
Ok. I appreciate everythine what you done here and You done more then enough.
Big thanks !

(@denist)
Joined: 11 months ago

Posts: 0

ha! you see it… but the using of a flat button gives nice and free: mouse enter, mouse leave, and mouse down appearance

(@gazybara)
Joined: 11 months ago

Posts: 0

devX simple button object have very nice property “Allow Focus” to disable selection rectangle
and nicer enter-leave-down appearance with gradient touch

try(form.close()) catch() 
(
	dotcolor = dotnetclass "System.Drawing.Color"
	
	global form = dotnetobject "MaxCustomControls.Maxform"
	form.Text = "VScroll"
	form.ShowInTaskbar = off
	form.DockPadding.All = 2

	form.StartPosition = form.StartPosition.Manual
	form.Size = dotnetobject "System.Drawing.Size" 200 300
	form.Location = dotnetobject "System.Drawing.Point" 800 200

	p = dotnetobject "UserControl"	
	p.Dock = p.Dock.Fill

	barWidth = 7 
	barMinHeight = 7

	global sb = dotnetobject "UserControl"
	sb.Backcolor = sb.Backcolor.Black
	sb.width = barWidth
	sb.DockPadding.All = 1 
	sb.Dock = sb.Dock.Right

	global tt = dotnetobject "Button"
	tt.Name = "Thumb"
	tt.Backcolor = tt.Backcolor.Dimgray
	tt.FlatStyle = tt.FlatStyle.Flat
	tt.FlatAppearance.BorderSize = 1
	--controlops.setselectable tt off
	tt.width = 8
	tt.MinimumSize = dotnetobject "System.Drawing.Size" barWidth barMinHeight
	tt.Location = dotnetobject "System.Drawing.Point" 0 0
	sb.controls.add tt

	bc = dotnetobject "UserControl"
	bc.Enabled = off
	bc.Dock = bc.Dock.Fill
	bc.Backcolor = bc.Backcolor.FromArgb 40 40 40 
	sb.controls.add bc

	global pp = dotnetobject "UserControl"
	pp.Dock = pp.Dock.Fill
	
	cc = dotnetobject "UserControl"
	cc.Padding = dotnetobject "Padding" 0 0 1 0
	cc.AutoSize = on
	bts = for k=25 to 1 by -1 collect
	(
		devXbtn = dotNetObject "DevExpress.XtraEditors.SimpleButton"
		devXbtn.text = ("button"+k as string)  ; devXbtn.AllowFocus = off
		devXbtn.size = (dotnetobject "System.Drawing.Size" 185 20)
		devXbtn.dock = devXbtn.dock.top
		devXbtn.appearance.backcolor = devXbtn.appearance.backcolor.FromArgb 100 140 200
		devXbtn.appearance.backcolor2 = devXbtn.appearance.backcolor2.FromArgb 50 100 150
		devXbtn.appearance.forecolor = devXbtn.appearance.forecolor.FromArgb 0 0 0
		devXbtn.appearance.bordercolor = devXbtn.appearance.bordercolor.FromArgb 50 50 50
		devXbtn.appearance.GradientMode = (dotNetClass "System.Drawing.Drawing2D.LinearGradientMode").Vertical
		devXbtn.BorderStyle = devXbtn.BorderStyle.HotFlat --Flat,HotFlat,NoBorder,Office2003,Simple,Style3D,UltraFlat
		devXbtn
	)
	cc.controls.addrange bts

	pp.controls.add cc

	p.controls.addrange #(pp, sb)
	sb.tag = cc

	form.controls.add p
	sb.MaximumSize = tt.MaximumSize = (dotnetobject "System.Drawing.Size" barWidth cc.PreferredSize.Height)
	
	tt.tag = #(0,0,0)

	fn onSizeChanged s e =
	(
		c = s.controls.item[0]
		v = s.tag.Height - s.Height + s.tag.Location.Y as float
		
		if v > 0 then
		(
			h = (s.Height as float)/s.tag.PreferredSize.Height*s.Height 
			c.Location.Y = (s.tag.Location.Y as float)/(s.Height - s.tag.Height)*(s.Height - h)
		)
		else
		(
			s.tag.Location.Y = amin 0 (s.tag.Location.Y - v)
			h = (s.Height as float)/s.tag.PreferredSize.Height*s.Height
		)
		h = amax c.MinimumSize.Height ((h + 0.5) as integer)
		if c.Location.Y + h > s.Height do c.Location.Y = amax 0 (s.Height - h)
		c.Height = h
	)
	fn onPanelSizeChanged s e = (s.controls.item[0].Width = s.Width)
	fn onMouseDown s e =
	(
		if e.Button == e.Button.Left do s.tag = #(e.y, 0, 1)
	)
	fn onMouseMove s e = 
	(
		if e.Button == e.Button.Left and e.y != s.tag[1] do
		(
			p = s.parent.tag
			y = s.Location.y + e.y - s.tag[1]
			y = amin (s.parent.Height - s.Height) (amax 0 y)
			s.tag = #(s.tag[1], y, 0)
			if y != s.Location.y do 
			(
				p.Location.Y = (y as float)/(s.parent.Height - s.Height)*(s.parent.Height - p.Height)
				s.Location.Y = y
			)
		)
	)
	dotnet.addEventHandler tt "MouseDown" onMouseDown
	dotnet.addEventHandler tt "MouseMove" onMouseMove
	dotnet.addEventHandler sb "SizeChanged" onSizeChanged
	dotnet.addEventHandler pp "SizeChanged" onPanelSizeChanged
	
	onPanelSizeChanged pp undefined
	onSizeChanged sb undefined	
	
	form.ShowModeless()
)
(@denist)
Joined: 11 months ago

Posts: 0

try to test any devx control performance vs its base.

(@gazybara)
Joined: 11 months ago

Posts: 0

But if we use paint event for gradient and other coloring stuff on base control then will “equate”
performance :).
Yup. devX is slower in any case , but you have to admit that it looks cool

Page 4 / 5