Select the time for the timer

Just starting out? Need help? Post your questions and find answers here.
AZJIO
Addict
Addict
Posts: 2183
Joined: Sun May 14, 2017 1:48 am

Select the time for the timer

Post by AZJIO »

I've previously tried making a handy time setter for the timer, but nothing worked. Now I'm trying again using CanvasGadget.
Maybe someone would like to give it a try too?

Button

Code: Select all

Global Dim ListTimer(10, 4) ; двумерный массив
#Window_1 = 0
Procedure OpenWindow_Window_1(index)
	If OpenWindow(#Window_1, #PB_Ignore, #PB_Ignore, 500, 500, "Задатчик", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
		
		
		; 		For i = 1 To 24
		; 		    ButtonGadget(i+1000 , Cos(i*1.7)*60+110 , Sin(i*1.7)*60+110 , 30 , 30 , Str(i), #PB_Button_Toggle)
		; 		Next
		
		j=0
		For i=0 To 359 Step 15
			ButtonGadget(j+1000 , 160 * Cos(Radian(i-90))+230 , 160 * Sin(Radian(i-90))+230 , 30 , 30 , Str(j), #PB_Button_Toggle)
			j+1
		Next
		j=0
		For i=0 To 359 Step 6
			ButtonGadget(j+1100 , 236 * Cos(Radian(i-90))+239 , 236 * Sin(Radian(i-90))+239 , 19 , 19 , Str(j), #PB_Button_Toggle)
			j+1
		Next
		
		ListTimer(index, 3) = 0
		ListTimer(index, 4) = 0
		
		; Обработать гаджеты только этого окна
		Repeat
			Select WaitWindowEvent()
				Case #PB_Event_Gadget
					EvnGd = EventGadget()
					Select EvnGd
						Case 1000 To 1023
							For i=1000 To 1023
								If GetGadgetState(EvnGd) = 1 And i <> EvnGd
									SetGadgetState(i , 0)
									ListTimer(index, 3) = EvnGd - 1000
								EndIf
							Next
						Case 1100 To 1159
							For i=1100 To 1159
								If GetGadgetState(EvnGd) = 1 And i <> EvnGd
									SetGadgetState(i , 0)
									ListTimer(index, 4) = EvnGd - 1100
								EndIf
							Next
					EndSelect
				Case #PB_Event_CloseWindow
					EventWindow = EventWindow()
					If EventWindow = #Window_1
						CloseWindow(#Window_1)
						Break
					EndIf
			EndSelect
		ForEver
	EndIf
EndProcedure

index = 1
OpenWindow_Window_1(index)
Debug Str(ListTimer(index, 3)) + ":" + Str(ListTimer(index, 4))
Canvas

Code: Select all

; EnableExplicit
Define R, R2, color, j, i, x, y, p, RClick

#Red1 = $8888FF
#Green1 = $88FF88
#Window_1 = 0
#cnvs = 0
R=12
R2=20
If OpenWindow(#Window_1, #PB_Ignore, #PB_Ignore, 500, 500, "time", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
color = #Red1
	CanvasGadget(#cnvs, 0 , 0 , 500, 500)
	If StartDrawing(CanvasOutput(#cnvs))
		j = 0
		For i = 0 To 359 Step 15
			x = 160 * Cos(Radian(i - 90)) + 230 + R2
			y = 160 * Sin(Radian(i - 90)) + 230 + R2
			Circle(x, y, R2, color)
			DrawText(x - R2/3, y - R2/3, Str(i/15), 0, color)
			j + 1
			If j = 3
				j = 0
				color = #Red1
			Else
				color = #Green1
			EndIf
		Next
		j = 0
		For i = 0 To 359 Step 6
			x = 236 * Cos(Radian(i - 90)) + 239 + R
			y = 236 * Sin(Radian(i - 90)) + 239 + R
			Circle(x, y, R , color)
			DrawText(x - R/2, y - R/2, Str(i/6), 0, color)
			j + 1
			If j = 5
				j = 0
				color = #Red1
			Else
				color = #Green1
			EndIf
		Next
		StopDrawing()
	EndIf


		;- Loop
	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #cnvs
						If EventType() = #PB_EventType_LeftButtonDown
							x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
							y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
							x - 250
							y - 250
							If x > 0
								If y > 0
									p = 1
								Else
									p = 2
								EndIf
							Else
								If y > 0
									p = 4
								Else
									p = 3
								EndIf
							EndIf
; 							x = Abs(x)
; 							y = Abs(y)
; 							RClick = Sqr(Pow(x, 2) + Pow(y, 2))
							RClick = Sqr(Pow(Abs(y), 2) + Pow(Abs(y), 2))
							If RClick > 200
								Debug "minutes"
							Else
								Debug "hours"
; 								Это неправильно, я пытаюсь найти четверть и вычислить число.
; 								Мне нужно получить градус угла, чтобы понять число.
								Select p
									Case 1
										Debug Sin(x/RClick) * 6
									Case 2
										Debug Cos(x/RClick) * 6
									Case 3
										Debug Sin(x/RClick) * 6 + 12
									Case 4
										Debug Cos(x/RClick) * 6 + 12
								EndSelect
							EndIf
						EndIf
				EndSelect
			Case #PB_Event_CloseWindow
				CloseWindow(0)
				End
		EndSelect
	ForEver
EndIf
User avatar
idle
Always Here
Always Here
Posts: 5888
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Select the time for the timer

Post by idle »

like this maybe?

Code: Select all

EnableExplicit
#Red1 = $8888FF
#Green1 = $88FF88
#Window_1 = 0
#cnvs = 0

Structure button 
  x.f
  y.f
  r.f
  tw.i
  th.i
  text.s
  backcolor.i 
  FrontColor.i 
EndStructure 

Global Dim bMinute.button(60) 
Global Dim bhour.button(24) 

Procedure SetMinutes(canvas,r1,r2)  
  
  Protected w.f = (GadgetWidth(canvas) / 2) - r2 
  Protected h.f = (GadgetHeight(canvas) / 2) - r2 
  Protected color =#Red1
  Protected a.i,j.i,i.f = (360/60)
  For a = 1 To 60 
    bMinute(a)\x = w * Cos(Radian(a * i - 90)) + w + r2
    bMinute(a)\y = w * Sin(Radian(a * i - 90)) + w + r2
    bMinute(a)\backcolor = color 
    bMinute(a)\text = Str(a) 
    bMinute(a)\r = r1 
    
    j + 1
    If j = 3
      j = 0
      color = #Red1
    Else
      color = #Green1
    EndIf
  Next
  
EndProcedure 

Procedure SetHours(canvas,r1,r2)  
  Protected w.f = (GadgetWidth(canvas) / 2) - r2 
  Protected h.f = (GadgetHeight(canvas) / 2) - r2 
  Protected color =#Red1
  Protected a.i,j.i,i.f = (360/24)
  
  For a = 1 To 24 
    bhour(a)\x = w * Cos(Radian(a * i - 90)) + w + r2
    bhour(a)\y = w * Sin(Radian(a * i - 90)) + w + r2
    bhour(a)\backcolor = color 
    bhour(a)\text = Str(a) 
    bhour(a)\r = r1 
    
    j + 1
    If j = 3
      j = 0
      color = #Red1
    Else
      color = #Green1
    EndIf
  Next
  
EndProcedure   

Procedure checkhit(canvas,x,y) 
  Protected a,dx.f,dy.f 
  
  For a = 1 To 60 
    dx = (x - bMinute(a)\x) 
    dy = (y - bMinute(a)\y) 
    If (Abs(dx) < bMinute(a)\r And Abs(dy) < bMinute(a)\r)
      Debug "min " + bMinute(a)\text
      If bMinute(a)\backcolor = #RED1 
        bMinute(a)\backcolor = #Green1
      Else 
        bMinute(a)\backcolor = #Red1
      EndIf
      If StartDrawing(CanvasOutput(canvas))
        Circle(bMinute(a)\x,bMinute(a)\y,bMinute(a)\r,bMinute(a)\backcolor) 
        DrawText(bMinute(a)\x-bMinute(a)\tw/2,bMinute(a)\y-bMinute(a)\th/2,bMinute(a)\text,0,bMinute(a)\backcolor)
        StopDrawing()  
      EndIf 
      
    EndIf 
  Next   
  
  For a = 1 To 24 
    dx = (x - bhour(a)\x) 
    dy = (y - bhour(a)\y) 
    If (Abs(dx) < bhour(a)\r And Abs(dy) < bhour(a)\r)
      Debug "Hour " + bhour(a)\text
      If bhour(a)\backcolor = #RED1 
        bhour(a)\backcolor = #Green1
      Else 
        bhour(a)\backcolor = #Red1
      EndIf
      If StartDrawing(CanvasOutput(canvas))
        Circle(bhour(a)\x,bhour(a)\y,bhour(a)\r,bhour(a)\backcolor) 
         DrawText(bhour(a)\x-bhour(a)\tw/2,bhour(a)\y-bhour(a)\th/2,bhour(a)\text,0,bhour(a)\backcolor)
        StopDrawing()  
      EndIf 
      
    EndIf 
  Next   
  
EndProcedure 

Procedure Resize(window,canvas,color) 
  
  Protected a,cx.f,cy.f
  
  ResizeWindow(Window,WindowX(Window),WindowY(Window),WindowWidth(Window),WindowWidth(Window))
  ResizeGadget(canvas,0,0,WindowWidth(Window),WindowWidth(Window))
  SetMinutes(canvas,12,20) 
  SetHours(canvas,20,90) 
  
  If StartDrawing(CanvasOutput(canvas))
    Box( 0,0,WindowWidth(Window),WindowWidth(Window),color)	     
    For a = 1 To 60 
      bMinute(a)\tw = TextWidth(Str(a)) 
      bMinute(a)\th = TextHeight(Str(a)) 
      Circle(bMinute(a)\x,bMinute(a)\y,bMinute(a)\r,bMinute(a)\backcolor) 
      DrawText(bMinute(a)\x-bMinute(a)\tw/2,bMinute(a)\y-bMinute(a)\th/2,bMinute(a)\text,0,bMinute(a)\backcolor)
    Next   
    For a = 1 To 24 
      bhour(a)\tw = TextWidth(Str(a)) 
      bhour(a)\th = TextHeight(Str(a)) 
      Circle(bhour(a)\x,bhour(a)\y,bhour(a)\r,bhour(a)\backcolor) 
      DrawText(bhour(a)\x-bhour(a)\tw/2,bhour(a)\y-bhour(a)\th/2,bhour(a)\text,0,bhour(a)\backcolor)
    Next    
    StopDrawing()
  EndIf
  
EndProcedure  

Define a.i
If OpenWindow(#Window_1, #PB_Ignore, #PB_Ignore, 500, 500, "time", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
  
  CanvasGadget(#cnvs, 0 , 0 , 500, 500)
  SetMinutes(#cnvs,12,20) 
  SetHours(#cnvs,20,90) 
  resize(#Window_1,#cnvs,$FFFFFFFF) 
  ;- Loop
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #cnvs
            If EventType() = #PB_EventType_LeftButtonDown
              checkhit(#cnvs, GetGadgetAttribute(0, #PB_Canvas_MouseX),GetGadgetAttribute(0, #PB_Canvas_MouseY))
            EndIf
        EndSelect
      Case #PB_Event_SizeWindow 
        resize(#Window_1,#cnvs,$FFFFFFFF) 
      Case #PB_Event_CloseWindow
        CloseWindow(0)
        End
    EndSelect
  ForEver
EndIf
AZJIO
Addict
Addict
Posts: 2183
Joined: Sun May 14, 2017 1:48 am

Re: Select the time for the timer

Post by AZJIO »

idle wrote: Sat May 31, 2025 1:16 am like this maybe?
Thanks
Added a few changes.

Code: Select all

EnableExplicit
; #Blue1 = $FFAAAA
#Blue1 = $FFAAFF
#Red1 = $8888FF
#Green1 = $88FF88
#Window_1 = 0
#cnvs = 0

Structure button
	x.f
	y.f
	r.f
	tw.i
	th.i
	text.s
	backcolor.i
	FrontColor.i
EndStructure

Global Dim bMinute.button(60)
Global Dim bhour.button(24)
Global ShowHour = 1

Procedure SetMinutes(canvas, r1, r2)

	Protected w.f = (GadgetWidth(canvas) / 2) - r2
	Protected h.f = (GadgetHeight(canvas) / 2) - r2
	Protected color = #Green1
	Protected a.i, j.i, i.f = (360 / 60)

	For a = 1 To 60
		j + 1
		If j = 5
			j = 0
			color = #Red1
		Else
			color = #Green1
		EndIf
		bMinute(a)\x = w * Cos(Radian(a * i - 90)) + w + r2
		bMinute(a)\y = w * Sin(Radian(a * i - 90)) + w + r2
		bMinute(a)\backcolor = color
		bMinute(a)\text = Str(a)
		bMinute(a)\r = r1

	Next

EndProcedure

Procedure SetHours(canvas, r1, r2)
	Protected w.f = (GadgetWidth(canvas) / 2) - r2
	Protected h.f = (GadgetHeight(canvas) / 2) - r2
	Protected color = #Green1
	Protected a.i, j.i, i.f = (360 / 24)

	For a = 1 To 24
		j + 1
		If j = 3
			j = 0
			color = #Red1
		Else
			color = #Green1
		EndIf
		bhour(a)\x = w * Cos(Radian(a * i - 90)) + w + r2
		bhour(a)\y = w * Sin(Radian(a * i - 90)) + w + r2
		bhour(a)\backcolor = color
		bhour(a)\text = Str(a)
		bhour(a)\r = r1

	Next

EndProcedure

Procedure checkhit(canvas, x, y)
	Protected a, dx.f, dy.f
	Static oldM
	Static oldH

	If oldM
		If Mod(oldM, 5)
			bMinute(oldM)\backcolor = #Green1
		Else
			bMinute(oldM)\backcolor = #Red1
		EndIf
		If StartDrawing(CanvasOutput(canvas))
			Circle(bMinute(oldM)\x, bMinute(oldM)\y, bMinute(oldM)\r, bMinute(oldM)\backcolor)
			DrawText(bMinute(oldM)\x - bMinute(oldM)\tw / 2, bMinute(oldM)\y - bMinute(oldM)\th / 2, bMinute(oldM)\text, 0, bMinute(oldM)\backcolor)
			StopDrawing()
		EndIf
	EndIf
	For a = 1 To 60
		dx = (x - bMinute(a)\x)
		dy = (y - bMinute(a)\y)
		If (Abs(dx) < bMinute(a)\r And Abs(dy) < bMinute(a)\r)
			oldM = a
			Debug "min " + bMinute(a)\text
			bMinute(a)\backcolor = #Blue1
			If StartDrawing(CanvasOutput(canvas))
				Circle(bMinute(a)\x, bMinute(a)\y, bMinute(a)\r, bMinute(a)\backcolor)
				DrawText(bMinute(a)\x - bMinute(a)\tw / 2, bMinute(a)\y - bMinute(a)\th / 2, bMinute(a)\text, 0, bMinute(a)\backcolor)
				StopDrawing()
			EndIf
			Break

		EndIf
	Next

	If ShowHour

		If oldH
			If Mod(oldH, 3)
				bhour(oldH)\backcolor = #Green1
			Else
				bhour(oldH)\backcolor = #Red1
			EndIf
			If StartDrawing(CanvasOutput(canvas))
				Circle(bhour(oldH)\x, bhour(oldH)\y, bhour(oldH)\r, bhour(oldH)\backcolor)
				DrawText(bhour(oldH)\x - bhour(oldH)\tw / 2, bhour(oldH)\y - bhour(oldH)\th / 2, bhour(oldH)\text, 0, bhour(oldH)\backcolor)
				StopDrawing()
			EndIf
		EndIf

		For a = 1 To 24
			dx = (x - bhour(a)\x)
			dy = (y - bhour(a)\y)
			If (Abs(dx) < bhour(a)\r And Abs(dy) < bhour(a)\r)
				oldH = a
				Debug "Hour " + bhour(a)\text
				bhour(a)\backcolor = #Blue1
				If StartDrawing(CanvasOutput(canvas))
					Circle(bhour(a)\x, bhour(a)\y, bhour(a)\r, bhour(a)\backcolor)
					DrawText(bhour(a)\x - bhour(a)\tw / 2, bhour(a)\y - bhour(a)\th / 2, bhour(a)\text, 0, bhour(a)\backcolor)
					StopDrawing()
				EndIf
				Break
			EndIf
		Next
	EndIf

EndProcedure

Procedure Resize(window, canvas, color)

	Protected a, cx.f, cy.f

	ResizeWindow(Window, WindowX(Window), WindowY(Window), WindowWidth(Window), WindowWidth(Window))
	ResizeGadget(canvas, 0, 0, WindowWidth(Window), WindowWidth(Window))
	SetMinutes(canvas, 12, 20)
	If ShowHour
		SetHours(canvas, 20, 90)
	EndIf

	If StartDrawing(CanvasOutput(canvas))
		Box( 0, 0, WindowWidth(Window), WindowWidth(Window), color)
		For a = 1 To 60
			bMinute(a)\tw = TextWidth(Str(a))
			bMinute(a)\th = TextHeight(Str(a))
			Circle(bMinute(a)\x, bMinute(a)\y, bMinute(a)\r, bMinute(a)\backcolor)
			DrawText(bMinute(a)\x - bMinute(a)\tw / 2, bMinute(a)\y - bMinute(a)\th / 2, bMinute(a)\text, 0, bMinute(a)\backcolor)
		Next
		If ShowHour
			For a = 1 To 24
				bhour(a)\tw = TextWidth(Str(a))
				bhour(a)\th = TextHeight(Str(a))
				Circle(bhour(a)\x, bhour(a)\y, bhour(a)\r, bhour(a)\backcolor)
				DrawText(bhour(a)\x - bhour(a)\tw / 2, bhour(a)\y - bhour(a)\th / 2, bhour(a)\text, 0, bhour(a)\backcolor)
			Next
		EndIf
		StopDrawing()
	EndIf

EndProcedure

Define a.i
If OpenWindow(#Window_1, #PB_Ignore, #PB_Ignore, 500, 500, "time", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)

	CanvasGadget(#cnvs, 0 , 0 , 500, 500)
	SetMinutes(#cnvs, 12, 20)
	If ShowHour
		SetHours(#cnvs, 20, 90)
	EndIf
	resize(#Window_1, #cnvs, $FFFFFFFF)
  ;- Loop
	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #cnvs
						If EventType() = #PB_EventType_LeftButtonDown
							checkhit(#cnvs, GetGadgetAttribute(0, #PB_Canvas_MouseX), GetGadgetAttribute(0, #PB_Canvas_MouseY))
						EndIf
				EndSelect
			Case #PB_Event_SizeWindow
				resize(#Window_1, #cnvs, $FFFFFFFF)
			Case #PB_Event_CloseWindow
				CloseWindow(0)
				End
		EndSelect
	ForEver
EndIf
User avatar
Demivec
Addict
Addict
Posts: 4267
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Select the time for the timer

Post by Demivec »

Right now your checkhit() comparison looks to see if the mouse is within the square that contains the button. This means that it will detect a button hit even in the corners of the bounding box which aren't within the button's circle.

To have more precision in the checkhit() procedure use a comparison like:

Code: Select all

		If (Abs(dx) < bMinute(a)\r And Abs(dy) < bMinute(a)\r) And
		   (dx * dx + dy * dy) <= (bMinute(a)\r * bMinute(a)\r)
		  ;---contents snipped
		EndIf

;and

		If (Abs(dx) < bhour(a)\r And Abs(dy) < bhour(a)\r) And
		   (dx * dx + dy * dy) <= (bhour(a)\r * bhour(a)\r)
		  ;---contents snipped
		EndIf
The change will limit it to detect a hit only within a button. It only does the finer check if the mouse is already within the bounding box of the button.
Post Reply