Seite 1 von 1

Kalender

Verfasst: 04.07.2011 13:04
von Cläusel
Heyho!
Ich möchte einen Kalender programmieren in dem Termine als Balken angezeigt werden,
welche mit der Maus verschiebbar und in der Länge veränderbar sind.
Jetzt hab ich NULL Idee wie ich sowas anfange..
Was benutze ich als Grundfläche (Imagegadget.?) und welches Gadget würde sich als Balken eignen.
Oder was nimmt man am besten?

Gruß Cläusel
;o)

Re: Kalender

Verfasst: 04.07.2011 13:20
von ts-soft
Bei einem neuem Projekt spricht ja nichts gegen eine Beta Version von PB, die sollte ja hoffentlich bald fertig sein :wink:
Für solche Aufgaben sollte sich das neue CanvasGadget gut eignen. RMChart wäre auch eine Möglichkeit, wobei ich eher
zum CanvasGadget tendieren würde.

Gruß
Thomas

Re: Kalender

Verfasst: 04.07.2011 13:54
von Cläusel
Danke für die Antwort... <)
Müsste doch auch ohne Canvas oder RMChart gehen.. so ähnlich wie im Visual Designer
um Steuerelemente zu platzieren. Der VisualDesigner ist doch auch mal in PB geschreiben worden... oder?

Gruß Claus

Re: Kalender

Verfasst: 04.07.2011 14:00
von ts-soft
Was spricht den gegen das CanvasGadget? Einfach die aktuelle Beta downloaden.
Alles andere ginge nur mit viel API und sehr umständlich, aber gehen tut es. Ich
würde mir das aber eher verkneifen, wenn es nicht not tut :mrgreen:

Re: Kalender

Verfasst: 04.07.2011 14:05
von Cläusel
Werd ich gleich mal ausprobieren...
Danke erstmal!
Schreib dann meine Erfahrung damit... <)

Re: Kalender

Verfasst: 04.07.2011 21:03
von STARGÅTE
So, ich konnte es einfach nicht lasse, mit Hilfe des CanvasGadgets ein Beispiel zu schreiben:
Bild

Hier der "auf die schnelle hingeschmierte" Code, der natürlich noch verbessert werden kann.
Bis jetzt bietet er nur (was heißt nur, ist n ganze Menge ^^) die Möglichkeit, Termine zu verschieben, oder in der Länge zu ändern:

Code: Alles auswählen

;
;  !! PureBasic 4.60 !!
;

Enumeration
	#Window
EndEnumeration

Enumeration
	#Gadget
EndEnumeration

EnableExplicit

Structure Appointment
	TimeStamp.i		; in Sekunden
	Length.i			; in Stunden
	Color.i
	Text.s
EndStructure

Global NewList Appointment.Appointment()

Procedure AddAppointment(TimeStamp.i, Length.i, Color.i, Text.s)
	AddElement(Appointment())
	Appointment()\TimeStamp = TimeStamp - TimeStamp%3600
	Appointment()\Length = Length
	If Hour(Appointment()\TimeStamp) + Length > 24
		Appointment()\Length = 24-Hour(Appointment()\TimeStamp)
	EndIf 
	Appointment()\Color = Color
	Appointment()\Text = Text
EndProcedure

#HeaderWidth = 64
#HeaderHeight = 32

Procedure DrawCanvasContent(Gadget.i)
	
	Protected DayWidth.i, HourHeight.i, Text.s
	Protected Date = Date() : Date - Date%(24*60*60)
	Protected Day.i, Hour.i, X.i, Y.i
	
	StartDrawing(CanvasOutput(Gadget))
		Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)
		DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Transparent)
		DayWidth = (OutputWidth()-#HeaderWidth)/7
		HourHeight = (OutputHeight()-#HeaderHeight)/24
		Box(0, 0, OutputWidth(), #HeaderHeight, $FFF0F0F0)
		Box(0, #HeaderHeight, #HeaderWidth, OutputHeight()-#HeaderHeight, $FFF0F0F0)
		For Day = 0 To 6
			X = Day*DayWidth+#HeaderWidth
			Line(X, 0, 1, OutputHeight(), $FFD0D0D0)
			Text = FormatDate("%dd.%mm.", Date+Day*24*60*60)
			DrawText(X+DayWidth*0.5-TextWidth(Text)*0.5, #HeaderHeight*0.5-TextHeight(Text)*0.5, Text, $FFC0C0C0)
		Next
		For Hour = 0 To 23
			Y = Hour*HourHeight+#HeaderHeight
			Line(0, Y, OutputWidth(), 1, $FFD0D0D0)
			If Hour % 2 = 0
				Text = RSet(Str(Hour),2,"0")+" Uhr"
				DrawText(#HeaderWidth*0.5-TextWidth(Text)*0.5, Y, Text, $FFC0C0C0)
			EndIf
		Next
		ForEach Appointment()
			With Appointment()
				Day = DayOfYear(\TimeStamp)-DayOfYear(Date)
				Hour = Hour(\TimeStamp)
				X = Day*DayWidth+#HeaderWidth
				Y = Hour*HourHeight+#HeaderHeight
				DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Transparent)
				RoundBox(X+2, Y+2, DayWidth-3, \Length*HourHeight-3, 8, 8, \Color&$FFFFFF|$80<<24)
				DrawText(X+DayWidth*0.5-TextWidth(\Text)*0.5, Y+4, \Text, \Color&$FFFFFF|$FF<<24)
				DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Outlined)
				RoundBox(X+2, Y+2, DayWidth-3, \Length*HourHeight-3, 8, 8, \Color&$FFFFFF|$80<<24)
			EndWith
		Next
	StopDrawing()
	
EndProcedure


Procedure CanvasContentEvent(Gadget.i, EventType.i)
	
	Static *ActiveAppointment.Appointment
	Static ShiftY.i, SaveLength.i, SaveTimeStamp.i
	Protected DayWidth.i, HourHeight.i, Text.s, TimeStamp.i
	Protected Date = Date() : Date - Date%(24*60*60)
	Protected Day.i, Hour.i, X.i, Y.i, Length.i
	Protected MouseX.i = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
	Protected MouseY.i = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
	Protected *Appointment.Appointment
	Static Mode = #Null
	
	StartDrawing(CanvasOutput(Gadget))
		DayWidth = (OutputWidth()-#HeaderWidth)/7
		HourHeight = (OutputHeight()-#HeaderHeight)/24
	StopDrawing()
	If *ActiveAppointment = #Null
		ForEach Appointment()
			With Appointment()
				Day = DayOfYear(\TimeStamp)-DayOfYear(Date)
				Hour = Hour(\TimeStamp)
				X = Day*DayWidth+#HeaderWidth
				Y = Hour*HourHeight+#HeaderHeight
				Length = \Length*HourHeight
				If MouseX > X And MouseX < X+DayWidth And MouseY > Y And MouseY < Y+Length
					*Appointment = @Appointment()
					ShiftY = (MouseY-Y)/HourHeight
					If MouseY < Y+8 : Mode = -1 : ElseIf MouseY > Y+Length-8 : Mode = 1 : Else : Mode = 0 : EndIf
				EndIf
			EndWith
		Next
		If *Appointment
			Select Mode
				Case 0 : SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_Arrows)
				Case -1, 1 : SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
			EndSelect
			If EventType = #PB_EventType_LeftButtonDown
				*ActiveAppointment = *Appointment
				SaveTimeStamp = *ActiveAppointment\TimeStamp
				SaveLength = *ActiveAppointment\Length
			EndIf
		Else
			SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
		EndIf
	EndIf
	If EventType = #PB_EventType_LeftButtonUp
		*ActiveAppointment = #Null
	EndIf
	If *ActiveAppointment And EventType = #PB_EventType_MouseMove
		Select Mode
			Case 0
				Day = (MouseX-#HeaderWidth)/DayWidth
				If Day < 0 : Day = 0 : ElseIf Day > 6 : Day = 6 : EndIf
				Hour = (MouseY-#HeaderHeight)/HourHeight-ShiftY
				If Hour < 0 : Hour = 0 : ElseIf Hour+*ActiveAppointment\Length > 23 : Hour = 24-*ActiveAppointment\Length : EndIf
				*ActiveAppointment\TimeStamp = Date
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Day, Day)
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Hour, Hour)
			Case -1
				Day = DayOfYear(SaveTimeStamp)-DayOfYear(Date)
				Hour = (MouseY-#HeaderHeight)/HourHeight
				If Hour < 0 : Hour = 0 : ElseIf Hour > 23 : Hour = 23 : EndIf
				*ActiveAppointment\TimeStamp = Date
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Day, Day)
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Hour, Hour)
				*ActiveAppointment\Length = SaveLength - (*ActiveAppointment\TimeStamp-SaveTimeStamp)/60/60
				If *ActiveAppointment\Length < 1
					*ActiveAppointment\TimeStamp - 1 + *ActiveAppointment\Length*60*60
					*ActiveAppointment\Length = 1
				EndIf
			Case 1
				Day = DayOfYear(SaveTimeStamp)-DayOfYear(Date)
				Hour = (MouseY-#HeaderHeight)/HourHeight
				If Hour < 0 : Hour = 0 : ElseIf Hour > 23 : Hour = 23 : EndIf
				TimeStamp = Date
				TimeStamp = AddDate(TimeStamp, #PB_Date_Day, Day)
				TimeStamp = AddDate(TimeStamp, #PB_Date_Hour, Hour)
				*ActiveAppointment\Length = 1+(TimeStamp-SaveTimeStamp)/60/60
				If *ActiveAppointment\Length < 1
					*ActiveAppointment\Length = 1
				EndIf
		EndSelect
		DrawCanvasContent(Gadget)
	EndIf
	
EndProcedure


Define n.i

OpenWindow(#Window, 0, 0, 589, 632, "Fenster", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

	CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window), #PB_Canvas_GrabMouse)
	
	RandomSeed(1)
	For n = 1 To 10
		AddAppointment(Date()+Random(6*24*60*60), Random(6)+1, RGB(Random($80),Random($80),Random($80)), "Termin "+Str(n))
	Next
	DrawCanvasContent(#Gadget)
	
Repeat
	
	Select WaitWindowEvent()
			
		Case #PB_Event_CloseWindow
			End
			
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #Gadget
					CanvasContentEvent(#Gadget, EventType())
			EndSelect
			
	EndSelect
	
ForEver

Re: Kalender

Verfasst: 04.07.2011 21:10
von NicTheQuick
Bei mir unter Ubuntu wird nicht registriert, wenn die Maustaste los gelassen wird und dann wird das Fenster irgendwann grau, obwohl ich den Termin noch verschieben kann. Aber scheinbar werden dann die Events nicht mehr abgearbeitet.

Re: Kalender

Verfasst: 04.07.2011 21:14
von ts-soft
@STARGÅTE :allright:

Unter Ubuntu muss ich nach loslassen der Maus ein paar Sek. warten, bis es registriert wurde, könnte ein Bug sein.

Re: Kalender

Verfasst: 04.07.2011 21:37
von NicTheQuick
Ich habe gerade etwas heraus gefunden: Je länger ich die Maustaste gedrückt hatte, desto länger muss ich warten bis er das Loslassen registriert hat. Und da wird zwischenzeitlich auch mal das Fenster grau.

Sobald ich anfange einen Termin zu verschieben oder die Länge zu ändern, werden selbst nach dem Loslassen der Maustaste noch ewig lange Events gefeuert. Vielleicht sammeln die sich an durch's Neuzeichnen des Gadgets. Ich hab einfach in der Eventschleife noch ein 'Default: Debug "Event"' eingefügt um das zu testen.

///Edit 1:
Ja, es lag daran, dass das CanvasGadget auch dann neu gezeichnet wurde, wenn man die Maus nur ein Stückchen bewegt hatte, ohne dass sich aber etwas am Termin geändert hatte. Der folgende Code zeichnet nur dann neu, wenn sich wirklich was geändert hat. Trotzdem ist es nicht schön, dass es unter Linux so derartig ruckelt, wenn es das unter Windows scheinbar nicht tut. Die Zeichenroutinen scheinen wohl wirklich recht langsam zu sein.

Code: Alles auswählen

;
;  !! PureBasic 4.60 !!
;

Enumeration
	#Window
EndEnumeration

Enumeration
	#Gadget
EndEnumeration

EnableExplicit

Structure Appointment
	TimeStamp.i      ; in Sekunden
	Length.i         ; in Stunden
	Color.i
	Text.s
EndStructure

Global NewList Appointment.Appointment()

Procedure AddAppointment(TimeStamp.i, Length.i, Color.i, Text.s)
	AddElement(Appointment())
	Appointment()\TimeStamp = TimeStamp - TimeStamp%3600
	Appointment()\Length = Length
	If Hour(Appointment()\TimeStamp) + Length > 24
		Appointment()\Length = 24-Hour(Appointment()\TimeStamp)
	EndIf
	Appointment()\Color = Color
	Appointment()\Text = Text
EndProcedure

#HeaderWidth = 64
#HeaderHeight = 32

Procedure DrawCanvasContent(Gadget.i)
	
	Protected DayWidth.i, HourHeight.i, Text.s
	Protected Date = Date() : Date - Date%(24*60*60)
	Protected Day.i, Hour.i, X.i, Y.i
	
	StartDrawing(CanvasOutput(Gadget))
	Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)
	DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Transparent)
	DayWidth = (OutputWidth()-#HeaderWidth)/7
	HourHeight = (OutputHeight()-#HeaderHeight)/24
	Box(0, 0, OutputWidth(), #HeaderHeight, $FFF0F0F0)
	Box(0, #HeaderHeight, #HeaderWidth, OutputHeight()-#HeaderHeight, $FFF0F0F0)
	For Day = 0 To 6
		X = Day*DayWidth+#HeaderWidth
		Line(X, 0, 1, OutputHeight(), $FFD0D0D0)
		Text = FormatDate("%dd.%mm.", Date+Day*24*60*60)
		DrawText(X+DayWidth*0.5-TextWidth(Text)*0.5, #HeaderHeight*0.5-TextHeight(Text)*0.5, Text, $FFC0C0C0)
	Next
	For Hour = 0 To 23
		Y = Hour*HourHeight+#HeaderHeight
		Line(0, Y, OutputWidth(), 1, $FFD0D0D0)
		If Hour % 2 = 0
			Text = RSet(Str(Hour),2,"0")+" Uhr"
			DrawText(#HeaderWidth*0.5-TextWidth(Text)*0.5, Y, Text, $FFC0C0C0)
		EndIf
	Next
	ForEach Appointment()
		With Appointment()
			Day = DayOfYear(\TimeStamp)-DayOfYear(Date)
			Hour = Hour(\TimeStamp)
			X = Day*DayWidth+#HeaderWidth
			Y = Hour*HourHeight+#HeaderHeight
			DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Transparent)
			RoundBox(X+2, Y+2, DayWidth-3, \Length*HourHeight-3, 8, 8, \Color&$FFFFFF|$80<<24)
			DrawText(X+DayWidth*0.5-TextWidth(\Text)*0.5, Y+4, \Text, \Color&$FFFFFF|$FF<<24)
			DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Outlined)
			RoundBox(X+2, Y+2, DayWidth-3, \Length*HourHeight-3, 8, 8, \Color&$FFFFFF|$80<<24)
		EndWith
	Next
	StopDrawing()
	
EndProcedure


Procedure CanvasContentEvent(Gadget.i, EventType.i)
	
	Static *ActiveAppointment.Appointment
	Static ShiftY.i, SaveLength.i, SaveTimeStamp.i
	Protected DayWidth.i, HourHeight.i, Text.s, TimeStamp.i
	Protected Date = Date() : Date - Date%(24*60*60)
	Protected Day.i, Hour.i, X.i, Y.i, Length.i
	Protected MouseX.i = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
	Protected MouseY.i = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
	Protected *Appointment.Appointment
	Static Mode = #Null
	
	StartDrawing(CanvasOutput(Gadget))
	DayWidth = (OutputWidth()-#HeaderWidth)/7
	HourHeight = (OutputHeight()-#HeaderHeight)/24
	StopDrawing()
	If *ActiveAppointment = #Null
		ForEach Appointment()
			With Appointment()
				Day = DayOfYear(\TimeStamp)-DayOfYear(Date)
				Hour = Hour(\TimeStamp)
				X = Day*DayWidth+#HeaderWidth
				Y = Hour*HourHeight+#HeaderHeight
				Length = \Length*HourHeight
				If MouseX > X And MouseX < X+DayWidth And MouseY > Y And MouseY < Y+Length
					*Appointment = @Appointment()
					ShiftY = (MouseY-Y)/HourHeight
					If MouseY < Y+8 : Mode = -1 : ElseIf MouseY > Y+Length-8 : Mode = 1 : Else : Mode = 0 : EndIf
				EndIf
			EndWith
		Next
		If *Appointment
			Select Mode
				Case 0 : SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_Arrows)
				Case -1, 1 : SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
			EndSelect
			If EventType = #PB_EventType_LeftButtonDown
				*ActiveAppointment = *Appointment
				SaveTimeStamp = *ActiveAppointment\TimeStamp
				SaveLength = *ActiveAppointment\Length
			EndIf
		Else
			SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
		EndIf
	EndIf
	If EventType = #PB_EventType_LeftButtonUp
		*ActiveAppointment = #Null
	EndIf
	If *ActiveAppointment And EventType = #PB_EventType_MouseMove
		Protected old.Appointment
		CopyStructure(*ActiveAppointment, @old, Appointment)
		Select Mode
			Case 0
				Day = (MouseX-#HeaderWidth)/DayWidth
				If Day < 0 : Day = 0 : ElseIf Day > 6 : Day = 6 : EndIf
				Hour = (MouseY-#HeaderHeight)/HourHeight-ShiftY
				If Hour < 0 : Hour = 0 : ElseIf Hour+*ActiveAppointment\Length > 23 : Hour = 24-*ActiveAppointment\Length : EndIf
				*ActiveAppointment\TimeStamp = Date
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Day, Day)
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Hour, Hour)
			Case -1
				Day = DayOfYear(SaveTimeStamp)-DayOfYear(Date)
				Hour = (MouseY-#HeaderHeight)/HourHeight
				If Hour < 0 : Hour = 0 : ElseIf Hour > 23 : Hour = 23 : EndIf
				*ActiveAppointment\TimeStamp = Date
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Day, Day)
				*ActiveAppointment\TimeStamp = AddDate(*ActiveAppointment\TimeStamp, #PB_Date_Hour, Hour)
				*ActiveAppointment\Length = SaveLength - (*ActiveAppointment\TimeStamp-SaveTimeStamp)/60/60
				If *ActiveAppointment\Length < 1
					*ActiveAppointment\TimeStamp - 1 + *ActiveAppointment\Length*60*60
					*ActiveAppointment\Length = 1
				EndIf
			Case 1
				Day = DayOfYear(SaveTimeStamp)-DayOfYear(Date)
				Hour = (MouseY-#HeaderHeight)/HourHeight
				If Hour < 0 : Hour = 0 : ElseIf Hour > 23 : Hour = 23 : EndIf
				TimeStamp = Date
				TimeStamp = AddDate(TimeStamp, #PB_Date_Day, Day)
				TimeStamp = AddDate(TimeStamp, #PB_Date_Hour, Hour)
				*ActiveAppointment\Length = 1+(TimeStamp-SaveTimeStamp)/60/60
				If *ActiveAppointment\Length < 1
					*ActiveAppointment\Length = 1
				EndIf
		EndSelect
		If (*ActiveAppointment\TimeStamp <> old\TimeStamp Or *ActiveAppointment\Length <> old\Length)
			DrawCanvasContent(Gadget)
		EndIf
	EndIf
	
EndProcedure


Define n.i

OpenWindow(#Window, 0, 0, 589, 632, "Fenster", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window), #PB_Canvas_GrabMouse)

RandomSeed(1)
For n = 1 To 10
	AddAppointment(Date()+Random(6*24*60*60), Random(6)+1, RGB(Random($80),Random($80),Random($80)), "Termin "+Str(n))
Next
DrawCanvasContent(#Gadget)

Repeat
	
	Select WaitWindowEvent()
			
		Case #PB_Event_CloseWindow
			End
			
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #Gadget
					CanvasContentEvent(#Gadget, EventType())
			EndSelect
	EndSelect
	
ForEver
///Edit 2:
Ich habe mal zurück verfolgt, welche Events neben #PB_Event_Gadget noch sehr häufig vorkommen. Nach Start des Programms, dem kurzen Verschieben eines Termins und der Änderung der Länge eines anderen, kommt dieses hier raus (Event: Häufigkeit). Ich habe nur keine Ahnung zu welchen Konstanten die Werte gehören könnten.
4: 1
5: 2
7: 2
8: 1
24: 666
-1: 11

Re: Kalender

Verfasst: 20.09.2011 20:06
von marco2007
@Stargate: WOW!!! :allright:

Da ist man mal eine Zeitlang weg und dann sieht man diesen geilen Code...gibt`s da noch mehr? :o