Skip to content

Instantly share code, notes, and snippets.

@RonchettiAssociati
Created March 21, 2010 13:52
Show Gist options
  • Save RonchettiAssociati/339310 to your computer and use it in GitHub Desktop.
Save RonchettiAssociati/339310 to your computer and use it in GitHub Desktop.
/*
* AppController.j
* Created by Bruno Ronchetti on March 21, 2010
* Copyright 2010, Ronchetti & Associati.
* The MIT licence
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
@import <Foundation/CPObject.j>
@import "BRoCalendarView.j"
@implementation AppController : CPObject
{
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView];
var calendar = [[BRoCalendarView alloc] init];
[calendar displayAtPoint:CGPointMake(100,100)];
[calendar prepareData:"today"];
[calendar display];
[contentView addSubview:calendar];
[theWindow orderFront:self];
}
@end
/*
* BRoCalendarView.j
*
* Created by Bruno Ronchetti on March 21, 2010
* Copyright 2010, Ronchetti & Associati.
* The MIT licence
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
@import <Foundation/CPDate.j>
@import <AppKit/CPView.j>
@import <AppKit/CPColor.j>
// CONSTANTS
//
var weekDays = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var colorBRoLightGray = [CPColor colorWithCalibratedRed:243/255 green:245/255 blue:247/255 alpha:1];
var colorBRoMediumGray = [CPColor colorWithCalibratedRed:213/255 green:215/255 blue:217/255 alpha:1];
var colorBRoDarkGray = [CPColor colorWithCalibratedRed:155/255 green:151/255 blue:157/255 alpha:1];
var colorBRoDirtyWhite = [CPColor colorWithCalibratedRed:255/255 green:255/255 blue:255/255 alpha:1];
var colorBRoHighLightBlue = [CPColor colorWithCalibratedRed:170/255 green:211/255 blue:233/255 alpha:1];
// IMPLEMENTATION
//
@implementation BRoCalendarView: CPView
{
CPDate id today;
CPDate id pivotDate;
CPDate id firstOfPivotMonth;
CPDate id firstOfFollowingMonth;
CPDate id firstOfPrecedingMonth;
CPArray id savedViews;
CPObject sender;
CPTextField id targetField;
CPInt id tileWidth;
CPInt id borderWidth;
CPInt id tileHeight;
CGSize id tileElementSize;
CPInt id width;
CPInt id height;
CgRect id rect;
CPDictionary id appointments;
}
- (CPView) init
{
self = [super init];
if (self)
{
var appointments = [CPDictionary dictionaryWithObjectsAndKeys:
@"15:30 Barber", @"Sun Mar 21 2010", @"8:30 school", @"Mon Mar 22 2010"
];
return self;
}
}
// SET-UP DATA AND DISPLAY CALENDAR WIDGET
//
-(void)displayAtPoint:(CGPoint)aPoint
{
tileWidth = 90;
borderWidth = 1;
width = 7*tileWidth + 8*borderWidth;
tileHeight = 80;
tileElementSize=CGSizeMake(88,78);
height = 6*tileHeight+tileHeight+15;
var originX = aPoint.x;
var originY = aPoint.y;
rect = CGRectMake(originX, originY, width, height);
}
-(void)prepareData:(CPDate)aDate
{
// Determine Key Dates
//
if (aDate == "today") aDate = new Date();
today = new Date();
pivotDate = new Date(aDate);
pivotMonth = pivotDate.getMonth();
firstOfPivotMonth = new Date(pivotDate); firstOfPivotMonth.setDate(1);
weekdayOfFirstOfPivotMonth = firstOfPivotMonth.getDay();
firstOfFollowingMonth = new Date(firstOfPivotMonth); firstOfFollowingMonth.setMonth(pivotMonth+1);
firstOfPrecedingMonth = new Date(firstOfPivotMonth); firstOfPrecedingMonth.setMonth(pivotMonth-1);
// Prepare 5 weeks of dates around the pivot date, starting with the monday
// preceding the first day of the month
datesArray = [];
var anchorDate = new Date(firstOfPivotMonth.getTime());
var calendarItem = new Date();
var j= - weekdayOfFirstOfPivotMonth;
var i = 42;
while (i--)
{
calendarItem.setTime(firstOfPivotMonth.getTime() + j*24*3600*1000);
var calendarItemType = "normal";
if (calendarItem.toDateString() == today.toDateString()) calendarItemType = "today";
if (calendarItem.getMonth() != pivotMonth) calendarItemType = "other";
var calendarItemObject = { name: "CalendarItem",
calendarDate: calendarItem.toDateString(),
type: calendarItemType,
month: calendarItem.getMonth(),
date: calendarItem.getDate(),
day: calendarItem.getDay() };
datesArray[41-i] = calendarItemObject;
j++;
}
weeksArray = [];
for (var j=0; j<6; j++) {
weeksArray[j] = datesArray.splice(0*j,7);
}
}
-(void)display
{
widgetView = self;
[widgetView setBackgroundColor:colorBRoMediumGray];
[widgetView setAlphaValue:1];
// Display 2 Navigation Buttons
//
var backButton = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
[backButton setFrameSize:tileElementSize];
[backButton setFrameOrigin:CGPointMake(0,-30)];
[backButton setTitle:"<"];
[backButton setTag:"backButton"];
[backButton setTextColor:colorBRoDarkGray];
[backButton setFont:[CPFont boldSystemFontOfSize:20]];
[backButton setBordered:NO];
//[backButton setBackgroundColor:[CPColor whiteColor]];
[backButton setTarget:self];
[backButton setAction:@selector(newMonth:)];
[widgetView addSubview:backButton];
var forwardButton = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
[forwardButton setFrameSize:tileElementSize];
[forwardButton setFrameOrigin:CGPointMake(width-tileWidth,-30)];
[forwardButton setTitle:">"];
[forwardButton setTag:"forwardButton"];
[forwardButton setTextColor:colorBRoDarkGray];
[forwardButton setFont:[CPFont boldSystemFontOfSize:20]];
[forwardButton setBordered:NO];
//[forwardButton setBackgroundColor:[CPColor whiteColor]];
[forwardButton setTarget:self];
[forwardButton setAction:@selector(newMonth:)];
[widgetView addSubview:forwardButton];
// Display Widget Title, Days of the Week and Separator
//
var displayedMonth = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[displayedMonth setFrameSize:CGSizeMake(tileWidth*4, tileHeight+2)
];
[displayedMonth setCenter:CGPointMake(width/2,tileHeight/2)];
[displayedMonth setStringValue:months[pivotDate.getMonth()] + " " + pivotDate.getFullYear()];
[displayedMonth setTextColor:colorBRoDarkGray];
[displayedMonth setFont:[CPFont boldSystemFontOfSize:24]];
[displayedMonth setAlignment:CPCenterTextAlignment];
[widgetView addSubview:displayedMonth];
for (var i = 0; i < 7; i++) {
var dayOfWeek = [[CPTextField alloc] initWithFrame:CGRectMake(i*tileWidth+(i+1),45,tileWidth,13)];
[dayOfWeek setStringValue:[weekDays[i].substring(0,3)]];
[dayOfWeek setTextColor:colorBRoDarkGray];
[dayOfWeek setFont:[CPFont systemFontOfSize:10]];
[dayOfWeek setAlignment:CPCenterTextAlignment];
[widgetView addSubview:dayOfWeek];
}
// Display Calendar Grid
//
startTimeD = (new Date()).getTime();
[self setFrame:rect];
for (var i=0; i<6; i++)
{
for (var j=0; j<7; j++)
{
var tile = [[CPView alloc] initWithFrame:CGRectMake(j*tileWidth+(j+1),60+i*(tileHeight),tileWidth,tileHeight-1)];
[tile setBackgroundColor:colorBRoDirtyWhite];
var dayOfMonth = [[CPButton alloc] initWithFrame:CGRectMake(1,0,tileWidth-2, 12)];
[dayOfMonth setBordered:NO];
[dayOfMonth setTitle:weeksArray[i][j].date.toString()];
[dayOfMonth setFont:[CPFont boldSystemFontOfSize:12]];
[dayOfMonth setTag:weeksArray[i][j]];
[dayOfMonth setTextColor:colorBRoDarkGray];
[dayOfMonth setBackgroundColor:[CPColor whiteColor]];
[dayOfMonth setTarget:self];
[dayOfMonth setAction:@selector(daySelected:)];
// special cases:
// if the day is not in month - make transparent
// if the day is today - highlight
//
if (weeksArray[i][j].type == "other") [dayOfMonth setTextColor:colorBRoHighLightBlue];
if (weeksArray[i][j].type == "today") [dayOfMonth setBackgroundColor:colorBRoHighLightBlue];
// special case: if first day of 6th week is already in following month
// no need to display week; therefore reduce height of frame
//
if (i==5 && j==0 && (weeksArray[i][j].type == "other"))
{
[self setFrameSize:CGSizeMake(width,height-tileHeight)];
break;
}
else
{
[self setFrameSize:CGSizeMake(width,height)];
}
[dayOfMonth setFont:[CPFont systemFontOfSize:10]];
[dayOfMonth setAlignment:CPCenterTextAlignment];
[tile addSubview:dayOfMonth];
if ([appointments objectForKey:[dayOfMonth tag].calendarDate])
{
var appointment = [[CPButton alloc] initWithFrame:CGRectMake(1,14,tileWidth-2, 12)];
[appointment setBordered:NO];
[appointment setTitle:[appointments objectForKey:[dayOfMonth tag].calendarDate]];
[appointment setFont:[CPFont systemFontOfSize:11]];
[appointment setTag:[appointments objectForKey:[dayOfMonth tag].calendarDate]];
[appointment setTextColor:[CPColor whiteColor]];
[appointment setBackgroundColor:[CPColor redColor]];
[appointment setTarget:self];
[appointment setAction:@selector(appointmentSelected:)];
[tile addSubview:appointment];
}
[widgetView addSubview:tile];
}
}
}
// HANDLE WIDGET UI - HIGHLIGHT ELEMENTS, SCROLL THROUGH MONTHS
//
-(void)newMonth:(CPObject)clickedButton
{
var subviews = [self subviews];
var i = [subviews count];
while(i--) [subviews[i] removeFromSuperview];
switch([clickedButton tag]) {
case "backButton": [self prepareData:firstOfPrecedingMonth]; break;
case "forwardButton": [self prepareData:firstOfFollowingMonth]; break;
case "todayButton": [self prepareData:today]; break;
}
[self display];
}
-(void)daySelected:(CPEvent)aButton
{
alert([aButton tag].calendarDate);
var appNotificationCenter = [CPNotificationCenter defaultCenter];
var notificationInfo = [aButton tag].calendarDate;
[appNotificationCenter postNotificationName:@"calendarDidDaySelection" object:self userInfo:notificationInfo];
}
-(void)appointmentSelected:(CPEvent)aButton
{
alert([aButton tag]);
var appNotificationCenter = [CPNotificationCenter defaultCenter];
var notificationInfo = [aButton tag];
[appNotificationCenter postNotificationName:@"calendarDidAppointmentSelection" object:self userInfo:notificationInfo];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment