Notifications
Clear all

[Closed] How to make your own Timeline (NOT ENCRYPTED)

 lo1

Only screen wrapping

NumericUpDown doesn’t catch Enter key… i don’t want to do any User32 things. but I can’t find another solution yet.

This is my try to use TextBox for Numeric input (see attachment).
But maybe this is not the best solution.:hmm:
I do not know whether you’re planning to add something similar like THIS in your script
It’s not bad idea.

LO means that when we drag mouse UP/DOWN it stops on screen edges. That’s the right point.

here is a version that fixes this problem. It calls edgeless mouse movement. Also I stick X cursor position during dragging, and change cursor to Size North/South…


fn makeTimeSpinner width:60 value:0 onChange: =
(
	sp = dotnetobject "NumericUpDown"
	sp.Width = width
	sp.Backcolor = backcolor
	
	sp.Minimum = -1e9
	sp.Maximum = 1e9
	sp.Value = value
	
	fn onGotFocus s e = enableAccelerators = off
	fn onLostFocus s e = 
	(
		s.Text = s.Value as string
		enableAccelerators = on
	)
	dotnet.addeventhandler sp "GotFocus" onGotFocus
	dotnet.addeventhandler sp "LostFocus" onLostFocus

	fn onKeyPress s e = 
	(
		char = dotnetclass "System.Char"
		c = e.KeyChar
		if not (char.IsControl c) and not (char.IsDigit c) do
		(
			e.Handled = not ((c == "-") and (findstring s.Text c) == undefined)
		)
	)
	dotnet.addeventhandler sp "KeyPress" onKeyPress
	fn onTextChanged s e = 
	(
		if s.Text != "-" and s.Text as Integer == undefined do
		(
			t = s.Controls.Item[1]
			i = amax 1 t.SelectionStart
			s.Text = replace s.Text i 1 ""

			t.SelectionStart = i-1
			t.SelectionLength = 0
		)
	)
	dotnet.addeventhandler sp "TextChanged" onTextChanged

	fn onMouseDown s e = 
	(
		tag = s.tag
		case e.Button of
		(
			 (e.Button.Left): tag[2] == e.y
			(e.Button.Right): if tag[3] == 1 do s.value = tag[1]
		)
		s.tag = tag
	)
	dotnet.addeventhandler sp "MouseDown" onMouseDown
	fn onMouseUp s e = 
	(
		tag = s.tag
		case e.Button of
		(
			 (e.Button.Left): tag[1] == s.value
			(e.Button.Right): if tag[3] == 0 do s.value = 0
		)
		s.tag = tag
	)
	dotnet.addeventhandler sp "MouseUp" onMouseUp
	fn onMouseMove s e = 
	(
		p = s.Cursor.Current.Position
		tag = s.tag
		
		case e.Button of
		(
			(e.Button.Left):
			(
				s.Cursor.Current = (dotnetclass "System.Windows.Forms.Cursors").SizeNS
				
				h = (dotnetclass "SystemInformation").VirtualScreen.Height 
				
				if act = (p.x != tag[4]) do p.x = tag[4]
				case p.y of 
				(
					0:  
					(
						p.y = h-1 
						tag[2] += h-2
						act = on
					)
					(h-1):
					(
						p.y = 0
						tag[2] -= h-2
						act = on
					)
				)
				if act do s.Cursor.Current.Position = p
			
				tag[3] = 1
				s.value = tag[1] + (tag[2] - e.y)*s.Increment 
				
				s.tag = tag
			)
			(e.Button.None): 
			(
				s.Cursor.Current = (dotnetclass "System.Windows.Forms.Cursors").Arrow
				s.tag = #(s.value, e.y, 0, p.x)
			)
		)
	)
	dotnet.addeventhandler sp "MouseMove" onMouseMove

	if onChange != unsupplied do dotnet.addeventhandler sp "ValueChanged" onChange
		
	sp.tag = #(sp.value,0,0,0)
	sp
)

try(destroydialog timelineRollout) catch()
rollout timelineRollout "timelineRollout" width:200 height:24
(
	dotnetcontrol panel "UserControl" pos:[0,0] height:24

	on timelineRollout open do
	(
		sp = makeTimeSpinner()
		sp.Dock = sp.Dock.Left
		panel.controls.addrange #(sp)
		dotnet.setLifetimeControl sp #dotnet
	)
)
createdialog timelineRollout

2 Replies
 lo1
(@lo1)
Joined: 1 year ago

Posts: 0

That is almost exactly how I did it, except you still have one very minor problem.
SystemInformation.VirtualScreen will get you the maximum height of your monitors.

For example, I am using one 19201200 monitor and one 12801024 monitor. In this case VirtualScreen.Height returns 1200. Therefore, the spinner does not wrap properly on the smaller monitor. It is better to use system.windows.forms.screen.frompoint to get the correct screen each time.

(@denist)
Joined: 1 year ago

Posts: 0

i thought about something like that… that’s why i stick the X position. i will check what we can do with it…

to make our spinner almost perfect we have to solve two problems:
#1 support Enter and Escape keys to set or reset the value
#2 disable this annoying BEEP when a wrong key is pressed. (letters, some controls, symbols, ect.)

2 Replies
(@denist)
Joined: 1 year ago

Posts: 0

the problem #1… I know how to solve it using User32 (and I’ve showed it ones in some thread) but I want to make the project without any extra (including on-fly compiled) assembly.

(@denist)
Joined: 1 year ago

Posts: 0

dammit… it seems like i can’t solve #2 without overriding onKeyPress… But maybe anyone can show 100% right and elegant enough way to convert KeyCode (or KeyData) to KeyChar?

start with the second problem… to solve it we need some key event that fires before KeyPressed (which is making the BEEP) and is being able to Suspend the Key.
well… there is only one event that can help us – KeyDown and its KeyEventArgs.

to be continued…

that’s way i decided to stick with spinners

following LO’s advice we need to change the code to:


 --h = (dotnetclass "SystemInformation").VirtualScreen.Height 
   h = ((dotnetclass "Screen").FromPoint p).Bounds.Height
  

right, LO?

 lo1

Yes, I approve

hmm… probably not… bounds return me maximum resolution. WorkingArea could be a solutuion, but it returns the actual size minus height of windows taskbar… which is not right too.

4 Replies
 lo1
(@lo1)
Joined: 1 year ago

Posts: 0

What do you mean by maximum resolution? It seems right to me. bounds.Height Returns 1200 on my big screen and 1024 on my small screen.

(@denist)
Joined: 1 year ago

Posts: 0

i set two screens: 1920 x 1200 and 1680 x 1050

((dotnetclass “Screen”).FromPoint (dotnetobject “System.Drawing.Point” 3000 20)).Bounds.Height
returns me 1200

 lo1
(@lo1)
Joined: 1 year ago

Posts: 0

I assume the big screen is on the left, and is the one with the taskbar?

(@denist)
Joined: 1 year ago

Posts: 0

correct…

Page 2 / 8