Yesterday, 10:36 PM
Well here's a little Screen Zero Hero Productions goody from 25 years a ago.
I did a rewrite because my coding style back then was to use all caps, no remarks, non-descriptive variable names, and no indentation.
I uses the mapping technique, I described in the other thread, for mouse recognition.
Anyway, I have some bells and whistles I'd like to add going forward, but here is a working demo that shows how it can be applied in what I term as a flow-through routine. That means the calendar routine will keep flowing through the main routine, so what's going on there won't be disturbed.
I'll post back with some more info on keys and Mouse use. For now, just use arrow keys, page keys, Enter, Esc, F1, F12, or click / double click a day, x symbol, "<" or ">" symbols enclosing the month and year, or use the mouse wheel.
The goal here again is to turn the calendar popup into a library.
Pete
I did a rewrite because my coding style back then was to use all caps, no remarks, non-descriptive variable names, and no indentation.
I uses the mapping technique, I described in the other thread, for mouse recognition.
Anyway, I have some bells and whistles I'd like to add going forward, but here is a working demo that shows how it can be applied in what I term as a flow-through routine. That means the calendar routine will keep flowing through the main routine, so what's going on there won't be disturbed.
I'll post back with some more info on keys and Mouse use. For now, just use arrow keys, page keys, Enter, Esc, F1, F12, or click / double click a day, x symbol, "<" or ">" symbols enclosing the month and year, or use the mouse wheel.
Code: (Select All)
ReDim Shared mRow$(0)
Palette 1, 8
Width 80, 28
_Font 16
Palette 7, 63
Color 0, 1
Cls
View Print 3 To _Height - 2
Color 0, 7: Cls 2
View Print
Color 14, 1
Locate 1, 1: Print String$(80, 196);
Locate _Height - 1, 1: Print String$(80, 196);
msg$ = "Chritmas Card and Calendar Demo"
Locate 2, _Width \ 2 + 1 - Len(msg$) \ 2: Print msg$;
Locate 3, 1: Print String$(80, 196);
msg$ = "Press [F12] for Calendar or [F1] for Help."
Locate _Height, _Width \ 2 + 1 - Len(msg$) \ 2: Print msg$;
train$ = Space$(_Width) + "[oo]-[oo]-[Oo>"
Color 2, 7
msg$ = " Merry Christmas "
Locate 8, _Width \ 2 - Len(msg$) \ 2 + 1
Color 4, 7: Print msg$: Color 2
Locate 14
a$ = "*"
For i = 1 To 13
If i > 10 Then a$ = "*": Color 0
Locate , _Width \ 2 - Len(a$) \ 2 + 1
Print a$
a$ = a$ + "**"
Next
y = CsrLin - 1
_Delay 2: x = 5: z = Timer
Do
If gocal = 0 Then
Locate 14: a$ = "*"
For i = 1 To 10
Locate , _Width \ 2 - Len(a$) \ 2 + 1
Color 2, 7: Print a$;
For j = 1 To Len(a$)
If Rnd * 20 > 17 Then
Locate , _Width \ 2 - Len(a$) \ 2 + j
Color 12 + 16: Print "*";
End If
Next
Print
a$ = a$ + "**"
Next
End If
If Abs(z - Timer) > x Then
z = Timer
If t = Len(train$) + 1 Then
t = 1: x = 3
Else
Sound 300, .05
t = t + 1: x = .05
Locate y, 1: Color 0, 7: Print Mid$(train$, Len(train$) - t, _Width);
If t >= _Width / 2 + Len(_Trim$(train$)) Then Color 0: Locate , _Width \ 2 + 1: Print "*";
End If
End If
b$ = InKey$
If b$ = Chr$(0) + Chr$(134) Then
_KeyClear
gocal = 1: Color 0, 7: Locate y, 1: Print Space$(_Width);
Color 0, 7: Locate , _Width \ 2 + 1: Print "*";
End If
If b$ = Chr$(0) + Chr$(59) Then
_MessageBox
End If
If gocal Then
cal ds$
If Len(ds$) Then
If ds$ <> "esc" Then _Title ds$
ds$ = "": gocal = 0: _KeyClear
End If
End If
Loop
Sub cal (Cal_DateSelected$)
Static initiate ' Needed for this sub. Other static variables below are only required for flo-through.
Static DaysInMonth$, EndDate, yr, mo, dy, month$, fullmonth$, oldmapy, oldday$, datex$, yy, xx
Static BorderColorFg, BorderColorBg, ShadowFg, ShadowBg, DOWColor, DOWColorSunday, DOWHighlightBg
Static w1, w2, w3, w4, xover, caly, calx, calfg, calbg, a1$, a2$, a3$, b1$, b2$, b3$
Static mx, my, lb, mb, mw, clkcnt, hlclose
Locate , , 0 ' Hide cursor.
If initiate = 0 Then
initiate = 1
PCopy 0, 3
Palette 5, 63
BorderColorFg = 15
BorderColorBg = 1
ShadowFg = 8
ShadowBg = 0
DOWColor = 15
DOWColorSunday = 3
DOWHighlightBg = 4
j = 4
a1$ = Chr$(218) + String$(j, Chr$(196)) + Chr$(191)
a2$ = Chr$(179) + String$(j, Chr$(32)) + Chr$(179)
a3$ = Chr$(192) + String$(j, Chr$(196)) + Chr$(217)
b1$ = a1$: b2$ = a2$: b3$ = a3$
For i = 1 To 7 - 1
a1$ = a1$ + " " + b1$
a2$ = a2$ + " " + b2$
a3$ = a3$ + " " + b3$
Next i
w1 = 7 ' Top
w2 = Int(_Width \ 2 - Len(a1$) \ 2) - 2 ' Left margin
w3 = 18 ' Height
w4 = Len(a1$) + 4 ' Width
yy = w1: xx = Int(_Width \ 2 - Len(a1$) \ 2) ' Left top corner.
Color BorderColorFg, BorderColorBg: Locate w1 - 1, w2: Print Chr$(218) + String$(w4 - 2, 196) + Chr$(191);
' Create box-----------------------------------------------------------------------
Locate w1, w2
For i = 1 To w3 - 1
Color BorderColorFg, BorderColorBg: Locate , w2: Print Chr$(179);: Color 7, 1: Print Space$(w4 - 2);: Color BorderColorFg, 1: Print Chr$(179);
Color 8, 0: Print Chr$(Screen(CsrLin, Pos(0)));: Print Chr$(Screen(CsrLin, Pos(0)))
Next i
Color BorderColorFg, BorderColorBg: Locate , w2: Print Chr$(192) + String$(w4 - 2, 196) + Chr$(217);
Color ShadowFg, ShadowBg: Print Chr$(Screen(CsrLin, Pos(0)));: Print Chr$(Screen(CsrLin, Pos(0)))
' ---------------------------------------------------------------------------------
Color ShadowFg, ShadowBg: Locate , w2 + 1
For i = 1 To w4 + 1
Print Chr$(Screen(CsrLin, Pos(0)));
Next
Locate yy + 1, xx
Color 11, 1
Print " Sun. Mon. Tue. Wed. Thu. Fri. Sat. "
DaysInMonth$ = "312831303130313130313031"
GoSub update_calendar
Else
Locate caly, calx
Color calfg, calbg
End If
Do
_Limit 30
MyMouse_and_Keyboard lb, mb, rb, my, mx, mw, shift%, alt%, clkcnt, drag, b$, autokey$
If hlclose Then
If Mid$(mRow$(my), mx, 1) <> "x" Then
s1 = CsrLin: s2 = Pos(0)
c1 = _DefaultColor: c2 = _BackgroundColor
Color BorderColorBg, BorderColorFg
Locate hlclose, InStr(mRow$(hlclose), "x") - 1
Color BorderColorBg, BorderColorBg: Print Chr$(221);
Color BorderColorFg, BorderColorBg: Print "x";
Color BorderColorBg, BorderColorBg: Print Chr$(222);
Color c1, c2
Locate s1, s2
hlclose = 0
End If
Else
If Mid$(mRow$(my), mx, 1) = "x" Then ' Highlight "x" close popup symbol.
hlclose = my
s1 = CsrLin: s2 = Pos(0)
c1 = _DefaultColor: c2 = _BackgroundColor
Color BorderColorFg, DOWHighlightBg
Locate my, mx - 1
Color BorderColorBg, DOWHighlightBg: Print Chr$(221);
Color BorderColorFg, DOWHighlightBg: Print "x";
Color BorderColorBg, DOWHighlightBg: Print Chr$(222);
Color c1, c2
Locate s1, s2
End If
End If
If lb = 2 Then
If hlclose Then
b$ = Chr$(27)
Else
x$ = Mid$(mRow$(my), mx, 1)
If x$ = "<" Or x$ = ">" Then
If InStr(mx, mRow$(my), "ù") Then
If x$ = "<" Then i = -1 Else i = 1 ' Change month.
j = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
b$ = "lb"
Else
If x$ = "<" Then j = -1 Else j = 1 ' Change year.
i = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
If dy > Val(Mid$(DaysInMonth$, mo * 2 - 1, 2)) Then dy = 0 ' Note: Automatically adjusts for a leap year when dy=0 is evaluated in next cycle.
b$ = "lb"
End If
End If
If InStr(mRow$(my), Chr$(179)) Then
j = InStr(mx, mRow$(my), Chr$(179)) - 1
x$ = Mid$(mRow$(my), 1, j)
x$ = Mid$(x$, _InStrRev(x$, Chr$(179)) + 1)
If Val(x$) Then ' Click was on a calendar date.
Select Case x$ ' Block is [3210] for j - mx.
Case "2330": If j - mx > 1 Then x$ = "23" Else x$ = "30"
Case "2431": If j - mx > 1 Then x$ = "24" Else x$ = "31"
End Select
dy = Val(x$)
If clkcnt = 1 Then
b$ = Chr$(13) ' A double click on a calendar date triggers selection.
Else
b$ = "lb" ' Highlights date clicked.
End If
End If
End If
End If
Else
If mw > 0 Then b$ = Chr$(0) + "P" ' Page up.
If mw < 0 Then b$ = Chr$(0) + "H" ' Page dn.
End If
If Len(b$) Then
h = 0: v = 0
Select Case b$
Case "lb" ' Mouse event.
Case Chr$(9), Chr$(8) ' Tab or Backspace.
datex$ = "" ' Triggers today's date.
GoSub update_calendar
Case Chr$(0) + "H", Chr$(0) + "M", Chr$(0) + "P", Chr$(0) + "K" ' Arrow keys.
Select Case b$
Case Chr$(0) + "H": v = -1
Case Chr$(0) + "M": h = 1
Case Chr$(0) + "P": v = 1
Case Chr$(0) + "K": h = -1
End Select
If h Then
If dy + h > 0 And dy + h <= EndDate Then
dy = dy + h
day$ = LTrim$(Str$(dy))
If Len(day$) = 1 Then day$ = "0" + day$
Else
If h > 0 Then
i = 1: j = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
dy = 1
ElseIf h < 0 Then
i = -1: j = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
dy = 0
End If
End If
ElseIf v Then
If dy + v * 7 > 0 And dy + v * 7 <= EndDate Then
dy = dy + v * 7
day$ = LTrim$(Str$(dy))
If Len(day$) = 1 Then day$ = "0" + day$
Else ' Change month/year.
If v > 0 Then
i = 1: j = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
dy = dy + 7 - EndDate
ElseIf v < 0 Then
i = -1: j = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
j = Val(Mid$(DaysInMonth$, mo * 2 - 1, 2))
If mo = 2 Then ' Leap Year adjustment.
If yr Mod 4 = 0 And yr Mod 100 Or yr Mod 4 = 0 And yr Mod 100 = 0 And yr Mod 400 = 0 Then j = j + 1
End If
dy = (dy - 7) + j
End If
End If
End If
Case Chr$(0) + "I", Chr$(0) + "Q" ' Page keys.
If b$ = Chr$(0) + "I" Then i = -1 Else i = 1
j = 0: GoSub change_mo_yr: If i = -999 Then Exit Do
j = (xover + dy - 1) \ 7 + 1 ' Calendar row.
k = (xover + ((dy - 1) Mod 7)) Mod 7 + 1 ' Calendar column.
cal_calc nul$, nul$, mo, yr, i, nul
l = Val(Mid$(DaysInMonth$, mo * 2 - 1, 2))
dy = (j - 1) * 7 + k - i
If dy > l Then dy = dy - 7
If dy < 1 Then dy = dy + 7
Case Chr$(0) + "G" ' Home key
dy = 1
Case Chr$(0) + "O" ' End key.
dy = EndDate
Case Chr$(13) ' Enter key.
temp$ = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
temp$ = Mid$(temp$, ((xover - 1 + dy) Mod 7) * 10 + 1, 10)
Cal_DateSelected$ = _Trim$(temp$) + " " + fullmonth$ + " " + LTrim$(Str$(dy)) + ", " + LTrim$(Str$(yr))
PCopy 3, 0
initiate = 0
Exit Do
Case Chr$(27), Chr$(0) + Chr$(134) ' Esc key or F12 toggle.
PCopy 3, 0
Cal_DateSelected$ = "esc"
initiate = 0
Exit Do
Case Else
Exit Do ' Bypass update_calendar routine, below.
End Select
If Len(b$) Then
GoSub update_calendar
End If
End If
Exit Do
Loop
caly = CsrLin: calx = Pos(0)
calfg = _DefaultColor: calbg = _BackgroundColor
Exit Sub
change_mo_yr:
k = mo + i ' Where k substitutes for month and l substitutes for year.
l = yr + j
If k = 0 Then l = l - 1: k = 12
If k = 13 Then i = i + 1: k = 1
If l <= 1582 Then Beep: dy = 1: i = -999 ' This value tell calling routine to exit the loop without changes.
If l > 9999 Then Beep: dy = EndDate: i = -999
If i <> -999 Then
mo = k: yr = l
End If
Return
update_calendar:
oldmapy = 0: oldmapx = 0: oldday$ = ""
If datex$ = "" Then
datex$ = Date$
mo = Val(Mid$(datex$, 1, 2))
yr = Val(Mid$(datex$, 7, 4))
dy = Val(Mid$(datex$, 4, 2))
End If
cal_calc month$, fullmonth$, mo, yr, xover, leapyear
Color BorderColorFg, 1 ' Make the squares to display the days.
Locate yy + 2, xx
For i = 1 To 5
a$ = a1$: cal_mapit a$
Locate CsrLin + 1, xx
a$ = a2$: cal_mapit a$
Locate CsrLin + 1, xx
a$ = a3$: cal_mapit a$
Locate CsrLin + 1, xx
Next i
Locate yy - 1, w2 + w4 - 4 ' Display date at top of the calendar.
y_close = CsrLin: x_close = Pos(0) + 1
Color BorderColorBg, BorderColorBg: a$ = "Ý": cal_mapit a$
Color BorderColorFg, BorderColorBg: a$ = "x": cal_mapit a$
Color BorderColorBg, BorderColorBg: a$ = "Þ": cal_mapit a$
Color BorderColorFg, BorderColorBg
Locate yy - 1, _Width / 2 - (Len(month$) + Len(LTrim$(Str$(yr)))) \ 2 - 3
a$ = "<": cal_mapit a$
a$ = month$: cal_mapit a$
a$ = ">": cal_mapit a$
a$ = "ù": cal_mapit a$
a$ = "<": cal_mapit a$
a$ = LTrim$(Str$(yr)): cal_mapit a$
a$ = ">": cal_mapit a$
EndDate = Val(Mid$(DaysInMonth$, mo * 2 - 1, 2))
k = EndDate
If k = 28 And leapyear Then k = 29: EndDate = 29
If k = 30 And xover = 6 Then k = k - 1 ' Overlap 1 date.
If k = 31 And xover > 4 Then k = k - (xover - 4) ' Overlap 2 dates.
If dy = 0 Then dy = EndDate ' Zero signals backtracking in months or years. Places highlighted date as the last day of the month.
j = yy + 3
Locate j, w2 - 1 + 7 * xover
For i = 1 To k ' Display the days in the squares.
Locate j, Pos(0) + 5
If (i + xover - 1) Mod 7 = 0 Then
Color DOWColorSunday, BorderColorBg ' Sunday.
If i > 1 Then j = j + 3: Locate j, xx + 2 ' Start next column.
Else
Color DOWColor, BorderColorBg ' Weekday/Saturday.
End If
If i < 10 Then a$ = "0" + LTrim$(Str$(i)) Else a$ = LTrim$(Str$(i))
If i = 23 Or i = 24 Then
If mo <> 2 Then
Select Case xover
Case 5
If EndDate = 31 And i = 24 Then a$ = "2431"
Case 6
Select Case EndDate
Case 30
If i = 23 Then a$ = "2330"
Case 31
If i = 23 Then a$ = "2330"
If i = 24 Then a$ = "2431"
End Select
End Select
End If
End If
If Len(a$) > 2 Then Locate , Pos(0) - 1
cal_mapit a$
If Len(a$) > 2 Then Locate , Pos(0) - 1
Next i
day$ = LTrim$(Str$(dy)): If Len(day$) = 1 Then day$ = "0" + day$
GoSub highlight_date
Return
highlight_date:
For i = 8 To _Height
j = InStr(mRow$(i), day$)
If j Then
Color BorderColorFg, BorderColorBg
If oldmapy Then Locate oldmapy, oldmapx: Print oldday$;
k = 0
p = Val(day$)
If p <> dy Then Beep
If mo <> 2 And xover > 4 Then
If dy = 23 Or dy = 24 Or dy = 30 Or dy = 31 Then
Select Case xover
Case 5
If EndDate = 31 Then If dy = 24 Or dy = 31 Then k = 1
Case 6
Select Case EndDate
Case 30
If dy = 23 Or dy = 30 Then k = 1
Case 31
If dy = 23 Or dy = 24 Or dy = 30 Or dy = 31 Then k = 1
End Select
End Select
End If
End If
Color BorderColorBg, DOWHighlightBg
If k Then
Locate i, j: Print " ";
Else
Locate i, j - 1: Print Chr$(221) + " " + Chr$(222);
End If
If (Val(day$) + xover - 1) Mod 7 = 0 Then
Color DOWColorSunday, DOWHighlightBg
Else
Color DOWColor, DOWHighlightBg
End If
Locate i, j: Print day$;
mapy = i: mapx = j
oldday$ = day$: oldmapy = mapy: oldmapx = mapx
Exit For
End If
Next
Return
End Sub
Sub cal_mapit (a$)
Static initiate As Integer
If initiate = 0 Then
initiate = 1
ReDim mRow$(_Height)
End If
If mRow$(CsrLin) = "" Then mRow$(CsrLin) = Space$(_Width)
Mid$(mRow$(CsrLin), Pos(0)) = a$
Print a$;
End Sub
Sub cal_calc (month$, fullmonth$, mo, yr, xover, leapyear)
Select Case mo
Case 1: month$ = "Jan": fullmonth$ = "January": ordinal = 0
Case 2: month$ = "Feb": fullmonth$ = "February": ordinal = 31
Case 3: month$ = "Mar": fullmonth$ = "March": ordinal = 59
Case 4: month$ = "Apr": fullmonth$ = "April": ordinal = 90
Case 5: month$ = "May": fullmonth$ = "May": ordinal = 120
Case 6: month$ = "Jun": fullmonth$ = "June": ordinal = 151
Case 7: month$ = "Jul": fullmonth$ = "July": ordinal = 181
Case 8: month$ = "Aug": fullmonth$ = "August": ordinal = 212
Case 9: month$ = "Sep": fullmonth$ = "September": ordinal = 243
Case 10: month$ = "Oct": fullmonth$ = "October": ordinal = 273
Case 11: month$ = "Nov": fullmonth$ = "November": ordinal = 304
Case 12: month$ = "Dec": fullmonth$ = "December": ordinal = 334
End Select
leapyear = 0
xdays = (365 * yr) + yr \ 4 - yr \ 100 + yr \ 400 - 365
If yr Mod 4 = 0 And yr Mod 100 Or yr Mod 4 = 0 And yr Mod 100 = 0 And yr Mod 400 = 0 Then leapyear = 1
xdays = xdays + ordinal + 1
If leapyear And mo < 3 Then xdays = xdays - 1
xover = xdays Mod 7 ' First day of month and year.
End Sub
Sub MyMouse_and_Keyboard (lb, mb, rb, my, mx, mw, shift%, alt%, clkcnt, drag, b$, autokey$)
Static oldmy, oldmx, z1, hover, mwy, oldmwy
If Len(autokey$) Then
b$ = Mid$(autokey$, 1, InStr(autokey$ + ",", ",") - 1)
autokey$ = Mid$(autokey$, InStr(autokey$ + ",", ",") + 1)
Exit Sub
Else
k& = _KeyHit
If k& = 100307 Or k& = 100308 Then alt% = -1: Exit Sub Else If alt% Then alt% = 0
If k& > 0 Then
b$ = MKI$(k&)
If Right$(b$, 1) = Chr$(0) Then b$ = Left$(b$, 1)
Else
b$ = ""
End If
End If
If z1 Then If Abs(Timer - z1) > .3 Then z1 = 0: clkcnt = 0
If lb > 0 Then
If lb = 1 Then
lb = -1
Else
lb = 0
End If
End If
If rb > 0 Then If rb = 1 Then rb = -1 Else rb = 0
If mb > 0 Then If mb = 1 Then mb = -1 Else mb = 0
While _MouseInput
mwy = mwy + _MouseWheel
Wend
my = _MouseY
mx = _MouseX
b_hover = 0
For i = 1 To nob ' number of buttons.
If my >= y_btl(i) And my <= y_bbr(i) And mx >= x_btl(i) And mx <= x_bbr(i) Then
b_hover = i
Exit For
End If
Next
If lb = -1 Then
If oldmy And oldmx <> mx Or oldmy And oldmy <> my Then
If mx <> oldmx Then drag = Sgn(mx - oldmx) ' Prevent zero which can occur if mouse moves off row when being dragged horizontally.
End If
End If
If drag = 0 Then
If mwy <> oldmw Then
mw = Sgn(mwy - oldmwy): mwy = 0
Else
mw = 0
End If
oldmwy = mwy
If _KeyDown(100303) Or _KeyDown(100304) Then shift% = -1 Else If shift% Then shift% = 0
End If
If lb = -1 And _MouseButton(1) = 0 Then
lb = 2: drag = 0: hover = 0
ElseIf rb = -1 And _MouseButton(2) = 0 Then
rb = 2
ElseIf mb = -1 And _MouseButton(3) = 0 Then
mb = 2
End If
If _MouseButton(1) Then
If lb = 0 Then
lb = 1
If z1 = 0 Then
z1 = Timer ' Let first click go through.
Else
clkcnt = clkcnt + 1
End If
End If
ElseIf _MouseButton(2) And rb = 0 Then
rb = 1
ElseIf _MouseButton(3) And mb = 0 Then
mb = 1
End If
oldmy = my: oldmx = mx
End Sub
The goal here again is to turn the calendar popup into a library.
Pete