Merge lp:~pkunal-parmar/ubuntu-calendar-app/Refactoring into lp:ubuntu-calendar-app

Proposed by Kunal Parmar
Status: Merged
Approved by: Olivier Tilloy
Approved revision: no longer in the source branch.
Merged at revision: 44
Proposed branch: lp:~pkunal-parmar/ubuntu-calendar-app/Refactoring
Merge into: lp:ubuntu-calendar-app
Diff against target: 811 lines (+325/-360)
7 files modified
DiaryView.qml (+34/-75)
DiaryViewDelegate.qml (+4/-6)
EventView.qml (+12/-11)
EventViewBase.qml (+70/-0)
TimeLineView.qml (+191/-244)
TimeSeparator.qml (+7/-0)
calendar.qml (+7/-24)
To merge this branch: bzr merge lp:~pkunal-parmar/ubuntu-calendar-app/Refactoring
Reviewer Review Type Date Requested Status
Olivier Tilloy (community) Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+166263@code.launchpad.net

Commit message

Moved common code between DiaryView and TimeLineView to command EventViewBase QML.
Used state instead of property in EventViewBase

Description of the change

Moved common code between DiaryView and TimeLineView to command EventViewBase QML.
Used state instead of property in EventViewBase

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

761 - onExpand: {
762 + onExpand: {

767 - onCompress: {
768 + onCompress: {

The diff appends trailing whitespaces to those two lines, please revert the change.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

212 + property Flickable flickbleChild;

Typo: flickble

review: Needs Fixing
36. By Omer Akram

Initial autopilot structure.

Approved by Ubuntu Phone Apps Jenkins Bot, Olivier Tilloy.

37. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

Revision history for this message
Olivier Tilloy (osomon) wrote :

735 === added file 'TimeSeperator.qml'

Typo: the component should be name TimeSeparator.qml

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

742 + id: separator

this id is unused, you can remove it

Revision history for this message
Olivier Tilloy (osomon) wrote :

158 - id: seperator
161 + id: seperator

165 - anchors.horizontalCenter: parent.horizontalCenter
167 + anchors.horizontalCenter: parent.horizontalCenter

Trailing whitespaces have been added to those lines, please remove them.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

675 + var separator = separatorComponent.createObject(bubbleOverLay);

This could be simplified and made more efficient by removing the need for the Component instance:

    var x = …
    var y = …
    var properties = {"x": x, "y": y, "visible": true}
    var component = Qt.createComponent("TimeSeperator.qml")
    var separator = component.createObject(bubbleOverLay, properties)

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

> var properties = {"x": x, "y": y, "visible": true}

By the way, on an item visible is True by default, so this last property is useless, it can be removed.

Revision history for this message
Olivier Tilloy (osomon) wrote :

In EventView.qml, you should get rid of the expand() and compress() signals, and replace them by using the states only (use a Binding element to connect the state of the eventViewDelegate’s item to that of the eventView item).

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

To make the code more readable, instead of explicitly triggering state changes upon contentYChanged or draggingChanged, use the 'when' property of the states (http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-state.html#when-prop).

38. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

39. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> To make the code more readable, instead of explicitly triggering state changes
> upon contentYChanged or draggingChanged, use the 'when' property of the states
> (http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-state.html#when-prop).

I tried to use this, but failed, mostly I got "Binding loop detected for property "when"" error.
I am not sure how this "when" works, but we want expand() and compress() to be called on the first time when Dragging and ContentY changes. Not sure how that can be captured with "when".

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

I addressed your comments, but i was facing problem implementing your suggestion for removing explicit state changes on dragging and contentY change. It detects loop there.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
40. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

41. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

Revision history for this message
Olivier Tilloy (osomon) wrote :

192 + property string previousItemState: "COMPRESSED";

I’m not sure I understand what this property is for? If the goal is to ensure that all the delegates get the same state, then it’s not working. In that case, you’d need to define a 'delegateState' property on eventView, so that all delegates’ states are bound to it.

Revision history for this message
Olivier Tilloy (osomon) wrote :

> I addressed your comments, but i was facing problem implementing your
> suggestion for removing explicit state changes on dragging and contentY
> change. It detects loop there.

Could you share the code you were testing? Maybe I can lend a hand there.

Revision history for this message
Olivier Tilloy (osomon) wrote :

807 + onStateChanged: {
808 + if( state == "EXPANDED") {
809 + monthView.compressed = true
810 + yBehavior.enabled = true
811 + } else if( state == "COMPRESSED") {
812 + monthView.compressed = false
813 + }
814 }

Instead of the above, inside monthView, just set the value of 'compressed' to be (eventView.state == "EXPANDED"), and the same for the value of 'enabled' inside yBehavior.

review: Needs Fixing
42. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

43. By Launchpad Translations on behalf of ubuntu-calendar-dev

Launchpad automatic translations update.

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> 192 + property string previousItemState: "COMPRESSED";
>
> I’m not sure I understand what this property is for? If the goal is to ensure
> that all the delegates get the same state, then it’s not working. In that
> case, you’d need to define a 'delegateState' property on eventView, so that
> all delegates’ states are bound to it.

previousItemState property's intention was to preserve state, when going from DiaryView to TimeLineView.
But you are right, we also need to preserve state when we change day by scrolling, this I overlooked.

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> > 192 + property string previousItemState: "COMPRESSED";
> >
> > I’m not sure I understand what this property is for? If the goal is to
> ensure
> > that all the delegates get the same state, then it’s not working. In that
> > case, you’d need to define a 'delegateState' property on eventView, so that
> > all delegates’ states are bound to it.
>
> previousItemState property's intention was to preserve state, when going from
> DiaryView to TimeLineView.
> But you are right, we also need to preserve state when we change day by
> scrolling, this I overlooked.

This approach was not working, To resolve I put a reverse binding from EventView to Delegate so all delegate share the same state,
It also works when you change from DiaryView to TimeLineView.

        //share state from eventview to delegate, so that all delegate share the same state
        Binding{
            target: eventViewDelegate.item
            property: "state"
            value: eventView.state
        }

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

807 + onStateChanged: {
808 + monthView.compressed = (eventView.state == "EXPANDED");
809 }

As I was suggesting in a previous comment, this should be removed, and *inside* the MonthView instance, set the value of 'compressed':

    MonthView {
        […]
        compressed: eventView.state == "EXPANDED"
        […]
    }

review: Needs Fixing
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> > I addressed your comments, but i was facing problem implementing your
> > suggestion for removing explicit state changes on dragging and contentY
> > change. It detects loop there.
>
> Could you share the code you were testing? Maybe I can lend a hand there.

I tried to resolve the errors, but still could not achieve required behavior.
I pushed code here

 lp:~pkunal-parmar/ubuntu-calendar-app/JUNK

Please have a look, most code change is in EventViewBase

Revision history for this message
Olivier Tilloy (osomon) wrote :

> > > I addressed your comments, but i was facing problem implementing your
> > > suggestion for removing explicit state changes on dragging and contentY
> > > change. It detects loop there.
> >
> > Could you share the code you were testing? Maybe I can lend a hand there.
>
> I tried to resolve the errors, but still could not achieve required behavior.
> I pushed code here
>
> lp:~pkunal-parmar/ubuntu-calendar-app/JUNK
>
> Please have a look, most code change is in EventViewBase

Ok, let’s not delay merging this branch any longer, it’s already a good improvement over the current trunk.
I’m convinced we can improve further the handling of states (in particular, it looks to me like we can get rid of the "EXPANDING" and "COMPRESSING" states), but let’s do that in another iteration.

review: Approve
44. By Kunal Parmar

Moved common code between DiaryView and TimeLineView to command EventViewBase QML.
Used state instead of property in EventViewBase.

Approved by Olivier Tilloy, Ubuntu Phone Apps Jenkins Bot.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'DiaryView.qml'
--- DiaryView.qml 2013-05-17 02:11:27 +0000
+++ DiaryView.qml 2013-06-10 11:03:26 +0000
@@ -5,84 +5,43 @@
5import "dateExt.js" as DateExt5import "dateExt.js" as DateExt
6import "colorUtils.js" as Color6import "colorUtils.js" as Color
77
8ListView {8EventViewBase{
9 id: diaryView9 id: root
1010
11 property var dayStart: new Date()11 flickableChild: diaryView
1212
13 property bool expanded: false13 ListView {
1414 id: diaryView
15 property bool expanding: false15
16 property bool compressing: false16 model: root.eventModel
1717 anchors.fill: parent
18 signal expand()18
19 signal compress()19 section {
20 signal newEvent()20 property: "category"
2121 // labelPositioning: ViewSection.CurrentLabelAtStart // FIXME, unreliable
22 clip: true22 delegate: ListItem.Header {
2323 text: i18n.tr(section)
24 model: EventListModel {24 MouseArea {
25 id: eventModel25 anchors.fill: parent
26 termStart: dayStart26 onClicked: {
27 termLength: Date.msPerDay27 if (expanded)
28 }28 compress()
2929 else
30 section {30 expand()
31 property: "category"31 }
32 // labelPositioning: ViewSection.CurrentLabelAtStart // FIXME, unreliable
33 delegate: ListItem.Header {
34 text: i18n.tr(section)
35 MouseArea {
36 anchors.fill: parent
37 onClicked: {
38 if (expanded)
39 compress()
40 else
41 expand()
42 }32 }
43 }33 }
44 }34 }
45 }35
4636 delegate: DiaryViewDelegate{
47 delegate: DiaryViewDelegate{37 onClicked: {
48 onClicked: {38 pageStack.push(Qt.resolvedUrl("EventDetails.qml"),{event:diaryView.model.get(index)});
49 pageStack.push(Qt.resolvedUrl("EventDetails.qml"),{event:diaryView.model.get(index)});39 }
50 }40 }
51 }41
5242 footer: ListItem.Standard {
53 footer: ListItem.Standard {43 text: i18n.tr("(+) New Event")
54 text: i18n.tr("(+) New Event")44 onClicked: newEvent()
55 onClicked: newEvent()
56 }
57
58 onContentYChanged: {
59 // console.log(expanded, expanding, compressing, dragging, flicking, moving, contentY)
60 if (expanding || compressing || !dragging) return
61
62 if (expanded) {
63 if (contentY < -units.gu(0.5)) {
64 compressing = true
65 expanding = false
66 }
67 }
68 else {
69 if (contentY < -units.gu(0.5)) {
70 expanding = true
71 compressing = false
72 }
73 }
74 }
75
76 onDraggingChanged: {
77 if (dragging) return
78
79 if (expanding) {
80 expanding = false
81 expand()
82 }
83 else if (compressing) {
84 compressing = false
85 compress()
86 }45 }
87 }46 }
88}47}
8948
=== modified file 'DiaryViewDelegate.qml'
--- DiaryViewDelegate.qml 2013-04-21 07:52:56 +0000
+++ DiaryViewDelegate.qml 2013-06-10 11:03:26 +0000
@@ -21,14 +21,14 @@
21 function showEventData() {21 function showEventData() {
22 // FIXME: remove test value, need to decide what to do if there is no location, hide it ?22 // FIXME: remove test value, need to decide what to do if there is no location, hide it ?
23 var venues = [{"name":"Test Venue"}]23 var venues = [{"name":"Test Venue"}]
24 DataService.getVenues(eventModel.get(index), venues)24 DataService.getVenues(diaryView.model.get(index), venues)
25 if( venues.length > 0 ) {25 if( venues.length > 0 ) {
26 locationLabel.text = venues[0].name;26 locationLabel.text = venues[0].name;
27 }27 }
2828
29 // FIXME: remove test value, need to decide what to do if there are no attendees, hide it ?29 // FIXME: remove test value, need to decide what to do if there are no attendees, hide it ?
30 var attendees = ["Test One","Test Two"]30 var attendees = ["Test One","Test Two"]
31 DataService.getAttendees(eventModel.get(index),attendees)31 DataService.getAttendees(diaryView.model.get(index),attendees)
32 attendeeLabel.text = attendees.toString();32 attendeeLabel.text = attendees.toString();
33 }33 }
3434
@@ -36,7 +36,7 @@
36 collapse(true);36 collapse(true);
3737
38 var now = new Date;38 var now = new Date;
39 var lastEvent = eventModel.get(index-1);39 var lastEvent = diaryView.model.get(index-1);
4040
41 if( endTime >= now41 if( endTime >= now
42 && (lastEvent === undefined || lastEvent.endTime < now )42 && (lastEvent === undefined || lastEvent.endTime < now )
@@ -54,14 +54,12 @@
54 height: eventRoot.height + seperator.height + (seperator.visible ? units.gu(1.5) : units.gu(0.5)) /*margins*/54 height: eventRoot.height + seperator.height + (seperator.visible ? units.gu(1.5) : units.gu(0.5)) /*margins*/
55 width: parent.width55 width: parent.width
5656
57 Rectangle {57 TimeSeparator {
58 id: seperator58 id: seperator
59 height: units.gu(0.5)
60 width: delegateRoot.width - units.gu(2)59 width: delegateRoot.width - units.gu(2)
61 anchors.top: parent.top60 anchors.top: parent.top
62 anchors.topMargin: units.gu(1)61 anchors.topMargin: units.gu(1)
63 anchors.horizontalCenter: parent.horizontalCenter62 anchors.horizontalCenter: parent.horizontalCenter
64 color: "#c94212"
65 visible: false63 visible: false
66 }64 }
6765
6866
=== modified file 'EventView.qml'
--- EventView.qml 2013-05-18 02:16:07 +0000
+++ EventView.qml 2013-06-10 11:03:26 +0000
@@ -11,14 +11,8 @@
11 signal incrementCurrentDay11 signal incrementCurrentDay
12 signal decrementCurrentDay12 signal decrementCurrentDay
1313
14 property bool expanded: false
15
16 signal compress()
17 signal expand()
18 signal newEvent()14 signal newEvent()
1915
20 readonly property real visibleHeight: parent.height - y
21
22 QtObject {16 QtObject {
23 id: intern17 id: intern
24 property int currentIndexSaved: 018 property int currentIndexSaved: 0
@@ -74,8 +68,6 @@
74 }68 }
7569
76 onLoaded: {70 onLoaded: {
77 item.expand.connect(eventView.expand);
78 item.compress.connect(eventView.compress);
79 item.newEvent.connect(eventView.newEvent);71 item.newEvent.connect(eventView.newEvent);
80 }72 }
8173
@@ -85,10 +77,19 @@
85 value: eventViewDelegate.dayStart77 value: eventViewDelegate.dayStart
86 }78 }
8779
80 //share state from delegate to eventView, if state change is from current delegate
88 Binding {81 Binding {
89 target: item82 target: eventView
90 property: "expanded"83 property: "state"
91 value: eventView.expanded84 value: eventViewDelegate.item.state;
85 when: index == eventView.currentIndex
86 }
87
88 //share state from eventview to delegate, so that all delegate share the same state
89 Binding{
90 target: eventViewDelegate.item
91 property: "state"
92 value: eventView.state
92 }93 }
93 }94 }
94}95}
9596
=== added file 'EventViewBase.qml'
--- EventViewBase.qml 1970-01-01 00:00:00 +0000
+++ EventViewBase.qml 2013-06-10 11:03:26 +0000
@@ -0,0 +1,70 @@
1import QtQuick 2.0
2import Ubuntu.Components 0.1
3
4import "dateExt.js" as DateExt
5import "colorUtils.js" as Color
6
7Item {
8 id: baseView
9
10 property var dayStart: new Date()
11 property alias eventModel: model;
12 property Flickable flickableChild;
13
14 state: "COMPRESSED"
15
16 signal newEvent()
17 signal modelRefreshed();
18
19 clip: true
20
21 EventListModel {
22 id: model
23 termStart: dayStart
24 termLength: Date.msPerDay
25
26 onReload: {
27 modelRefreshed();
28 }
29 }
30
31 Connections{
32 target: flickableChild
33
34 onContentYChanged: {
35 if (state == "COMPRESSING" || state == "EXPANDING" || !flickableChild.dragging ) return
36
37 if ( state == "EXPANDED" && flickableChild.contentY < -units.gu(0.5) ) {
38 state = "COMPRESSING";
39 }
40 else if (flickableChild.contentY < -units.gu(0.5)) {
41 state = "EXPANDING";
42 }
43 }
44
45 onDraggingChanged: {
46 if (flickableChild.dragging) return;
47
48 if( state == "EXPANDING" ) {
49 state = "EXPANDED";
50 } else if ( state == "COMPRESSING") {
51 state = "COMPRESSED";
52 }
53 }
54 }
55
56 states: [
57 State {
58 name: "EXPANDING"
59 },
60 State {
61 name: "COMPRESSING"
62 },
63 State {
64 name: "EXPANDED"
65 },
66 State {
67 name: "COMPRESSED"
68 }
69 ]
70}
071
=== modified file 'TimeLineView.qml'
--- TimeLineView.qml 2013-05-23 14:02:01 +0000
+++ TimeLineView.qml 2013-06-10 11:03:26 +0000
@@ -4,256 +4,203 @@
4import "dateExt.js" as DateExt4import "dateExt.js" as DateExt
5import "dataService.js" as DataService5import "dataService.js" as DataService
66
77EventViewBase{
8Flickable{8 id: root
9 id: timeLineView9
1010 flickableChild: timeLineView
11 property var dayStart : new Date();11
1212 onModelRefreshed: {
13 property bool expanded: false13 timeLineView.createEvents();
14 property bool expanding: false14 }
15 property bool compressing: false15
1616 Flickable{
17 signal expand()17 id: timeLineView
18 signal compress()18 anchors.fill: parent
19 signal newEvent()19
2020 function scroll() {
21 function scroll() {21 //scroll to first event or current hour
22 //scroll to first event or current hour22 var hour = intern.now.getHours();
23 var hour = intern.now.getHours();23 if( eventModel.count > 0) {
24 if(eventListModel.count > 0) {24 hour = eventModel.get(0).startTime.getHours();
25 hour = eventListModel.get(0).startTime.getHours();25 }
26 }26
2727 timeLineView.contentY = hour * intern.hourHeight;
28 timeLineView.contentY = hour * units.gu(10);28
2929 if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) {
30 if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) {30 timeLineView.contentY = timeLineView.contentHeight - timeLineView.height
31 timeLineView.contentY = timeLineView.contentHeight - timeLineView.height31 }
32 }32 }
33 }33
3434 function createEventMap() {
35 function createEventMap() {35 var eventMap = {};
36 var eventMap = {};36 for(var i = 0 ; i < eventModel.count ; ++i) {
37 for(var i = 0 ; i < eventListModel.count ; ++i) {37 var event = eventModel.get(i);
38 var event = eventListModel.get(i);38 eventMap[event.startTime.getHours()] = event
39 eventMap[event.startTime.getHours()] = event39 }
40 }40 return eventMap;
41 return eventMap;41 }
42 }42
4343 function createEvents() {
44 function createEvents() {44 intern.eventMap = createEventMap();
45 intern.eventMap = createEventMap();45
4646 bubbleOverLay.destroyAllChildren();
47 bubbleOverLay.destroyAllChildren();47
4848 for( var i=0; i < 24; ++i ) {
49 for( var i=0; i < 24; ++i ) {49 var event = intern.eventMap[i];
50 var event = intern.eventMap[i];50 if( event ) {
51 if( event ) {51 bubbleOverLay.createEvent(event,i);
52 bubbleOverLay.createEvent(event,i);52 } else if( i === intern.now.getHours()
53 } else if( i === intern.now.getHours()53 && intern.now.isSameDay( root.dayStart )) {
54 && intern.now.isSameDay( timeLineView.dayStart )) {54 bubbleOverLay.createSeparator(i);
55 bubbleOverLay.createSeparator(i);55 }
56 }56 }
57 }57
5858 scroll();
59 scroll();59 }
60 }60
6161 function showEventDetails(hour) {
62 function showEventDetails(hour) {62 var event = intern.eventMap[hour];
63 var event = intern.eventMap[hour];63 pageStack.push(Qt.resolvedUrl("EventDetails.qml"),{"event":event});
64 pageStack.push(Qt.resolvedUrl("EventDetails.qml"),{"event":event});64 }
65 }65
6666 contentHeight: timeLineColumn.height + units.gu(3)
67 onContentYChanged: {67 contentWidth: width
68 // console.log(expanded, expanding, compressing, dragging, flicking, moving, contentY)68
69 if (expanding || compressing || !dragging) return69 QtObject {
7070 id: intern
71 if (expanded) {71 property var eventMap;
72 if (contentY < -units.gu(0.5)) {72 property var now : new Date();
73 compressing = true73 property var hourHeight : units.gu(10)
74 expanding = false74 }
75 }75
76 }76 Rectangle{
77 else {77 id: background; anchors.fill: parent
78 if (contentY < -units.gu(0.5)) {78 color: "white"
79 expanding = true79 }
80 compressing = false80
81 }81 //Time line view
82 }82 Column{
83 }83 id: timeLineColumn
8484 anchors.top: parent.top
85 onDraggingChanged: {85 anchors.topMargin: units.gu(3)
86 if (dragging) return86 width: parent.width
8787
88 if (expanding) {88 Repeater{
89 expanding = false89 model: 24 // hour in a day
90 expand()90
91 }91 delegate: Item {
92 else if (compressing) {92 id: delegate
93 compressing = false
94 compress()
95 }
96 }
97
98 clip: true
99
100 contentHeight: timeLineColumn.height + units.gu(3)
101 contentWidth: width
102
103 QtObject {
104 id: intern
105 property var eventMap;
106 property var now : new Date();
107 property var hourHeight : units.gu(10)
108 }
109
110 EventListModel {
111 id: eventListModel
112 termStart: timeLineView.dayStart
113 termLength: Date.msPerDay
114
115 onReload: {
116 createEvents();
117 }
118 }
119
120 Rectangle{
121 id: background; anchors.fill: parent
122 color: "white"
123 }
124
125 //Time line view
126 Column{
127 id: timeLineColumn
128 anchors.top: parent.top
129 anchors.topMargin: units.gu(3)
130 width: parent.width
131
132 Repeater{
133 model: 24 // hour in a day
134
135 delegate: Item {
136 id: delegate
137 width: parent.width
138 height: intern.hourHeight
139
140 Row {
141 width: parent.width93 width: parent.width
142 y: -timeLabel.height/294 height: intern.hourHeight
143 Label{95
144 id: timeLabel96 Row {
145 // TRANSLATORS: this is a time formatting string,97 width: parent.width
146 // see http://qt-project.org/doc/qt-5.0/qtqml/qml-qtquick2-date.html#details for valid expressions98 y: -timeLabel.height/2
147 text: new Date(0, 0, 0, index).toLocaleTimeString(Qt.locale(), i18n.tr("HH:mm"))99 Label{
148 color:"gray"100 id: timeLabel
149 anchors.top: parent.top101 // TRANSLATORS: this is a time formatting string,
102 // see http://qt-project.org/doc/qt-5.0/qtqml/qml-qtquick2-date.html#details for valid expressions
103 text: new Date(0, 0, 0, index).toLocaleTimeString(Qt.locale(), i18n.tr("HH:mm"))
104 color:"gray"
105 anchors.top: parent.top
106 }
107 Rectangle{
108 width: parent.width -timeLabel.width
109 height:units.dp(1)
110 color:"gray"
111 anchors.verticalCenter: parent.verticalCenter
112 }
150 }113 }
114
151 Rectangle{115 Rectangle{
152 width: parent.width -timeLabel.width116 width: parent.width - units.gu(5)
153 height:units.dp(1)117 height:units.dp(1)
154 color:"gray"118 color:"gray"
155 anchors.verticalCenter: parent.verticalCenter119 anchors.verticalCenter: parent.verticalCenter
156 }120 anchors.horizontalCenter: parent.horizontalCenter
157 }121 }
158122 }
159 Rectangle{123 }
160 width: parent.width - units.gu(5)124 }
161 height:units.dp(1)125
162 color:"gray"126 Item {
163 anchors.verticalCenter: parent.verticalCenter127 id: bubbleOverLay
164 anchors.horizontalCenter: parent.horizontalCenter128
165 }129 width: timeLineColumn.width
166 }130 height: timeLineColumn.height
167 }131 anchors.top: parent.top
168 }132 anchors.topMargin: units.gu(3)
169133
170 Item {134 function destroyAllChildren() {
171 id: bubbleOverLay135 for( var i = children.length - 1; i >= 0; --i ) {
172136 children[i].destroy();
173 width: timeLineColumn.width137 }
174 height: timeLineColumn.height138 }
175 anchors.top: parent.top139
176 anchors.topMargin: units.gu(3)140 function createEvent( event ,hour) {
177141 var eventBubble = infoBubbleComponent.createObject(bubbleOverLay);
178 function destroyAllChildren() {142 eventBubble.title = event.title;
179 for( var i = children.length - 1; i >= 0; --i ) {143 eventBubble.location = "test";
180 children[i].destroy();144 eventBubble.hour = hour;
181 }145
182 }146 var yPos = (( event.startTime.getMinutes() * intern.hourHeight) / 60) + hour * intern.hourHeight
183147 eventBubble.y = yPos;
184 function createEvent( event ,hour) {148
185 var eventBubble = infoBubbleComponent.createObject(bubbleOverLay);149 var durationMin = (event.endTime.getHours() - event.startTime.getHours()) * 60;
186 eventBubble.title = event.title;150 durationMin += (event.endTime.getMinutes() - event.startTime.getMinutes());
187 eventBubble.location = "test";151 var height = (durationMin * intern.hourHeight )/ 60;
188 eventBubble.hour = hour;152 eventBubble.height = height;
189153 }
190 var yPos = (( event.startTime.getMinutes() * intern.hourHeight) / 60) + hour * intern.hourHeight154
191 eventBubble.y = yPos;155 function createSeparator(hour) {
192156 var w = timeLineView.width - units.gu(2);
193 var durationMin = (event.endTime.getHours() - event.startTime.getHours()) * 60;157 var y = ((intern.now.getMinutes() * intern.hourHeight) / 60) + hour * intern.hourHeight;
194 durationMin += (event.endTime.getMinutes() - event.startTime.getMinutes());158 var x = (parent.width - w)/ 2;
195 var height = (durationMin * intern.hourHeight )/ 60;159 var properties = {"x": x, "y": y, "width": w}
196 eventBubble.height = height;160
197 }161 var component = Qt.createComponent("TimeSeparator.qml");
198162 var separator = component.createObject(bubbleOverLay, properties);
199 function createSeparator(hour) {163 }
200 var separator = separatorComponent.createObject(bubbleOverLay);164 }
201 var yPos = ((intern.now.getMinutes() * intern.hourHeight) / 60) + hour * intern.hourHeight165
202 separator.visible = true;166 Component{
203 separator.y = yPos;167 id: infoBubbleComponent
204 separator.x = (parent.width - separator.width)/2168 Rectangle{
205 }169 id: infoBubble
206 }170
207171 property string title;
208 Component{172 property string location;
209 id: infoBubbleComponent173 property int hour;
210 Rectangle{174
211 id: infoBubble175 color:'#fffdaa';
212176 width: timeLineView.width - units.gu(8)
213 property string title;177 x: units.gu(5)
214 property string location;178
215 property int hour;179 border.color: "#f4d690"
216180
217 color:'#fffdaa';181 Column{
218 width: timeLineView.width - units.gu(8)182 id: column
219 x: units.gu(5)183 anchors {
220184 left: parent.left
221 border.color: "#f4d690"185 right: parent.right
222186 top: parent.top
223 Column{187
224 id: column188 leftMargin: units.gu(1)
225 anchors {189 rightMargin: units.gu(1)
226 left: parent.left190 topMargin: units.gu(1)
227 right: parent.right191 }
228 top: parent.top192 spacing: units.gu(1)
229193 Label{text:infoBubble.title;fontSize:"medium";color:"black"}
230 leftMargin: units.gu(1)194 Label{text:infoBubble.location; fontSize:"small"; color:"black"}
231 rightMargin: units.gu(1)195 }
232 topMargin: units.gu(1)196
233 }197 MouseArea{
234 spacing: units.gu(1)198 anchors.fill: parent
235 Label{text:infoBubble.title;fontSize:"medium";color:"black"}199 onClicked: {
236 Label{text:infoBubble.location; fontSize:"small"; color:"black"}200 timeLineView.showEventDetails(hour);
237 }201 }
238202 }
239 MouseArea{203 }
240 anchors.fill: parent
241 onClicked: {
242 timeLineView.showEventDetails(hour);
243 }
244 }
245 }
246 }
247
248 Component {
249 id: separatorComponent
250 Rectangle {
251 id: separator
252 height: units.gu(0.5)
253 width: timeLineView.width - units.gu(2)
254 color: "#c94212"
255 visible: false
256 }204 }
257 }205 }
258}206}
259
260207
=== added file 'TimeSeparator.qml'
--- TimeSeparator.qml 1970-01-01 00:00:00 +0000
+++ TimeSeparator.qml 2013-06-10 11:03:26 +0000
@@ -0,0 +1,7 @@
1import QtQuick 2.0
2
3Rectangle {
4 id: separator
5 height: units.gu(0.5)
6 color: "#c94212"
7}
08
=== modified file 'calendar.qml'
--- calendar.qml 2013-05-23 12:31:50 +0000
+++ calendar.qml 2013-06-10 11:03:26 +0000
@@ -81,42 +81,25 @@
81 //y: units.gu(9.5) // FIXME81 //y: units.gu(9.5) // FIXME
82 onMovementEnded: eventView.currentDayStart = currentDayStart82 onMovementEnded: eventView.currentDayStart = currentDayStart
83 onCurrentDayStartChanged: if (!(dragging || flicking)) eventView.currentDayStart = currentDayStart83 onCurrentDayStartChanged: if (!(dragging || flicking)) eventView.currentDayStart = currentDayStart
84 Component.onCompleted: eventView.currentDayStart = currentDayStart 84 Component.onCompleted: eventView.currentDayStart = currentDayStart
85 compressed: (eventView.state == "EXPANDED")
86 Behavior on height {
87 NumberAnimation { duration: 100 }
88 }
85 }89 }
8690
87 EventView {91 EventView {
88 id: eventView92 id: eventView
8993
90 property real minY: monthView.y + monthView.compressedHeight94 height: parent.height - monthView.height
91 property real maxY: monthView.y + monthView.expandedHeight
92
93 y: maxY
94 width: mainView.width95 width: mainView.width
95 height: parent.height - y96 anchors.top: monthView.bottom
96
97 expanded: monthView.compressed
9897
99 Component.onCompleted: {98 Component.onCompleted: {
100 incrementCurrentDay.connect(monthView.incrementCurrentDay)99 incrementCurrentDay.connect(monthView.incrementCurrentDay)
101 decrementCurrentDay.connect(monthView.decrementCurrentDay)100 decrementCurrentDay.connect(monthView.decrementCurrentDay)
102 }101 }
103102
104 onExpand: {
105 monthView.compressed = true
106 yBehavior.enabled = true
107 y = minY
108 }
109 onCompress: {
110 monthView.compressed = false
111 y = maxY
112 }
113
114 Behavior on y {
115 id: yBehavior
116 enabled: false
117 NumberAnimation { duration: 100 }
118 }
119
120 onNewEvent: monthViewPage.newEvent()103 onNewEvent: monthViewPage.newEvent()
121 }104 }
122105

Subscribers

People subscribed via source and target branches

to status/vote changes: