Implement current day selection for views, also various misc UI fixes

This commit is contained in:
vladimir%pobox.com 2005-06-16 06:52:11 +00:00
parent 7d2090d07a
commit 1e3a6865e6
6 changed files with 248 additions and 113 deletions

View File

@ -37,6 +37,10 @@ calendar-month-day-box {
background: #eeeeee;
}
calendar-month-day-box[selected="true"] {
background: #ffe79c !important;
}
.calendar-month-day-box-date-label {
color: #556;
font-weight: bold;

View File

@ -98,12 +98,40 @@
<field name="mDate">null</field>
<!-- mItemData will always be kept sorted in display order -->
<field name="mItemData">[]</field>
<field name="mMonthView">null</field>
<property name="date">
<getter>return this.mDate;</getter>
<setter>this.setDate(val); return val;</setter>
</property>
<property name="monthView">
<getter><![CDATA[
return this.mMonthView;
]]></getter>
<setter><![CDATA[
this.mMonthView = val;
return val;
]]></setter>
</property>
<property name="selected">
<getter><![CDATA[
var sel = this.getAttribute("selected");
if (sel && sel == "true") {
return true;
}
return false;
]]></getter>
<setter><![CDATA[
if (val)
this.setAttribute("selected", "true");
else
this.removeAttribute("selected");
]]></setter>
</property>
<property name="dayitems">
<getter>return document.getAnonymousElementByAttribute(this, "anonid", "day-items");</getter>
</property>
@ -245,6 +273,15 @@
]]></body>
</method>
</implementation>
<handlers>
<handler event="mousedown" button="0"><![CDATA[
event.preventBubble();
if (this.mDate)
this.monthView.selectedDay = this.mDate;
]]></handler>
</handlers>
</binding>
<binding id="calendar-month-view-column-header">
@ -339,6 +376,9 @@
<field name="mEndDate">null</field>
<field name="mDateBoxes">null</field>
<field name="mSelectedItem">null</field>
<field name="mSelectedDayBox">null</field>
<field name="mShowDaysOutsideMonth">true</field>
<!-- calICalendarView -->
@ -387,14 +427,36 @@
]]></setter>
</property>
<property name="selectedDay">
<getter><![CDATA[
if (this.mSelectedDayBox)
return this.mSelectedDayBox.date.clone();
]]></getter>
<setter><![CDATA[
if (this.mSelectedDayBox)
this.mSelectedDayBox.box.selected = false;
var realVal = val;
if (!realVal.isDate) {
realVal = val.clone();
realVal.isDate = true;
}
var box = this.findBoxForDate(realVal);
if (box) {
box.box.selected = true;
this.mSelectedDayBox = box;
}
return val;
]]></setter>
</property>
<method name="showDate">
<parameter name="aDate"/>
<body><![CDATA[
dump ("showDate: " + aDate + "\n");
var realEnd = aDate.endOfMonth;
realEnd.day += 1;
realEnd.normalize();
this.setDateRange(aDate.startOfMonth, realEnd);
this.setDateRange(aDate.startOfMonth, aDate.endOfMonth);
this.selectedDay = aDate;
]]></body>
</method>
@ -402,17 +464,8 @@
<parameter name="aStartDate"/>
<parameter name="aEndDate"/>
<body><![CDATA[
var realStart = aStartDate.startOfWeek;
var realEnd = aEndDate.endOfWeek;
dump ("setDateRange: " + aStartDate + " -> " + aEndDate + "\n");
realEnd.day += 1;
realEnd.normalize();
this.mStartDate = realStart;
this.mEndDate = realEnd;
dump ("setDateRange: " + realStart + " -> " + realEnd + "\n");
this.mStartDate = aStartDate.startOfWeek;
this.mEndDate = aEndDate.endOfWeek;
this.refresh();
]]></body>
@ -439,7 +492,7 @@
curDate.isDate = true;
curDate.normalize();
while (curDate.compare(this.mEndDate) < 0) {
while (curDate.compare(this.mEndDate) <= 0) {
results.push(curDate.clone());
curDate.day += 1;
curDate.normalize();
@ -475,17 +528,23 @@
<method name="refresh">
<body><![CDATA[
if (!this.startDate || !this.endDate)
return;
this.relayout();
if (!this.mCalendar)
return;
var queryEnd = this.endDate.clone();
queryEnd.day += 1;
queryEnd.normalize();
this.mCalendar.getItems(this.mCalendar.ITEM_FILTER_COMPLETED_ALL |
this.mCalendar.ITEM_FILTER_TYPE_ALL |
this.mCalendar.ITEM_FILTER_CLASS_OCCURRENCES,
0,
this.startDate,
this.endDate,
queryEnd,
this.mOperationListener);
]]></body>
</method>
@ -500,6 +559,12 @@
// XXX - reuse the grid boxes!
// clear out the grid
if (this.mSelectedItem)
this.mSelectedItem = null;
if (this.mSelectedDayBox)
this.mSelectedDayBox = null;
while (gridrows.lastChild)
gridrows.removeChild(gridrows.lastChild);
@ -550,6 +615,7 @@
curRow.appendChild(box);
box.setDate(date);
box.monthView = this;
var boxdata = {
date: date,
@ -566,6 +632,18 @@
]]></body>
</method>
<method name="findBoxForDate">
<parameter name="aDate"/>
<body><![CDATA[
for each (box in this.mDateBoxes) {
if (box.date.compare(aDate) == 0)
return box;
}
return null;
]]></body>
</method>
<method name="findBoxForItem">
<parameter name="aItem"/>
<body><![CDATA[
@ -579,12 +657,7 @@
if (!targetDate)
return null;
for each (box in this.mDateBoxes) {
if (box.date.compare(targetDate) == 0)
return box;
}
return null;
return this.findBoxForDate(targetDate);
]]></body>
</method>

View File

@ -12,6 +12,14 @@ calendar-event-column {
border-top: 1px solid #999999;
}
calendar-event-column[selected="true"] {
background: #ffe79c !important;
}
.calendar-event-column-header[selected="true"] {
background: #ffe79c !important;
}
.calendar-event-column-header {
border-left: 1px solid #999999;
border-top: 1px solid #999999;

View File

@ -225,7 +225,7 @@
// specifically, this should get us to a <calendar-event-box>
var evbox = this.parentNode.parentNode;
// still select it (since we'll preventBubble())
evbox.calendarView.selectedOccurrence = evbox.mOccurrence;
evbox.calendarView.selectedItem = evbox.mOccurrence;
// then start dragging it
evbox.parentColumn.startSweepingToModifyEvent(evbox, evbox.mOccurrence, whichside, event.screenX, event.screenY);
]]></handler>
@ -283,6 +283,21 @@
]]></setter>
</property>
<property name="selected">
<getter><![CDATA[
if (this.getAttribute("selected") == "true")
return true;
return false;
]]></getter>
<setter><![CDATA[
if (val)
this.setAttribute("selected", "true");
else
this.removeAttribute("selected");
return val;
]]></setter>
</property>
<property name="date">
<getter><![CDATA[
return this.mDate;
@ -456,8 +471,8 @@
}
if (itemIndex != -1) {
if (this.mSelectedOccurrence == this.mEvents[itemIndex])
this.mSelectedOccurrence = null;
if (this.mSelectedItem == this.mEvents[itemIndex])
this.mSelectedItem = null;
this.mEvents.splice(itemIndex, 1);
return true;
@ -1125,6 +1140,9 @@
- event.
-->
<handler event="mousedown" button="0"><![CDATA[
// select this column
this.calendarView.selectedDay = this.mDate;
// snap to 15 minute intervals
var interval = this.mPixPerMin * 15;
@ -1260,7 +1278,7 @@
<handlers>
<handler event="mousedown"><![CDATA[
event.preventBubble();
this.calendarView.selectedOccurrence = this.mOccurrence;
this.calendarView.selectedItem = this.mOccurrence;
this.mInMouseDown = true;
this.mMouseX = event.screenX;
@ -1346,7 +1364,7 @@
// ask the
var minutes = timebar.endMinute - timebar.startMinute;
var ppm = size / minutes;
dump ("new ppm: " + ppm + "\n");
//dump ("new ppm: " + ppm + "\n");
this.pixelsPerMinute = ppm;
]]></body>
</method>
@ -1357,11 +1375,12 @@
<field name="mEndDate">null</field>
<!-- mDateList will always be sorted before being set -->
<field name="mDateList">null</field>
<!-- array of { date: calIDatetime, col: column item } -->
<!-- array of { date: calIDatetime, column: colbox, header: hdrbox } -->
<field name="mDateColumns">null</field>
<field name="mBatchCount">0</field>
<field name="mPixPerMin">0.6</field>
<field name="mSelectedOccurrence">null</field>
<field name="mSelectedItem">null</field>
<field name="mSelectedDayCol">null</field>
<field name="mObserver"><![CDATA[
// the calIObserver, and calICompositeObserver
@ -1528,8 +1547,6 @@
<body><![CDATA[
var targetDate = aDate.clone();
targetDate.isDate = true;
if (targetDate.timezone != "UTC")
targetDate = targetDate.getInTimezone("UTC");
if (this.mStartDate && this.mEndDate) {
if (this.mStartDate.compare(targetDate) <= 0 &&
@ -1546,18 +1563,12 @@
// if we're only showing one date, then continue
// to only show one date; otherwise, show the week.
if (this.numVisibleDates == 1) {
var st = aDate;
var end = aDate.clone();
end.day += 1;
end.normalize();
this.setDateRange(st, end);
this.setDateRange(aDate, aDate);
} else {
var wkStart = aDate.startOfWeek;
var wkEnd = aDate.endOfWeek;
this.setDateRange(wkStart, wkEnd);
this.setDateRange(aDate.startOfWeek, aDate.endOfWeek);
}
this.selectedDay = aDate;
]]></body>
</method>
@ -1570,8 +1581,6 @@
this.mStartDate = aStartDate.clone();
this.mStartDate.makeImmutable();
this.mEndDate = aEndDate.clone();
this.mEndDate.day -= 1;
this.mEndDate.normalize();
this.mEndDate.makeImmutable();
// this function needs to be smarter, and needs to compare
@ -1631,18 +1640,54 @@
]]></body>
</method>
<property name="selectedOccurrence">
<property name="selectedDay">
<getter><![CDATA[
return this.mSelectedOccurrence;
if (this.numVisibleDates == 1)
return this.mDateColumns[0].date;
if (this.mSelectedDayCol)
return this.mSelectedDayCol.date;
return null;
]]></getter>
<setter><![CDATA[
if (this.mSelectedOccurrence != val) {
if (this.mSelectedOccurrence) {
var col = this.findColumnForEvent(this.mSelectedOccurrence);
// ignore if just 1 visible, it's always selected,
// but we don't indicate it
if (this.numVisibleDates == 1)
return val;
if (this.mSelectedDayCol) {
this.mSelectedDayCol.column.selected = false;
this.mSelectedDayCol.header.removeAttribute("selected");
}
if (val) {
this.mSelectedDayCol = this.findColumnForDate(val);
if (this.mSelectedDayCol) {
this.mSelectedDayCol.column.selected = true;
this.mSelectedDayCol.header.setAttribute("selected", "true");
} else {
dump ("XX couldn't find column to select for day: " + val + "\n");
return null;
}
}
return val;
]]></setter>
</property>
<property name="selectedItem">
<getter><![CDATA[
return this.mSelectedItem;
]]></getter>
<setter><![CDATA[
if (this.mSelectedItem != val) {
if (this.mSelectedItem) {
var col = this.findColumnForEvent(this.mSelectedItem);
if (col) {
col.column.selectOccurrence(null);
} else {
dump ("Thought I had a selected occurrence (id: " + this.mSelectedOccurrence.id + "), but couldn't find a column for it!\n");
dump ("Thought I had a selected occurrence (id: " + this.mSelectedItem.id + "), but couldn't find a column for it!\n");
}
}
@ -1654,7 +1699,7 @@
val = null;
}
return (this.mSelectedOccurrence = val);
return (this.mSelectedItem = val);
}
]]></setter>
</property>
@ -1782,6 +1827,9 @@
<method name="refresh">
<body><![CDATA[
if (!this.startDate || !this.endDate)
return;
// recreate our columns as necessary
this.relayout();
@ -1791,13 +1839,16 @@
// start our items query; for a disjoint date range
// we get all the items, and just filter out the ones we don't
// care about in addItem
//dump ("+++++++++ Calling getItems\n");
var queryEnd = this.endDate.clone();
queryEnd.day += 1;
queryEnd.normalize();
this.mCalendar.getItems(this.mCalendar.ITEM_FILTER_COMPLETED_ALL |
this.mCalendar.ITEM_FILTER_TYPE_EVENT |
this.mCalendar.ITEM_FILTER_CLASS_OCCURRENCES,
0,
this.startDate,
this.endDate,
queryEnd,
this.mOperationListener);
]]></body>
</method>
@ -1889,9 +1940,6 @@
d.isDate = true;
if (d.timezone != "UTC")
d = d.getInTimezone("UTC");
this.mDateColumns.push ( { date: d, column: dayEventsBox, header: dayHeaderBox } );
}
@ -1900,26 +1948,25 @@
]]></body>
</method>
<method name="findColumnForDate">
<parameter name="aDate"/>
<body><![CDATA[
for each (var col in this.mDateColumns) {
if (col.date.compare(aDate) == 0)
return col;
}
return null;
]]></body>
</method>
<method name="findColumnForEvent">
<parameter name="aEvent"/>
<body><![CDATA[
var estart = aEvent.startDate;
var eend = aEvent.endDate;
var eday = estart.clone();
eday.isDate = true;
if (eday.timezone != "UTC")
eday = eday.getInTimezone("UTC");
var column = null;
var header = null;
for each (var col in this.mDateColumns) {
if (col.date.compare(eday) == 0) {
return col;
}
}
return null;
return this.findColumnForDate(estart);
]]></body>
</method>
@ -2001,8 +2048,8 @@
if (event.keyCode == kKE.DOM_VK_BACK_SPACE ||
event.keyCode == kKE.DOM_VK_DELETE)
{
if (this.selectedOccurrence && this.controller) {
var occurrence = (event.ctrlKey) ? this.selectedOccurrence.parentItem : this.selectedOccurrence;
if (this.selectedItem && this.controller) {
var occurrence = (event.ctrlKey) ? this.selectedItem.parentItem : this.selectedItem;
this.controller.deleteOccurrence(occurrence);
}
}

View File

@ -44,7 +44,7 @@ interface calIDateTime;
interface calICalendarViewController;
interface calIItemBase;
[scriptable, uuid(448a7f1a-384c-4e47-b5b5-1c372b4ad3d1)]
[scriptable, uuid(3e567ccb-2ecf-4f59-b7ca-bf42b0fbf24a)]
interface calICalendarView : nsISupports
{
/**
@ -60,13 +60,13 @@ interface calICalendarView : nsISupports
/**
* Ensure that the given date is visible; the view is free
* to show more dates than the given date (e.g. week view
* would show the entire week.
* would show the entire week).
*/
void showDate(in calIDateTime aDate);
/**
* Set a date range for the view to display, from aStartDate
* inclusive to aEndDate, not inclusive.
* to aEndDate, inclusive.
*
* Some views may decide to utilize the time portion of these
* calIDateTimes; pass in calIDateTimes that are dates if you
@ -116,4 +116,9 @@ interface calICalendarView : nsISupports
* Get or set the selected item. Only one item may be selected.
*/
attribute calIItemBase selectedItem;
/**
* Get or set the selected day.
*/
attribute calIDateTime selectedDay;
};

View File

@ -19,6 +19,13 @@ function ltnEditSelectedCalendar()
ltnEditCalendarProperties(ltnSelectedCalendar());
}
function today()
{
var d = Components.classes['@mozilla.org/calendar/datetime;1'].createInstance(Components.interfaces.calIDateTime);
d.jsDate = new Date();
return d.getInTimezone(calendarDefaultTimezone());
}
function nextMonth(dt)
{
var d = new Date(dt);
@ -49,12 +56,10 @@ function ltnMinimonthPick(which, minimonth)
var cdt = new CalDateTime();
cdt.jsDate = minimonth.value;
cdt = cdt.getInTimezone(calendarDefaultTimezone());
cdt.isDate = true;
currentView().showDate(cdt);
showCalendar(false);
showCalendar(cdt);
}
function ltnOnLoad(event)
@ -68,6 +73,10 @@ function ltnOnLoad(event)
document.getElementById("ltnMinimonthRight").showMonth(nextmo);
gMiniMonthLoading = false;
// nuke the onload, or we get called every time there's
// any load that occurs
document.removeEventListener("load", ltnOnLoad, true);
}
function currentView()
@ -76,23 +85,22 @@ function currentView()
return calendarViewBox.selectedPanel;
}
function showCalendar(jumpToToday)
function showCalendar(aDate1, aDate2)
{
document.getElementById("displayDeck").selectedPanel =
document.getElementById("calendar-view-box");
var view = currentView();
if (jumpToToday) {
var d = Components.classes['@mozilla.org/calendar/datetime;1'].createInstance(Components.interfaces.calIDateTime);
d.jsDate = new Date();
d = d.getInTimezone(calendarDefaultTimezone());
view.showDate(d);
}
if (view.displayCalendar != getCompositeCalendar()) {
view.displayCalendar = getCompositeCalendar();
view.controller = ltnCalendarViewController;
}
if (aDate1 && !aDate2)
view.showDate(aDate1);
else if (aDate1 && aDate2)
view.setDateRange(aDate1, aDate2);
document.getElementById("displayDeck").selectedPanel =
document.getElementById("calendar-view-box");
}
function switchView(type) {
@ -102,56 +110,46 @@ function switchView(type) {
var monthView = document.getElementById("calendar-month-view");
var multidayView = document.getElementById("calendar-multiday-view");
// XXX we need a selectedDate in calICalendarView.idl!
var selectedDate = calendarViewBox.selectedPanel.startDate;
var selectedDay = calendarViewBox.selectedPanel.selectedDay;
if (!selectedDate) {
var d = Components.classes['@mozilla.org/calendar/datetime;1'].createInstance(Components.interfaces.calIDateTime);
d.jsDate = new Date();
selectedDate = d.getInTimezone(calendarDefaultTimezone());
}
if (!selectedDay)
selectedDay = today();
var d1, d2;
switch (type) {
case "month": {
monthView.showDate(selectedDate);
d1 = selectedDay;
calendarViewBox.selectedPanel = monthView;
}
break;
case "week": {
var start = selectedDate.startOfWeek;
var end = selectedDate.endOfWeek.clone();
end.day += 1;
end.normalize();
multidayView.setDateRange(start, end);
d1 = selectedDay.startOfWeek;
d2 = selectedDay.endOfWeek;
calendarViewBox.selectedPanel = multidayView;
}
break;
case "day":
default: {
var start = selectedDate;
var end = selectedDate.clone();
end.day += 1;
end.normalize();
multidayView.setDateRange(start, end);
d1 = selectedDay;
d2 = selectedDay;
calendarViewBox.selectedPanel = multidayView;
}
break;
}
if (messengerDisplayDeck.selectedPanel = calendarViewBox)
showCalendar(false);
else
showCalendar(true);
showCalendar(d1, d2);
calendarViewBox.selectedPanel.selectedDay = selectedDay;
}
function selectedCalendarPane(event)
{
dump("selecting calendar pane\n");
document.getElementById("displayDeck").selectedPanel =
document.getElementById("calendar-view-box");
// give the view the calendar
showCalendar(true);
showCalendar(today());
}
function LtnObserveDisplayDeckChange(event)