Notifications
Clear all

[Closed] Replacement for Vertical Scroll

Using your example I replaced “FLP” with ContainerControl

 try(form.close()) catch() 
 (
	 global form = dotnetobject "MaxCustomControls.Maxform"
	 form.Text = "Show Test"
	 form.ShowInTaskbar = off
	 form.BackColor = form.BackColor.DarkGray
	 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.Backcolor = p.Backcolor.Gray 
	 p.Dock = p.Dock.Fill
 
	 sb = dotnetobject "UserControl"
	 sb.Backcolor = sb.Backcolor.black
	 sb.width = 8
	 sb.Dock = sb.Dock.Right
	 
	 global tt = dotnetobject "Button"
	 tt.Backcolor = tt.Backcolor.dimgray
	 tt.FlatStyle = tt.FlatStyle.Flat
	 tt.width = 8
	 sb.controls.add tt
	 
	 global fp = dotnetobject "ContainerControl"
	 fp.dock = fp.dock.fill
	 fp.backColor = fp.backColor.gray
	 --fp.FlowDirection = fp.FlowDirection.TopDown
	 --fp.WrapContents = off
	 
	 for k=1 to 20 do
	 (
		 bt = dotnetobject "Button"
		 bt.text = k as string
		bt.dock = bt.dock.Bottom
		 bt.Size = dotnetobject "System.Drawing.Size" 160 24
		 fp.controls.add bt
	 )
 
	 p.controls.addrange #(fp, sb)
		 
	 form.controls.add p
	 form.ShowModeless()
 )
 fp.VerticalScroll.Value = 50 
 
 fn onSizeChanged s e =
 (
	 s.tag.controls.item[0].Height = s.tag.height*(s.Height as float/s.PreferredSize.Height) 
 )
 dotnet.addEventHandler fp "SizeChanged" onSizeChanged
 fp.tag = tt.parent
 onSizeChanged fp undefined

Now I can get but not set VerticalScroll.value :).
Tried with this in listener when form is opened

cc = (form.controls.item[0]).controls.item[0]
-- this works
cc.verticalscroll.value
-->50
-- but this not ei. nothing happens
cc.verticalscroll.value = 30

Opposite behavior from FLP. Where did I go wrong?

first of all you have to dock children(buttons) from Top

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Ok I get it. Like this

	 for k = 20 to 1 by -1 do
 	 (
 		 bt = dotnetobject "Button"
 		 bt.text = k as string
 		bt.dock = bt.dock.top
 		 bt.Size = dotnetobject "System.Drawing.Size" 160 24
 		 fp.controls.add bt
 	 )

Ok now when I run

cc = (form.controls.item[0]).controls.item[0]
 -- to see top item (works)
 cc.verticalscroll.value = 1 
 -- with this i can't see the last one (not works)
 cc.verticalscroll.value = 100

because you refused ‘AutoScroll’ service you have to do all yourself. it will scroll the control, but you have to recalculate VerticalScroll.maximum when size or scroll changed, record the current scroll value, and change it if size changed… and no Scroll event for you anymore…

so everything do yourself. that’s a punishment for neglect built-in features.

Ok.
No hope I see. I need to think of something else 🙁
Thank you

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

no hope for any help from control… but it doesn’t mean no help from me

you have SizeChanged event… it gives you all what you need. your custom scrollbar has to keep tracking about scroll value, and fire ‘scroll’ event when its thumb position was changed

you will be probably surprised when you see how everything easy

I said no hope but that does not mean I give up. I almost forgot about this thread where we talk about custom timeline. This can be used as well.
But can you post example for your previous statement, please?

here is a beginning:


try(form.close()) catch() 
(
	global form = dotnetobject "MaxCustomControls.Maxform"
	form.Text = "Show Test"
	form.ShowInTaskbar = off
	form.BackColor = form.BackColor.DarkGray
	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.Backcolor = p.Backcolor.Gray 
	p.Dock = p.Dock.Fill

	sb = dotnetobject "UserControl"
	sb.Backcolor = sb.Backcolor.black
	sb.width = 8
	sb.Dock = sb.Dock.Right

	global tt = dotnetobject "Button"
	tt.Backcolor = tt.Backcolor.dimgray
	tt.FlatStyle = tt.FlatStyle.Flat
	tt.width = 8
	sb.controls.add tt

	global cc = dotnetobject "ContainerControl"
	cc.Dock = cc.Dock.Fill
	cc.BackColor = cc.BackColor.gray

	bts = for k=20 to 1 by -1 collect
	(
		bt = dotnetobject "Button"
		bt.text = k as string
		bt.Dock = bt.Dock.Top
		bt.Size = dotnetobject "System.Drawing.Size" 160 24
		bt
	)
	cc.controls.addrange bts

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

	fn onSizeChanged s e =
	(
		s.tag.controls.item[0].Height = amin s.Height (s.tag.height*(s.Height as float/s.PreferredSize.Height))
		s.VerticalScroll.Maximum = amax s.VerticalScroll.Minimum (s.PreferredSize.Height - s.Height - s.tag.tag)
	)
	dotnet.addEventHandler cc "SizeChanged" onSizeChanged
	
	form.controls.add p
	
	onSizeChanged cc undefined
	cc.VerticalScroll.Maximum = cc.PreferredSize.Height - cc.Height
	
	form.ShowModeless()
)

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

First ugly result.

try(form.close()) catch() 
 (
 	fn maxHW = (dotNetObject "maxCustomControls.win32HandleWrapper" (dotNetObject "System.IntPtr" (windows.getMaxHWND())))
 	fn defColor r g b = ((dotNetClass "System.Drawing.Color").FromArgb r g b)
 	fn defSize w h = (dotNetObject "System.Drawing.Size" w h)
 	fn defPoint x y = (dotNetObject "System.Drawing.Point" w h)
 	fn defRect x y w h = (dotNetObject "System.Drawing.Rectangle" x y w h)	
 	-->>> main form
 	global form = dotnetobject "Form"
 	form.Icon = (dotNetClass "ManagedServices.AppSDK").GetMainApplicationIcon()
 	form.FormBorderStyle = form.FormBorderStyle.SizableToolWindow
 	form.StartPosition = form.StartPosition.Manual
 	form.Text = "vScrollTest" ; form.ShowInTaskbar = off
 	form.BackColor = defColor 150 20 20 ; form.DockPadding.All = 2
 	form.MaximumSize = defSize 200 500
 	form.MinimumSize = defSize 200 103
 	form.Bounds = defRect 10 110 200 284
 	-->>> main container
 	mainUC = dotnetobject "UserControl"
 	mainUC.Backcolor = mainUC.Backcolor.Gray 
 	mainUC.Dock = mainUC.Dock.Fill
 	-->>> scroll container
 	scrollUC = dotnetobject "UserControl"
 	scrollUC.Backcolor = scrollUC.Backcolor.black
 	scrollUC.width = 6 ; scrollUC.tag = 0
 	scrollUC.Dock = scrollUC.Dock.Right
 	-->>> scrollbar
 	global scrollBar = dotnetobject "Label"
 	scrollBar.Backcolor = defColor 51 175 235
 	scrollBar.width = 6
 	-->>> button container
 	global cc = dotnetobject "ContainerControl"
 	cc.Dock = cc.Dock.Fill ; cc.tag = scrollUC
 	cc.BackColor = defColor 20 20 180
 	-->>> buttons
 	btns = for k = 20 to 1 by -1 collect
 	(
 		btn = dotnetobject "Button"
 		btn.FlatStyle = btn.FlatStyle.Flat
 		btn.FlatAppearance.BorderSize = 1
 		btn.FlatAppearance.BorderColor = defColor 60 60 60
 		btn.Backcolor = defColor 180 180 180
 		btn.text = "Button_#"+k as string
 		btn.Dock = btn.Dock.Top
 		btn.Size = defSize 160 20
 		btn
 	)
 	--> add Controls
 	cc.controls.addrange btns
 	scrollUC.controls.add scrollBar
 	mainUC.controls.addrange #(cc, scrollUC)
 	form.controls.add mainUC
 	-->>> add Events
 	fn onSizeChanged s e =
 	(
 		s.tag.controls.item[0].Height = amin s.Height (s.tag.height*(s.Height as float/s.PreferredSize.Height))
 		s.VerticalScroll.Maximum = amax s.VerticalScroll.Minimum (s.PreferredSize.Height - s.Height - s.tag.tag)
 	)
 	fn onMouseDown s e = 
 	(
 		local crs = dotnetclass "Cursors"
 		if s.Height != s.Parent.Height then (s.Cursor.Current = crs.Hand ; s.tag = #(e.y,0))
 		else (s.Cursor.Current = crs.Default ; s.tag = #(e.y,1))
 	)
 	fn onMouseMove s e = 
 	(
 		local crs = dotnetclass "Cursors", tag
 		case e.Button of
 		(
 			(e.Button.None): (s.Cursor.Current = if s.Height != s.Parent.Height then c.Hand else c.Default)			
 			(e.Button.Left): if s.Height == s.Parent.Height then (tag = s.tag ; tag[2] = 0 ; s.tag = tag) else
 			(
 				tag = s.tag ; d = e.y - tag[1] ; tag[2] = 1
 				s.location.y = amin (s.Parent.Height - s.Height) (amax 0 (s.location.y + d))
 				s.tag = tag
 			)
 		)
 	)
 	dotnet.addeventhandler scrollBar "Move" (fn scroll s e = cc.VerticalScroll.Value = s.Location.y)
 	dotnet.addeventhandler scrollBar "MouseDown" onMouseDown
 	dotnet.addeventhandler scrollBar "MouseMove" onMouseMove
 	dotnet.addEventHandler cc "SizeChanged" onSizeChanged
 	onSizeChanged cc undefined
 	cc.VerticalScroll.Maximum = cc.PreferredSize.Height - cc.Height
 	
 	form.Show(maxHW())	
 )

2 questions:

  • how to get rid of flickering
  • is it impotrtant to set LifetimeControl for all .net objects to #dotnet
4 Replies
(@denist)
Joined: 11 months ago

Posts: 0

#1
dont’t use scrollable control as panel
#2
yes. it’s important. it makes them protected from garbage collection.

(@gazybara)
Joined: 11 months ago

Posts: 0

Not understant #1 answer.
#2 ok. Do I need to set this for all .net object or only few (main controls only)?

(@denist)
Joined: 11 months ago

Posts: 0

what is flickering?

(@gazybara)
Joined: 11 months ago

Posts: 0

When I move blue label (scrollbar) all buttons in ContainerControl start to flicker and also start to show and hide vertial scrolbar of ContainerControl

#2 question: Like this?

mapped fn setLifetimeControl control = dotnet.setLifetimeControl control #dotnet
allControls = join btns #(form, mainUC, scrollUC, scrollBar, cc)
setLifetimeControl allControls

that’s why i suggested to not use scrollable control (ContainerControl in your case)

4 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

Tell me then which control can I use. Label control can be also container

(@denist)
Joined: 11 months ago

Posts: 0

UserControl for example

(@gazybara)
Joined: 11 months ago

Posts: 0

I get same result when replace ContainerControl with UserControl.
I need to use different aproch.
edit
I was thinking to use Label as container for buttons and just offset label location.y in main UserControl. What do you think?

(@gazybara)
Joined: 11 months ago

Posts: 0
   And this is the answer
try(form.close()) catch() 
(
	mapped fn setLifetimeControl control = dotnet.setLifetimeControl control #dotnet
	fn maxHW = (dotNetObject "maxCustomControls.win32HandleWrapper" (dotNetObject "System.IntPtr" (windows.getMaxHWND())))
	fn defColor r g b = ((dotNetClass "System.Drawing.Color").FromArgb r g b)
	fn defSize w h = (dotNetObject "System.Drawing.Size" w h)
	fn defPoint x y = (dotNetObject "System.Drawing.Point" x y)
	fn defRect x y w h = (dotNetObject "System.Drawing.Rectangle" x y w h)	
	-->>> main form
	global form = dotnetobject "Form"
	form.Icon = (dotNetClass "ManagedServices.AppSDK").GetMainApplicationIcon()
	form.FormBorderStyle = form.FormBorderStyle.SizableToolWindow
	form.StartPosition = form.StartPosition.Manual
	form.Text = "vScrollTest" ; form.ShowInTaskbar = off
	form.BackColor = defColor 150 20 20 ; form.DockPadding.All = 2
	form.MaximumSize = defSize 185 500
	form.MinimumSize = defSize 185 103
	form.Bounds = defRect 10 110 185 284
	-->>> main container
	mainUC = dotnetobject "UserControl"
	mainUC.Backcolor = mainUC.Backcolor.Gray 
	mainUC.Dock = mainUC.Dock.Fill
	-->>> scroll container
	scrollUC = dotnetobject "UserControl"
	scrollUC.Backcolor = scrollUC.Backcolor.black
	scrollUC.width = 6 ; scrollUC.tag = 0
	scrollUC.Dock = scrollUC.Dock.Right
	-->>> scrollbar
	global scrollBar = dotnetobject "Label"
	scrollBar.Backcolor = defColor 51 175 235
	scrollBar.width = 6
	-->>> button container
	global cc = dotnetobject "Label"
	cc.location = defPoint 0 0 ; cc.tag = scrollUC
	cc.BackColor = defColor 20 20 180
	--cc.autosize = off
	-->>> buttons
	btns = for k = 20 to 1 by -1 collect
	(
		btn = dotnetobject "Button"
		btn.FlatStyle = btn.FlatStyle.Flat
		btn.FlatAppearance.BorderSize = 1
		btn.FlatAppearance.BorderColor = defColor 60 60 60
		btn.Backcolor = defColor 180 180 180
		btn.text = "Button_#"+k as string
		btn.Dock = btn.Dock.Top
		btn.Size = defSize 160 20
		btn
	) ; cc.size = defSize 160 (btns[1].height*20)
	format "ccheight %
" cc.height 
	--> add Controls
	cc.controls.addrange btns
	scrollUC.controls.add scrollBar
	mainUC.controls.addrange #(cc, scrollUC)
	form.controls.add mainUC
	-->>> add Events
	fn onSizeChanged s e =
	(
		scrollBar.Height = amin s.Height (scrollUC.height*(mainUC.Height as float/cc.Height))
		if mainUC.Height >= cc.Height do cc.Location.y = scrollBar.Location.y = 0
	)
	fn onMouseDown s e = 
	(
		local crs = dotnetclass "Cursors"
		if s.Height != s.Parent.Height then (s.Cursor.Current = crs.Hand ; s.tag = #(e.y,0))
		else (s.Cursor.Current = crs.Default ; s.tag = #(e.y,1))
	)
	fn onMouseMove s e = 
	(
		local crs = dotnetclass "Cursors", tag
		case e.Button of
		(
			(e.Button.None): (s.Cursor.Current = if s.Height != s.Parent.Height then crs.Hand else crs.Default)			
			(e.Button.Left): if s.Height == s.Parent.Height then (tag = s.tag ; tag[2] = 0 ; s.tag = tag) else
			(
				tag = s.tag ; d = e.y - tag[1] ; tag[2] = 1
				s.location.y = amin (s.Parent.Height - s.Height) (amax 0 (s.location.y + d))
				s.tag = tag
			)
		)
	)
	dotnet.addeventhandler scrollBar "Move" (fn scroll s e = (cc.Location.y = -s.Location.y/(mainUC.Height as float/cc.Height)))
	dotnet.addeventhandler scrollBar "MouseDown" onMouseDown
	dotnet.addeventhandler scrollBar "MouseMove" onMouseMove
	dotnet.addEventHandler form "SizeChanged" onSizeChanged
	allControls = join btns #(form, mainUC, scrollUC, scrollBar, cc)
	setLifetimeControl allControls
	onSizeChanged form undefined
	--cc.VerticalScroll.Maximum = cc.PreferredSize.Height - cc.Height
	
	form.Show(maxHW())	
)
 For me .net Label is most adjustable control for custom controls creations.

Now I want to adjust form event “SizeChanged” to be able to control location of “cc” label.

woooooooooooooooow, great – This is fantastic!!!

Branko, Everything works just perfect at me, the only thing is that I get this error

undefined
ccheight 400
undefined
– Error occurred in onMouseMove(); filename: C:\Users\SkyDrive\scripts…; position: 2934; line: 72
– Frame:
– c: undefined
– e: dotNetObject:System.Windows.Forms.MouseEventArgs
– crs: dotNetClass:System.Windows.Forms.Cursors
– s: dotNetObject:System.Windows.Forms.Label
– tag: undefined
– d: undefined
>> MAXScript dotNet event handler Exception:
– Unknown property: “Hand” in undefined <<

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

I edited code above.
I was changed Cursor variable name and forgot to change on other places in the code.
Hope that’s works now

Page 2 / 5