Its not really finished, but its a good start.
Calendargadget is already taken as a name, dategadget is also taken.. Calendar Canvas Gadget is also taken http://www.purebasic.fr/english/viewtopic.php?t=46349 and so is datepicker http://www.purebasic.fr/english/viewtopic.php?t=46300
I did a full week calendar before, but working with canvasgadget is so much nicer than sprites http://www.purebasic.fr/english/viewtopic.php?t=46369
So here it is - ScheduleGadget. A very early attempt on competing with Apple and their iCal
Code: Select all
; ScheduleGadget.pb by Jesper B.
; Creates a dayview calendar.
;
; Usage:
; *Doubleclick To add a meeting at current hour from computer time.
; *Leftclick to select a meeting -> drag/drop and write to change meeting name (+esc, enter, backspace can be used).
; *Rightclick to remove a meeting.
; Unitsperhour (2 = one tick every 30 minutes, 4 = one tick every 15 minutes, 6=one tick every 10 minutes etc)
;
;
; Still to do:
; *Most functions only work with full hours, not minutes at the moment.
; *End time is not taken in count yet.
; *Expand the ScheduleGadget_Add() to handle text, time etc.
; *Expand the ScheduleGadget_Remove() to be able to specify what event to remove.
; *Several day (3 day, weekview, monthview etc) and several calendars (multiple staff ie) view.
; *Collision check (right now two meetings will just show up on top of each other).
; *Zoom function
;
; Version: 0.1
;
; License: May not be ported to other languages, any contributions/changes/alterations
; to code would probably be appreciated in the Purebasic community. Use as you like with that in mind.
;
Enumeration
#Schedule_NewEvent
#Schedule_LeftClick
#Schedule_LeftDoubleClick
#Schedule_RightClick
EndEnumeration
Enumeration
#calendar_normaltext
#calendar_smalltext
EndEnumeration
LoadFont(#calendar_normaltext,"Arial",12)
LoadFont(#calendar_smalltext,"Arial",10)
Structure SCHEDULE_ITEM_INFO
text.s
time_start.i
time_end.i
colour.l
x.i
y.i
w.i
h.i
EndStructure
Structure SCHEDULE_INFO
*topgadget
*scrollareagadget
*canvasgadget
flags.l
UnitsPerHour.b
DateShown.i
SelectedItem.i
List item.SCHEDULE_ITEM_INFO()
EndStructure
Global NewList SGs.SCHEDULE_INFO()
Procedure ScheduleGadget_Repaint(*sg)
PushListPosition(SGs())
ChangeCurrentElement(SGs(),*sg)
If StartDrawing(CanvasOutput(SGs()\topgadget))
;//PAINT TOP
Box(0,0,GadgetWidth(SGs()\topgadget),50,RGB(255,255,255))
Box(0,0,GadgetWidth(SGs()\topgadget),80,RGB($BB,$CC,$FF))
Box(50,5,GadgetWidth(SGs()\topgadget)-80,25,RGB($FA,$D1,$63))
DrawingMode(#PB_2DDrawing_Transparent)
t.s=FormatDate("%yyyy-%mm-%dd",SGs()\DateShown)
DrawText((GadgetWidth(SGs()\topgadget)/2)-(TextWidth(t.s)/2),5,t.s,RGB($66,$66,$66))
DrawingMode(#PB_2DDrawing_Default)
StopDrawing()
;//PAINT BACKGROUND
StartDrawing(CanvasOutput(SGs()\canvasgadget))
Box(5,0,45,GadgetHeight(SGs()\canvasgadget)-65,RGB($F6,$F9,$FC))
Box(50,0,(GadgetWidth(SGs()\canvasgadget)-60),GadgetHeight(SGs()\canvasgadget)-100,RGB(210,210,215))
DrawingMode(#PB_2DDrawing_Transparent)
For a=1 To 24
Line(50,0+(GadgetHeight(SGs()\canvasgadget)-95)/(24*a),GadgetWidth(SGs()\canvasgadget),1,RGB(244, 244, 244))
Line(5,0+(GadgetHeight(SGs()\canvasgadget)-95)/(24*a),40,1,RGB($BB,$CC,$FF))
DrawingFont(FontID(#calendar_normaltext))
DrawText(31,10+(GadgetHeight(SGs()\canvasgadget)-95)/(24)*a,RSet(Str(a),2,"0"),RGB($66,$66,$66))
DrawingFont(FontID(#calendar_smalltext))
For j=0 To SGs()\UnitsPerHour-1
DrawingMode(#PB_2DDrawing_Default)
y.f=(GadgetHeight(SGs()\canvasgadget)-95)/(24)*(a+(j/SGs()\UnitsPerHour))
Line(50,y.f,GadgetWidth(SGs()\canvasgadget),1,RGB(244, 244, 244))
DrawingMode(#PB_2DDrawing_Transparent)
If j
DrawText(41-TextWidth(RSet(Str(((60/SGs()\UnitsPerHour)*j)),2,"0")),-5+y.f,RSet(Str(((60/SGs()\UnitsPerHour)*j)),2,"0"),RGB($aa,$aa,$aa))
EndIf
Next
Next
DrawingMode(#PB_2DDrawing_Default)
;//PAINT MEETINGS
ForEach SGs()\item()
start.s=FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",SGs()\item()\time_start)
stop.s=FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",SGs()\item()\time_end)
SGs()\item()\x=60
SGs()\item()\y=((GadgetHeight(SGs()\canvasgadget)-95)/24)*(Val(Mid(start,12,2))+(Val(Mid(start,15,2))/60))
SGs()\item()\w=GadgetWidth(SGs()\CanvasGadget)-80
SGs()\item()\h=100
DrawingMode(#PB_2DDrawing_AlphaBlend)
If SGs()\SelectedItem=ListIndex(SGs()\item())
If GetGadgetAttribute(SGs()\canvasgadget,#PB_Canvas_Buttons) & #PB_Canvas_LeftButton
y2=(GetGadgetAttribute(SGs()\canvasgadget,#PB_Canvas_MouseY))
For a=1 To 24
For j=1 To SGs()\UnitsPerHour-1
y.f=(GadgetHeight(SGs()\canvasgadget)-95)/(24)*(a+(j/SGs()\UnitsPerHour))
If y.f>y2
start.s=FormatDate("%yyyy-%mm-%dd",SGs()\item()\time_start)+" "+RSet(Str(a),2,"0")+":00:00"
Break 2
EndIf
Next
Next
SGs()\item()\time_start=ParseDate("%yyyy-%mm-%dd %hh:%ii:%ss",start)
SGs()\item()\y=((GadgetHeight(SGs()\canvasgadget)-95)/24)*(Val(Mid(start,12,2))+(Val(Mid(start,15,2))/60))
EndIf
Box(SGs()\item()\x,SGs()\item()\y,SGs()\item()\w,SGs()\item()\h,RGBA($144,$144,$44,240))
EndIf
RoundBox(SGs()\item()\x,SGs()\item()\y,SGs()\item()\w,SGs()\item()\h,5,5,RGBA($44,$44,$44,120))
RoundBox(SGs()\item()\x+1,SGs()\item()\y+1,SGs()\item()\w-2,SGs()\item()\h-2,5,5,SGs()\item()\colour)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#calendar_normaltext))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(5+SGs()\item()\x,5+SGs()\item()\y,start,RGBA(0,0,0,12))
DrawingFont(FontID(#calendar_smalltext))
DrawText(5+SGs()\item()\x,15+SGs()\item()\y,SGs()\item()\text,RGBA(0,0,0,12))
DrawingMode(#PB_2DDrawing_Default)
Next
StopDrawing()
EndIf
PopListPosition(SGs())
EndProcedure
Procedure ScheduleGadget_HandleEvent(*sg)
PushListPosition(SGs())
ChangeCurrentElement(SGs(),*sg)
mx = GetGadgetAttribute(SGs()\canvasgadget, #PB_Canvas_MouseX)
my = GetGadgetAttribute(SGs()\canvasgadget, #PB_Canvas_MouseY)
Select EventType()
Case #PB_EventType_MouseEnter ; The mouse cursor entered the gadget
If SGs()\SelectedItem<>-1
repaint=#True
EndIf
SGs()\SelectedItem=-1
Case #PB_EventType_MouseLeave ; The mouse cursor left the gadget
If SGs()\SelectedItem<>-1
repaint=#True
EndIf
SGs()\SelectedItem=-1
Case #PB_EventType_MouseMove ; The mouse cursor moved
If SGs()\SelectedItem<>-1
repaint=#True
EndIf
Case #PB_EventType_MouseWheel ; The mouse wheel was moved
SetGadgetAttribute(SGs()\scrollareagadget,#PB_ScrollArea_Y,GetGadgetAttribute(SGs()\scrollareagadget,#PB_ScrollArea_Y)-(GetGadgetAttribute(SGs()\canvasgadget,#PB_Canvas_WheelDelta)*10))
If SGs()\SelectedItem<>-1
repaint=#True
EndIf
Case #PB_EventType_LeftButtonDown ; The left mouse button was pressed
SGs()\SelectedItem=-1
ForEach SGs()\item()
If mx>SGs()\item()\x And mx<SGs()\item()\x+SGs()\item()\w
If my>SGs()\item()\y And my<SGs()\item()\y+SGs()\item()\h
SGs()\SelectedItem=ListIndex(SGs()\item())
Break
EndIf
EndIf
Next
repaint=#True
Case #PB_EventType_LeftButtonUp ; The left mouse button was released
Case #PB_EventType_LeftClick ; A click With the left mouse button
retval=#Schedule_LeftClick
Case #PB_EventType_LeftDoubleClick ; A double-click With the left mouse button
retval=#Schedule_LeftDoubleClick
Case #PB_EventType_RightButtonDown ; The right mouse button was pressed
Case #PB_EventType_RightButtonUp ; The right mouse button was released
Case #PB_EventType_RightClick ; A click With the right mouse button
retval=#Schedule_RightClick
SGs()\SelectedItem=-1
ForEach SGs()\item()
If mx>SGs()\item()\x And mx<SGs()\item()\x+SGs()\item()\w
If my>SGs()\item()\y And my<SGs()\item()\y+SGs()\item()\h
SGs()\SelectedItem=ListIndex(SGs()\item())
Break
EndIf
EndIf
Next
repaint=#True
Case #PB_EventType_RightDoubleClick; A double-click With the right mouse button
Case #PB_EventType_MiddleButtonDown; The middle mouse button was pressed
Case #PB_EventType_MiddleButtonUp ; The middle mouse button was released
Case #PB_EventType_Focus ; The gadget gained keyboard focus
Case #PB_EventType_LostFocus ; The gadget lost keyboard focus
Case #PB_EventType_KeyDown ; A key was pressed
Case #PB_EventType_KeyUp ; A key was released
key.l=GetGadgetAttribute(SGs()\canvasgadget,#PB_Canvas_Key)
SelectElement(SGs()\item(),SGs()\SelectedItem)
If key.l=#PB_Shortcut_Escape
SGs()\item()\text=""
ElseIf key.l=#PB_Shortcut_Return
SGs()\SelectedItem=-1
ElseIf key.l=#PB_Shortcut_Delete
If SGs()\item()\text
SGs()\item()\text=Left(SGs()\item()\text,Len(SGs()\item()\text)-1)
EndIf
EndIf
repaint=#True
Case #PB_EventType_Input ; Text input was generated
If SGs()\SelectedItem<>-1
char.s=Chr(GetGadgetAttribute(SGs()\canvasgadget,#PB_Canvas_Input))
SelectElement(SGs()\item(),SGs()\SelectedItem)
If Asc(char)=8
If SGs()\item()\text
SGs()\item()\text=Left(SGs()\item()\text,Len(SGs()\item()\text)-1)
EndIf
Else
SGs()\item()\text+char.s
EndIf
repaint=#True
EndIf
EndSelect
PopListPosition(SGs())
If repaint
ScheduleGadget_Repaint(*sg)
EndIf
ProcedureReturn retval
EndProcedure
Procedure ScheduleGadget(x.i, y.i, Width.i, Height.i, flags.l=#Null, DateShown.i=0, UnitsPerHour.i=4)
If DateShown=0
DateShown=Date()
EndIf
AddElement(SGs())
SGs()\topgadget= CanvasGadget(#PB_Any, x, y, Width, 25,#PB_Canvas_Keyboard)
SGs()\scrollareagadget=ScrollAreaGadget(#PB_Any, x, y+30, width, Height-30, width-50,3600)
SGs()\canvasgadget=CanvasGadget(#PB_Any, 0, 0, width-50,3600,#PB_Canvas_Keyboard)
SGs()\DateShown=DateShown
SGs()\SelectedItem=-1
SGs()\UnitsPerHour=UnitsPerHour
CloseGadgetList()
ScheduleGadget_Repaint(SGs())
ProcedureReturn SGs()
EndProcedure
Procedure ScheduleGadget_Resize(*sg,x,y,width,height)
PushListPosition(SGs())
ChangeCurrentElement(SGs(),*sg)
ResizeGadget(SGs()\topgadget, x, y, Width, 25)
ResizeGadget(SGs()\scrollareagadget, x, y+30, width, Height-30)
SetGadgetAttribute(SGs()\scrollareagadget, #PB_ScrollArea_InnerWidth,width-50)
ResizeGadget(SGs()\canvasgadget, 0, 0, width-50,3600)
PopListPosition(SGs())
ScheduleGadget_Repaint(*sg)
EndProcedure
Procedure ScheduleGadget_Add(*sg)
PushListPosition(SGs())
ChangeCurrentElement(SGs(),*sg)
AddElement(SGs()\item())
SGs()\item()\time_start=Date(Year(Date()),Month(Date()),Day(Date()),Hour(Date()),0,0)
SGs()\item()\colour=RGBA(170,170,230,200)
SGs()\item()\text="New Meeting"
PopListPosition(SGs())
ScheduleGadget_Repaint(*sg)
EndProcedure
Procedure ScheduleGadget_Remove(*sg)
PushListPosition(SGs())
ChangeCurrentElement(SGs(),*sg)
If SGs()\SelectedItem=-1
ProcedureReturn
EndIf
SelectElement(SGs()\item(),SGs()\SelectedItem)
DeleteElement(SGs()\item())
PopListPosition(SGs())
ScheduleGadget_Repaint(*sg)
EndProcedure
Procedure ScheduleGadget_SetTime(*sg,when.i)
PushListPosition(SGs())
ChangeCurrentElement(SGs(),*sg)
SetGadgetAttribute(SGs()\scrollareagadget,#PB_ScrollArea_Y,(GetGadgetAttribute(SGs()\scrollareagadget,#PB_ScrollArea_InnerHeight)/24)*(Hour(when)-1))
PopListPosition(SGs())
EndProcedure
;- Example
OpenWindow(0, 0, 0, 500, 700, "ScheduleGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
GadgetIndex=ScheduleGadget(0,0,500,700)
ScheduleGadget_Add(GadgetIndex)
ScheduleGadget_Repaint(GadgetIndex)
ScheduleGadget_SetTime(GadgetIndex,Date())
Repeat
EventID=WaitWindowEvent()
If EventID=#PB_Event_CloseWindow
End
ElseIf eventid=#PB_Event_SizeWindow Or eventid=#PB_Event_MaximizeWindow
ScheduleGadget_Resize(GadgetIndex,0,0,WindowWidth(0),WindowHeight(0))
ElseIf EventID=#PB_Event_Gadget
Select ScheduleGadget_HandleEvent(GadgetIndex)
Case #Schedule_NewEvent
Case #Schedule_LeftClick
Case #Schedule_LeftDoubleClick
ScheduleGadget_Add(GadgetIndex)
Case #Schedule_RightClick
ScheduleGadget_Remove(GadgetIndex)
EndSelect
EndIf
ForEver