Merge lp:~frankencode/ubuntu-calendar-app/MonthView into lp:ubuntu-calendar-app
- MonthView
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 6 |
Proposed branch: | lp:~frankencode/ubuntu-calendar-app/MonthView |
Merge into: | lp:ubuntu-calendar-app |
Diff against target: |
620 lines (+409/-118) 7 files modified
Calendar.desktop (+9/-0) DateLib.js (+47/-5) EventView.qml (+72/-0) MonthView.qml (+178/-55) calendar.qml (+89/-58) colorUtils.js (+10/-0) testrun.sh (+4/-0) |
To merge this branch: | bzr merge lp:~frankencode/ubuntu-calendar-app/MonthView |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mario Boikov (community) | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+152655@code.launchpad.net |
Commit message
First basic prototype of the calendar key journeys.
Description of the change
First basic prototype of the calendar key journeys.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Mario Boikov (mariob) wrote : | # |
In 'daysInMonth' function: Shouldn't the leap year thing only be applied to 'February'?
Now every month gets an extra day for a leap year. Would be great thou :)
- 24. By Frank Mertens
-
Fix for leap year: add leap day only to Feb.
Frank Mertens (frankencode) wrote : | # |
Ups, smth. got lost there when I was reformatting the code from C++.
(You have eagles eyes!)
Mario Boikov (mariob) wrote : | # |
> Ups, smth. got lost there when I was reformatting the code from C++.
> (You have eagles eyes!)
LOL! Actually, I was doing a similar function myself the other day, that why I spotted it :)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:24
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === added file 'Calendar.desktop' | |||
2 | --- Calendar.desktop 1970-01-01 00:00:00 +0000 | |||
3 | +++ Calendar.desktop 2013-03-11 18:20:26 +0000 | |||
4 | @@ -0,0 +1,9 @@ | |||
5 | 1 | [Desktop Entry] | ||
6 | 2 | Encoding=UTF-8 | ||
7 | 3 | Type=Application | ||
8 | 4 | Terminal=false | ||
9 | 5 | Exec=/usr/bin/qmlscene | ||
10 | 6 | Name=Calendar | ||
11 | 7 | GenericName=Calendar | ||
12 | 8 | Comment=Ubuntu Calendar | ||
13 | 9 | Icon=ubuntu-qmlrunner | ||
14 | 0 | 10 | ||
15 | === renamed file 'dateTimeUtils.js' => 'DateLib.js' | |||
16 | --- dateTimeUtils.js 2013-02-14 18:03:27 +0000 | |||
17 | +++ DateLib.js 2013-03-11 18:20:26 +0000 | |||
18 | @@ -1,17 +1,51 @@ | |||
19 | 1 | .pragma library | 1 | .pragma library |
20 | 2 | 2 | ||
23 | 3 | var msPerDay = 86400e3 | 3 | Date.msPerDay = 86400e3 |
24 | 4 | var msPerWeek = msPerDay * 7 | 4 | Date.msPerWeek = Date.msPerDay * 7 |
25 | 5 | |||
26 | 6 | Date.leapYear = function(year) { | ||
27 | 7 | return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) | ||
28 | 8 | } | ||
29 | 9 | |||
30 | 10 | Date.daysInMonth = function(year, month) { | ||
31 | 11 | return [ | ||
32 | 12 | 31/*Jan*/, 28/*Feb*/, 31/*Mar*/, 30/*Apr*/, 31/*May*/, 30/*Jun*/, | ||
33 | 13 | 31/*Jul*/, 31/*Aug*/, 30/*Sep*/, 31/*Oct*/, 30/*Nov*/, 31/*Dec*/ | ||
34 | 14 | ][month] + (month == 1) * Date.leapYear(year) | ||
35 | 15 | } | ||
36 | 16 | |||
37 | 17 | Date.weeksInMonth = function(year, month, weekday) { | ||
38 | 18 | var y = year, m = month | ||
39 | 19 | var date0 = new Date(y, m, 1) | ||
40 | 20 | var date1 = new Date(y + (m == 11), m < 11 ? m + 1 : 0, 1) | ||
41 | 21 | var day = date0.getDay() | ||
42 | 22 | var m = (date1.getTime() - date0.getTime()) / Date.msPerDay | ||
43 | 23 | var n = 0 | ||
44 | 24 | while (m > 0) { | ||
45 | 25 | if (day == weekday) n = n + 1 | ||
46 | 26 | day = day < 6 ? day + 1 : 0 | ||
47 | 27 | m = m - 1 | ||
48 | 28 | } | ||
49 | 29 | return n | ||
50 | 30 | } | ||
51 | 5 | 31 | ||
52 | 6 | Date.prototype.midnight = function() { | 32 | Date.prototype.midnight = function() { |
53 | 7 | var date = new Date(this) | 33 | var date = new Date(this) |
55 | 8 | date.setTime(date.getTime() - date.getTime() % msPerDay) | 34 | var t = date.getTime() |
56 | 35 | if (t % Date.msPerDay != 0) | ||
57 | 36 | date.setTime(t - t % Date.msPerDay) | ||
58 | 9 | return date | 37 | return date |
59 | 10 | } | 38 | } |
60 | 11 | 39 | ||
61 | 12 | Date.prototype.addDays = function(days) { | 40 | Date.prototype.addDays = function(days) { |
62 | 13 | var date = new Date(this) | 41 | var date = new Date(this) |
64 | 14 | date.setTime(date.getTime() + msPerDay * days) | 42 | date.setTime(date.getTime() + Date.msPerDay * days) |
65 | 43 | return date | ||
66 | 44 | } | ||
67 | 45 | |||
68 | 46 | Date.prototype.addMonths = function(months) { | ||
69 | 47 | var date = new Date(this) | ||
70 | 48 | date.setUTCMonth(date.getUTCMonth() + months) | ||
71 | 15 | return date | 49 | return date |
72 | 16 | } | 50 | } |
73 | 17 | 51 | ||
74 | @@ -26,14 +60,22 @@ | |||
75 | 26 | return date.addDays(-n) | 60 | return date.addDays(-n) |
76 | 27 | } | 61 | } |
77 | 28 | 62 | ||
78 | 63 | Date.prototype.monthStart = function() { | ||
79 | 64 | return this.midnight().addDays(1 - this.getDate()) | ||
80 | 65 | } | ||
81 | 66 | |||
82 | 29 | Date.prototype.weekNumber = function() { | 67 | Date.prototype.weekNumber = function() { |
83 | 30 | var date = this.weekStart(1).addDays(3) // Thursday midnight | 68 | var date = this.weekStart(1).addDays(3) // Thursday midnight |
84 | 31 | var newYear = new Date(date.getFullYear(), 0 /*Jan*/, 1 /*the 1st*/) | 69 | var newYear = new Date(date.getFullYear(), 0 /*Jan*/, 1 /*the 1st*/) |
85 | 32 | var n = 0 | 70 | var n = 0 |
86 | 33 | var tx = date.getTime(), tn = newYear.getTime() | 71 | var tx = date.getTime(), tn = newYear.getTime() |
87 | 34 | while (tn < tx) { | 72 | while (tn < tx) { |
89 | 35 | tx = tx - msPerWeek | 73 | tx = tx - Date.msPerWeek |
90 | 36 | n = n + 1 | 74 | n = n + 1 |
91 | 37 | } | 75 | } |
92 | 38 | return n | 76 | return n |
93 | 39 | } | 77 | } |
94 | 78 | |||
95 | 79 | Date.prototype.weeksInMonth = function(weekday) { | ||
96 | 80 | return Date.weeksInMonth(this.getFullYear(), this.getMonth(), weekday) | ||
97 | 81 | } | ||
98 | 40 | 82 | ||
99 | === added file 'EventView.qml' | |||
100 | --- EventView.qml 1970-01-01 00:00:00 +0000 | |||
101 | +++ EventView.qml 2013-03-11 18:20:26 +0000 | |||
102 | @@ -0,0 +1,72 @@ | |||
103 | 1 | import QtQuick 2.0 | ||
104 | 2 | import Ubuntu.Components 0.1 | ||
105 | 3 | import "DateLib.js" as DateLib | ||
106 | 4 | |||
107 | 5 | PathView { | ||
108 | 6 | id: eventView | ||
109 | 7 | |||
110 | 8 | property var currentDayStart: (new Date()).midnight() | ||
111 | 9 | |||
112 | 10 | signal incrementCurrentDay | ||
113 | 11 | signal decrementCurrentDay | ||
114 | 12 | |||
115 | 13 | readonly property real visibleHeight: parent.height - y | ||
116 | 14 | |||
117 | 15 | QtObject { | ||
118 | 16 | id: intern | ||
119 | 17 | property int currentIndexSaved: 0 | ||
120 | 18 | property int currentIndex: 0 | ||
121 | 19 | property var currentDayStart: (new Date()).midnight() | ||
122 | 20 | } | ||
123 | 21 | |||
124 | 22 | onCurrentIndexChanged: { | ||
125 | 23 | var delta = currentIndex - intern.currentIndexSaved | ||
126 | 24 | if (intern.currentIndexSaved == count - 1 && currentIndex == 0) delta = 1 | ||
127 | 25 | if (intern.currentIndexSaved == 0 && currentIndex == count - 1) delta = -1 | ||
128 | 26 | intern.currentIndexSaved = currentIndex | ||
129 | 27 | if (delta > 0) incrementCurrentDay() | ||
130 | 28 | else decrementCurrentDay() | ||
131 | 29 | } | ||
132 | 30 | |||
133 | 31 | onCurrentDayStartChanged: { | ||
134 | 32 | if (!moving) intern.currentDayStart = currentDayStart | ||
135 | 33 | } | ||
136 | 34 | |||
137 | 35 | onMovementEnded: { | ||
138 | 36 | intern.currentDayStart = currentDayStart | ||
139 | 37 | intern.currentIndex = currentIndex | ||
140 | 38 | } | ||
141 | 39 | |||
142 | 40 | preferredHighlightBegin: 0.5 | ||
143 | 41 | preferredHighlightEnd: 0.5 | ||
144 | 42 | highlightRangeMode: PathView.StrictlyEnforceRange | ||
145 | 43 | |||
146 | 44 | path: Path { | ||
147 | 45 | startX: -eventView.width; startY: eventView.height / 2 | ||
148 | 46 | PathLine { relativeX: eventView.width; relativeY: 0 } | ||
149 | 47 | PathLine { relativeX: eventView.width; relativeY: 0 } | ||
150 | 48 | PathLine { relativeX: eventView.width; relativeY: 0 } | ||
151 | 49 | } | ||
152 | 50 | |||
153 | 51 | snapMode: PathView.SnapOneItem | ||
154 | 52 | |||
155 | 53 | model: 3 | ||
156 | 54 | |||
157 | 55 | delegate: Rectangle { | ||
158 | 56 | property var dayStart: { | ||
159 | 57 | if (index == intern.currentIndex) return intern.currentDayStart | ||
160 | 58 | var previousIndex = intern.currentIndex > 0 ? intern.currentIndex - 1 : 2 | ||
161 | 59 | if (index == previousIndex) return intern.currentDayStart.addDays(-1) | ||
162 | 60 | return intern.currentDayStart.addDays(1) | ||
163 | 61 | } | ||
164 | 62 | width: eventView.width | ||
165 | 63 | height: eventView.height | ||
166 | 64 | color: index == 0 ? "#FFFFFF" : index == 1 ? "#EEEEEE" : "#DDDDDD" | ||
167 | 65 | Label { | ||
168 | 66 | anchors.horizontalCenter: parent.horizontalCenter | ||
169 | 67 | y: units.gu(4) | ||
170 | 68 | text: i18n.tr("No events for") + "\n" + Qt.formatDate(dayStart) | ||
171 | 69 | fontSize: "large" | ||
172 | 70 | } | ||
173 | 71 | } | ||
174 | 72 | } | ||
175 | 0 | 73 | ||
176 | === modified file 'MonthView.qml' | |||
177 | --- MonthView.qml 2013-02-15 08:10:23 +0000 | |||
178 | +++ MonthView.qml 2013-03-11 18:20:26 +0000 | |||
179 | @@ -1,73 +1,196 @@ | |||
180 | 1 | import QtQuick 2.0 | 1 | import QtQuick 2.0 |
181 | 2 | import Ubuntu.Components 0.1 | 2 | import Ubuntu.Components 0.1 |
183 | 3 | import "dateTimeUtils.js" as DateTime | 3 | import "DateLib.js" as DateLib |
184 | 4 | import "colorUtils.js" as Color | ||
185 | 4 | 5 | ||
186 | 5 | ListView { | 6 | ListView { |
195 | 6 | id: monthView // id for internal reference | 7 | id: monthView |
196 | 7 | 8 | ||
197 | 8 | // public properties | 9 | readonly property var monthStart: currentItem != null ? currentItem.monthStart : (new Date()).monthStart() |
198 | 9 | property bool portraitMode: width < height | 10 | readonly property var monthEnd: currentItem != null ? currentItem.monthEnd : (new Date()).monthStart().addMonths(1) |
199 | 10 | property real weeksInView: 8 | 11 | readonly property var currentDayStart: intern.currentDayStart |
200 | 11 | property int weekStartDay: 1 // Monday, FIXME: depends on locale / user settings | 12 | |
201 | 12 | 13 | property bool compressed: false | |
202 | 13 | // private properties | 14 | property real compressedHeight: intern.squareUnit + intern.verticalMargin * 2 |
203 | 15 | |||
204 | 16 | signal incrementCurrentDay | ||
205 | 17 | signal decrementCurrentDay | ||
206 | 18 | |||
207 | 19 | signal gotoNextMonth(int month) | ||
208 | 20 | signal focusOnDay(var dayStart) | ||
209 | 21 | |||
210 | 22 | onCurrentItemChanged: { | ||
211 | 23 | if (currentItem == null) { | ||
212 | 24 | intern.currentDayStart = intern.currentDayStart | ||
213 | 25 | return | ||
214 | 26 | } | ||
215 | 27 | if (currentItem.monthStart <= intern.currentDayStart && intern.currentDayStart < currentItem.monthEnd) | ||
216 | 28 | return | ||
217 | 29 | if (currentItem.monthStart <= intern.today && intern.today < currentItem.monthEnd) | ||
218 | 30 | intern.currentDayStart = intern.today | ||
219 | 31 | else | ||
220 | 32 | intern.currentDayStart = currentItem.monthStart | ||
221 | 33 | } | ||
222 | 34 | |||
223 | 35 | onIncrementCurrentDay: { | ||
224 | 36 | var t = intern.currentDayStart.addDays(1) | ||
225 | 37 | if (t < monthEnd) { | ||
226 | 38 | intern.currentDayStart = t | ||
227 | 39 | } | ||
228 | 40 | else if (currentIndex < count - 1) { | ||
229 | 41 | intern.currentDayStart = t | ||
230 | 42 | currentIndex = currentIndex + 1 | ||
231 | 43 | } | ||
232 | 44 | } | ||
233 | 45 | |||
234 | 46 | onDecrementCurrentDay: { | ||
235 | 47 | var t = intern.currentDayStart.addDays(-1) | ||
236 | 48 | if (t >= monthStart) { | ||
237 | 49 | intern.currentDayStart = t | ||
238 | 50 | } | ||
239 | 51 | else if (currentIndex > 0) { | ||
240 | 52 | intern.currentDayStart = t | ||
241 | 53 | currentIndex = currentIndex - 1 | ||
242 | 54 | } | ||
243 | 55 | } | ||
244 | 56 | |||
245 | 57 | onGotoNextMonth: { | ||
246 | 58 | if (monthStart.getMonth() != month) { | ||
247 | 59 | var i = intern.monthIndex0, m = intern.today.getMonth() | ||
248 | 60 | while (m != month) { | ||
249 | 61 | m = (m + 1) % 12 | ||
250 | 62 | i = i + 1 | ||
251 | 63 | } | ||
252 | 64 | currentIndex = i | ||
253 | 65 | } | ||
254 | 66 | } | ||
255 | 67 | |||
256 | 68 | onFocusOnDay: { | ||
257 | 69 | if (dayStart < monthStart) { | ||
258 | 70 | if (currentIndex > 0) { | ||
259 | 71 | intern.currentDayStart = dayStart | ||
260 | 72 | currentIndex = currentIndex - 1 | ||
261 | 73 | } | ||
262 | 74 | } | ||
263 | 75 | else if (dayStart >= monthEnd) { | ||
264 | 76 | if (currentIndex < count - 1) { | ||
265 | 77 | intern.currentDayStart = dayStart | ||
266 | 78 | currentIndex = currentIndex + 1 | ||
267 | 79 | } | ||
268 | 80 | } | ||
269 | 81 | else intern.currentDayStart = dayStart | ||
270 | 82 | } | ||
271 | 83 | |||
272 | 84 | focus: true | ||
273 | 85 | Keys.onLeftPressed: decrementCurrentDay() | ||
274 | 86 | Keys.onRightPressed: incrementCurrentDay() | ||
275 | 87 | |||
276 | 14 | QtObject { | 88 | QtObject { |
283 | 15 | id: internal | 89 | id: intern |
284 | 16 | 90 | ||
285 | 17 | property real weekHeight: monthView.height / monthView.weeksInView | 0 | 91 | property int squareUnit: monthView.width / 8 |
286 | 18 | property int indexOrigin: monthView.count / 2 | 92 | property int verticalMargin: units.gu(1) |
287 | 19 | property var timeOrigin: (new Date()).weekStart(monthView.weekStartDay) | 93 | property int weekstartDay: Qt.locale().firstDayOfWeek |
288 | 20 | property var today: (new Date()).midnight() | 94 | property int monthCount: 49 // months for +-2 years |
289 | 95 | |||
290 | 96 | property var today: (new Date()).midnight() // TODO: update at midnight | ||
291 | 97 | property var currentDayStart: today | ||
292 | 98 | property int monthIndex0: Math.floor(monthCount / 2) | ||
293 | 99 | property var monthStart0: today.monthStart() | ||
294 | 21 | } | 100 | } |
295 | 22 | 101 | ||
296 | 102 | width: parent.width | ||
297 | 103 | height: intern.squareUnit * 6 + intern.verticalMargin * 2 | ||
298 | 104 | |||
299 | 105 | interactive: !compressed | ||
300 | 23 | clip: true | 106 | clip: true |
303 | 24 | 107 | orientation: ListView.Horizontal | |
304 | 25 | model: 1041 // weeks for about +-10y | 108 | snapMode: ListView.SnapOneItem |
305 | 109 | cacheBuffer: width + 1 | ||
306 | 110 | |||
307 | 111 | highlightRangeMode: ListView.StrictlyEnforceRange | ||
308 | 112 | preferredHighlightBegin: 0 | ||
309 | 113 | preferredHighlightEnd: width | ||
310 | 114 | |||
311 | 115 | model: intern.monthCount | ||
312 | 116 | currentIndex: intern.monthIndex0 | ||
313 | 26 | 117 | ||
314 | 27 | delegate: Item { | 118 | delegate: Item { |
325 | 28 | id: weekItem | 119 | id: monthItem |
326 | 29 | 120 | ||
327 | 30 | property var weekOrigin: internal.timeOrigin.addDays((index - internal.indexOrigin) * 7) | 121 | property var monthStart: intern.monthStart0.addMonths(index - intern.monthIndex0) |
328 | 31 | 122 | property var monthEnd: monthStart.addMonths(1) | |
329 | 32 | width: parent.width | 123 | property var gridStart: monthStart.weekStart(intern.weekstartDay) |
330 | 33 | height: internal.weekHeight | 124 | property int currentWeekRow: Math.floor((currentDayStart.getTime() - gridStart.getTime()) / Date.msPerWeek) |
331 | 34 | 125 | ||
332 | 35 | Row { | 126 | width: monthView.width |
333 | 36 | anchors.fill: parent | 127 | height: monthView.height |
334 | 37 | spacing: 1 | 128 | |
335 | 129 | Grid { | ||
336 | 130 | id: monthGrid | ||
337 | 131 | |||
338 | 132 | rows: 6 | ||
339 | 133 | columns: 7 | ||
340 | 134 | |||
341 | 135 | x: intern.squareUnit / 2 | ||
342 | 136 | y: intern.verticalMargin | ||
343 | 137 | width: intern.squareUnit * columns | ||
344 | 138 | height: intern.squareUnit * rows | ||
345 | 38 | 139 | ||
346 | 39 | Repeater { | 140 | Repeater { |
349 | 40 | model: 7 | 141 | model: monthGrid.rows * monthGrid.columns |
350 | 41 | delegate: Rectangle { | 142 | delegate: Item { |
351 | 42 | id: dayItem | 143 | id: dayItem |
361 | 43 | 144 | property var dayStart: gridStart.addDays(index) | |
362 | 44 | property var dayOrigin: weekOrigin.addDays(index) | 145 | property bool isCurrentMonth: monthStart <= dayStart && dayStart < monthEnd |
363 | 45 | property bool isToday: internal.today.getTime() == dayOrigin.getTime() | 146 | property bool isToday: dayStart.getTime() == intern.today.getTime() |
364 | 46 | 147 | property bool isCurrent: dayStart.getTime() == intern.currentDayStart.getTime() | |
365 | 47 | width: weekItem.width / 7 | 148 | property int weekday: (index % 7 + intern.weekstartDay) % 7 |
366 | 48 | height: weekItem.height - 1 | 149 | property bool isSunday: weekday == 0 |
367 | 49 | color: isToday ? "#c94212" : dayOrigin.getMonth() % 2 ? "#c4c4c4" : "#e0e0e0" | 150 | property int row: Math.floor(index / 7) |
368 | 50 | 151 | property bool isCurrentWeek: row == currentWeekRow | |
369 | 51 | Label { | 152 | property real topMargin: (row == 0 || (monthView.compressed && isCurrentWeek)) ? -intern.verticalMargin : 0 |
370 | 153 | property real bottomMargin: (row == 5 || (monthView.compressed && isCurrentWeek)) ? -intern.verticalMargin : 0 | ||
371 | 154 | visible: monthView.compressed ? isCurrentWeek : true | ||
372 | 155 | width: intern.squareUnit | ||
373 | 156 | height: intern.squareUnit | ||
374 | 157 | Rectangle { | ||
375 | 158 | visible: isSunday | ||
376 | 159 | anchors.fill: parent | ||
377 | 160 | anchors.topMargin: dayItem.topMargin | ||
378 | 161 | anchors.bottomMargin: dayItem.bottomMargin | ||
379 | 162 | color: Color.warmGrey | ||
380 | 163 | opacity: 0.1 | ||
381 | 164 | } | ||
382 | 165 | Text { | ||
383 | 52 | anchors.centerIn: parent | 166 | anchors.centerIn: parent |
387 | 53 | text: dayOrigin.getDate() | 167 | text: dayStart.getDate() |
388 | 54 | color: isToday ? "white" : dayOrigin.getDay() == 0 ? "#c94212" : "#404040" | 168 | font: themeDummy.font |
389 | 55 | } | 169 | color: isToday ? Color.ubuntuOrange : themeDummy.color |
390 | 170 | scale: isCurrent ? 1.8 : 1. | ||
391 | 171 | opacity: isCurrentMonth ? 1. : 0.3 | ||
392 | 172 | Behavior on scale { | ||
393 | 173 | NumberAnimation { duration: 50 } | ||
394 | 174 | } | ||
395 | 175 | } | ||
396 | 176 | MouseArea { | ||
397 | 177 | anchors.fill: parent | ||
398 | 178 | anchors.topMargin: dayItem.topMargin | ||
399 | 179 | anchors.bottomMargin: dayItem.bottomMargin | ||
400 | 180 | onReleased: monthView.focusOnDay(dayStart) | ||
401 | 181 | } | ||
402 | 182 | // Component.onCompleted: console.log(dayStart, intern.currentDayStart) | ||
403 | 56 | } | 183 | } |
404 | 57 | } | 184 | } |
405 | 58 | } | 185 | } |
420 | 59 | } | 186 | |
421 | 60 | 187 | // Component.onCompleted: console.log("Created delegate for month", index, monthStart, gridStart, currentWeekRow, currentWeekRowReal) | |
422 | 61 | Timer { // make sure today is updated at midnight | 188 | } |
423 | 62 | interval: 1000 | 189 | |
424 | 63 | repeat: true | 190 | Label { |
425 | 64 | running: true | 191 | visible: false |
426 | 65 | 192 | id: themeDummy | |
427 | 66 | onTriggered: { | 193 | fontSize: "large" |
428 | 67 | var newDate = (new Date()).midnight() | 194 | // Component.onCompleted: console.log(color, Qt.lighter(color, 1.74)) |
429 | 68 | if (internal.today < newDate) internal.today = newDate | 195 | } |
416 | 69 | } | ||
417 | 70 | } | ||
418 | 71 | |||
419 | 72 | Component.onCompleted: positionViewAtIndex(internal.indexOrigin, ListView.Center) | ||
430 | 73 | } | 196 | } |
431 | 74 | 197 | ||
432 | === modified file 'calendar.qml' | |||
433 | --- calendar.qml 2013-02-14 18:03:27 +0000 | |||
434 | +++ calendar.qml 2013-03-11 18:20:26 +0000 | |||
435 | @@ -1,72 +1,103 @@ | |||
436 | 1 | import QtQuick 2.0 | 1 | import QtQuick 2.0 |
437 | 2 | import Ubuntu.Components 0.1 | 2 | import Ubuntu.Components 0.1 |
438 | 3 | 3 | ||
439 | 4 | /*! | ||
440 | 5 | \brief MainView with Tabs element. | ||
441 | 6 | First Tab has a single Label and | ||
442 | 7 | second Tab has a single ToolbarAction. | ||
443 | 8 | */ | ||
444 | 9 | |||
445 | 10 | MainView { | 4 | MainView { |
446 | 11 | // objectName for functional testing purposes (autopilot-qt5) | ||
447 | 12 | objectName: "calendar" | ||
448 | 13 | |||
449 | 14 | id: mainView | 5 | id: mainView |
450 | 15 | width: units.gu(45) | 6 | width: units.gu(45) |
451 | 16 | height: units.gu(80) | 7 | height: units.gu(80) |
453 | 17 | // FIXME: 80/45 = aspect ration of galaxy nexus | 8 | // FIXME: 80/45 = aspect ration of Galaxy Nexus |
454 | 18 | 9 | ||
456 | 19 | Tabs { | 10 | Tabs { // preliminary HACK, needs rewrite when NewTabBar is finalized! |
457 | 20 | id: tabs | 11 | id: tabs |
458 | 21 | anchors.fill: parent | 12 | anchors.fill: parent |
459 | 22 | 13 | ||
507 | 23 | // First tab begins here | 14 | Tab { id: pageArea; title: i18n.tr("January"); page: Item { anchors.fill: parent } } |
508 | 24 | Tab { | 15 | Tab { title: i18n.tr("February") } |
509 | 25 | objectName: "Tab1" | 16 | Tab { title: i18n.tr("March") } |
510 | 26 | 17 | Tab { title: i18n.tr("April") } | |
511 | 27 | title: i18n.tr("Calendar") | 18 | Tab { title: i18n.tr("May") } |
512 | 28 | 19 | Tab { title: i18n.tr("June") } | |
513 | 29 | // Tab content begins here | 20 | Tab { title: i18n.tr("July") } |
514 | 30 | page: Page { | 21 | Tab { title: i18n.tr("August") } |
515 | 31 | MonthView { | 22 | Tab { title: i18n.tr("September") } |
516 | 32 | width: mainView.width | 23 | Tab { title: i18n.tr("October") } |
517 | 33 | height: mainView.height | 24 | Tab { title: i18n.tr("November") } |
518 | 34 | // anchors.fill: parent // FIXME: delivers broken geometry on startup | 25 | Tab { title: i18n.tr("December") } |
519 | 35 | } | 26 | |
520 | 36 | } | 27 | onSelectedTabIndexChanged: monthView.gotoNextMonth(selectedTabIndex) |
521 | 37 | } | 28 | } |
522 | 38 | 29 | ||
523 | 39 | // Second tab begins here | 30 | MonthView { |
524 | 40 | Tab { | 31 | id: monthView |
525 | 41 | objectName: "Tab2" | 32 | onMonthStartChanged: tabs.selectedTabIndex = monthStart.getMonth() |
526 | 42 | 33 | y: pageArea.y | |
527 | 43 | title: i18n.tr("Optional Screen") | 34 | } |
528 | 44 | page: Page { | 35 | |
529 | 45 | anchors.margins: units.gu(2) | 36 | EventView { |
530 | 46 | 37 | id: eventView | |
531 | 47 | tools: ToolbarActions { | 38 | property real minY: pageArea.y + monthView.compressedHeight |
532 | 48 | Action { | 39 | property real maxY: pageArea.y + monthView.height |
533 | 49 | objectName: "action" | 40 | y: maxY |
534 | 50 | 41 | width: mainView.width | |
535 | 51 | iconSource: Qt.resolvedUrl("avatar.png") | 42 | height: parent.height - monthView.compressedHeight |
536 | 52 | text: i18n.tr("Tap me!") | 43 | currentDayStart: monthView.currentDayStart |
537 | 53 | 44 | Component.onCompleted: { | |
538 | 54 | onTriggered: { | 45 | incrementCurrentDay.connect(monthView.incrementCurrentDay) |
539 | 55 | label.text = i18n.tr("Toolbar tapped") | 46 | decrementCurrentDay.connect(monthView.decrementCurrentDay) |
540 | 56 | } | 47 | } |
541 | 57 | } | 48 | MouseArea { |
542 | 58 | } | 49 | id: drawer |
543 | 59 | 50 | property bool compression: true | |
544 | 60 | Column { | 51 | anchors.fill: parent |
545 | 61 | anchors.centerIn: parent | 52 | drag { |
546 | 62 | Label { | 53 | axis: Drag.YAxis |
547 | 63 | id: label | 54 | target: eventView |
548 | 64 | objectName: "label" | 55 | minimumY: monthView.y + monthView.compressedHeight |
549 | 65 | 56 | maximumY: monthView.y + monthView.height | |
550 | 66 | text: i18n.tr("Swipe from bottom to up to reveal the toolbar.") | 57 | onActiveChanged: { |
551 | 67 | } | 58 | if (compression) { |
552 | 68 | } | 59 | if (drag.active) { |
553 | 69 | } | 60 | monthView.compressed = true |
554 | 61 | } | ||
555 | 62 | else { | ||
556 | 63 | yBehavior.enabled = true | ||
557 | 64 | eventView.y = Qt.binding(function() { return eventView.minY }) | ||
558 | 65 | compression = false | ||
559 | 66 | } | ||
560 | 67 | } | ||
561 | 68 | else { | ||
562 | 69 | if (drag.active) {} | ||
563 | 70 | else{ | ||
564 | 71 | eventView.y = Qt.binding(function() { return eventView.maxY }) | ||
565 | 72 | monthView.compressed = false | ||
566 | 73 | compression = true | ||
567 | 74 | } | ||
568 | 75 | } | ||
569 | 76 | } | ||
570 | 77 | } | ||
571 | 78 | } | ||
572 | 79 | Behavior on y { | ||
573 | 80 | id: yBehavior | ||
574 | 81 | enabled: false | ||
575 | 82 | NumberAnimation { duration: 100 } | ||
576 | 83 | } | ||
577 | 84 | } | ||
578 | 85 | |||
579 | 86 | tools: ToolbarActions { | ||
580 | 87 | Action { | ||
581 | 88 | iconSource: Qt.resolvedUrl("avatar.png") | ||
582 | 89 | text: i18n.tr("To-do") | ||
583 | 90 | onTriggered:; // FIXME | ||
584 | 91 | } | ||
585 | 92 | Action { | ||
586 | 93 | iconSource: Qt.resolvedUrl("avatar.png") | ||
587 | 94 | text: i18n.tr("New Event") | ||
588 | 95 | onTriggered:; // FIXME | ||
589 | 96 | } | ||
590 | 97 | Action { | ||
591 | 98 | iconSource: Qt.resolvedUrl("avatar.png") | ||
592 | 99 | text: i18n.tr("Timeline") | ||
593 | 100 | onTriggered:; // FIXME | ||
594 | 70 | } | 101 | } |
595 | 71 | } | 102 | } |
596 | 72 | } | 103 | } |
597 | 73 | 104 | ||
598 | === added file 'colorUtils.js' | |||
599 | --- colorUtils.js 1970-01-01 00:00:00 +0000 | |||
600 | +++ colorUtils.js 2013-03-11 18:20:26 +0000 | |||
601 | @@ -0,0 +1,10 @@ | |||
602 | 1 | .pragma library | ||
603 | 2 | |||
604 | 3 | // colors for custom widgets | ||
605 | 4 | // see: http://design.ubuntu.com/brand/colour-palette | ||
606 | 5 | |||
607 | 6 | var ubuntuOrange = "#DD4814" | ||
608 | 7 | var canonicalAubergine = "#772953" | ||
609 | 8 | var lightAubergine = "#77216F" | ||
610 | 9 | var warmGrey = "#AEA79F" | ||
611 | 10 | var coolGrey = "#333333" | ||
612 | 0 | 11 | ||
613 | === added file 'testrun.sh' | |||
614 | --- testrun.sh 1970-01-01 00:00:00 +0000 | |||
615 | +++ testrun.sh 2013-03-11 18:20:26 +0000 | |||
616 | @@ -0,0 +1,4 @@ | |||
617 | 1 | #! /bin/bash -ex | ||
618 | 2 | |||
619 | 3 | rsync -aHv ./ phablet@nexus:/tmp/Calendar/ | ||
620 | 4 | ssh -t phablet@nexus 'cd /tmp/Calendar && GRID_UNIT_PX=18 qmlscene --desktop_file_hint=$PWD/Calendar.desktop $PWD/calendar.qml' |
PASSED: Continuous integration, rev:23 91.189. 93.125: 8080/job/ ubuntu- calendar- app-ci/ 5/ 91.189. 93.125: 8080/job/ ubuntu- calendar- app-ci/ ./build= pbuilder, distribution= quantal, flavor= amd64/5/ console
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.125: 8080/job/ ubuntu- calendar- app-ci/ 5//rebuild/?
http://