Merge lp:~renatofilho/quick-memo/fix-item-focus into lp:quick-memo/trunk

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Stefano Verzegnassi
Approved revision: 57
Merged at revision: 57
Proposed branch: lp:~renatofilho/quick-memo/fix-item-focus
Merge into: lp:quick-memo/trunk
Diff against target: 189 lines (+87/-30)
2 files modified
app/components/ListManager.qml (+77/-18)
app/components/NoteTextField.qml (+10/-12)
To merge this branch: bzr merge lp:~renatofilho/quick-memo/fix-item-focus
Reviewer Review Type Date Requested Status
Stefano Verzegnassi Approve
Bill Filler (community) Approve
Review via email: mp+245761@code.launchpad.net

Commit message

Fixed note items navigation and focus.

Description of the change

OBS: The keyboard "Enter" label still broken due a bug on ubuntu-keyboard, you will need this MR to get this fully working: https://code.launchpad.net/~renatofilho/ubuntu-keyboard/fix-qml-inputMethod-extensions/+merge/245775

To post a comment you must log in.
57. By Renato Araujo Oliveira Filho

Fixed note itens navigation and focus.

Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

Hi Renato,

Thanks for reporting this issue and submitting a patch.
During these days I'm studying for some exams, so I don't have much time to spend with source code.

I'm working on the "reboot" branch for Quick Memo, using a new database (in order to solve some issue with U1DB) and refactoring some parts of code that don't look so good ("Details" page is one of those "parts").

I just took a look at the diff and the code looks good to me. I just need some time to make a deeper review of the code and integrate it in the "reboot" branch (which, I hope, should be "almost" ready to be receive MPs during the next weekend).

Thank you again! :)
Stefano

Revision history for this message
Bill Filler (bfiller) wrote :

I tested this and it works well with ubuntu-keyboard in silo 19

review: Approve
Revision history for this message
Bill Filler (bfiller) wrote :

Stefano,
Wondering if you had plans to release a new version before the reboot branch? If so would be great to get this merged and released prior to the reboot branch as these changes really help usability alot. I use the app all the time (it's awesome!) and these make it even better.

Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

Bill,
Sorry for the late replay, I didn't get any notification by email about your comment.
I had no plan about an "intermediate" release, but I can definitely do it.
Just need some time to fix some issue with in-app notifications (hopefully it should be done during this week).

Renato,
Thank you very much for this contribution! It's really a great improvement! :D

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'app/components/ListManager.qml'
--- app/components/ListManager.qml 2014-11-03 00:21:23 +0000
+++ app/components/ListManager.qml 2015-01-07 18:28:07 +0000
@@ -29,8 +29,8 @@
29 property Flickable flickable29 property Flickable flickable
30 property alias model: repeater.model30 property alias model: repeater.model
31 property alias delegate: repeater.delegate31 property alias delegate: repeater.delegate
32
33 property alias footer: footerLoader.sourceComponent32 property alias footer: footerLoader.sourceComponent
33 readonly property bool focusOnLastItem: (model.focusedIndex === -1) || (model.focusedIndex === (model.count - 1))
3434
35 signal listChanged()35 signal listChanged()
3636
@@ -44,6 +44,8 @@
4444
45 model: ListModel {45 model: ListModel {
46 id: dataModel46 id: dataModel
47
48 property int focusedIndex: -1
47 }49 }
4850
49 delegate: delegate51 delegate: delegate
@@ -99,7 +101,7 @@
99 }101 }
100102
101 onClicked: {103 onClicked: {
102 rootItem.model.append({"checked": false, "text": ""})104 rootItem.addItem({"checked": false, "text": ""})
103 // Here we don't send listChanged signal, since it is an empty item that should not be saved105 // Here we don't send listChanged signal, since it is an empty item that should not be saved
104 }106 }
105 }107 }
@@ -120,6 +122,64 @@
120 return list122 return list
121 }123 }
122124
125 function addItem(args) {
126 rootItem.model.append(args)
127 var newItem = repeater.itemAt(repeater.count - 1)
128 newItem.textArea.forceActiveFocus()
129 autoScrollAnimation.makeMeVisible(newItem)
130 }
131
132 SequentialAnimation {
133 id: autoScrollAnimation
134
135 property var targetItem: null
136 alwaysRunToEnd: true
137
138 // wait item be moved to correct place
139 PauseAnimation {
140 duration: 100
141 }
142 // scroll to new item position
143 ScriptAction {
144 script: {
145 if (autoScrollAnimation.targetItem) {
146 autoScrollAnimation.makeMeVisibleImpl(autoScrollAnimation.targetItem)
147 autoScrollAnimation.targetItem = null
148 }
149 }
150 }
151
152 function makeMeVisible(newItem) {
153 autoScrollAnimation.targetItem = newItem
154 autoScrollAnimation.restart()
155 }
156
157 function makeMeVisibleImpl(newItem) {
158 if (!newItem) {
159 return
160 }
161
162 var positionY = rootItem.y + repeater.y + newItem.y
163
164 // check if the item is already visible
165 var bottomY = flickable.contentY + flickable.height
166 var itemBottom = positionY + (newItem.height *3) // margin
167 if (positionY >= flickable.contentY && itemBottom <= bottomY) {
168 return;
169 }
170
171 // if it is not, try to scroll and make it visible
172 var targetY = itemBottom - flickable.height
173 if (targetY >= 0 && positionY) {
174 flickable.contentY = targetY
175 } else if (positionY < flickable.contentY) {
176 // if it is hidden at the top, also show it
177 flickable.contentY = positionY
178 }
179 flickable.returnToBounds()
180 }
181 }
182
123183
124 // *** DELEGATE ***184 // *** DELEGATE ***
125 Component {185 Component {
@@ -197,17 +257,14 @@
197257
198 NoteTextField {258 NoteTextField {
199 id: textArea259 id: textArea
260
200 width: parent.width - (checkBox.width + (parent.spacing * 2))261 width: parent.width - (checkBox.width + (parent.spacing * 2))
201 anchors.verticalCenter: parent.verticalCenter262 anchors.verticalCenter: parent.verticalCenter
202263
203 font.strikeout: checkBox.checked264 font.strikeout: checkBox.checked
204265
205 __inverseMouseArea.parent: item266 onFocusReceived: {
206 onFocusLost: {267 rootItem.model.focusedIndex = model.index
207 if (rootItem.flickable)
208 rootItem.flickable.forceActiveFocus()
209 else
210 rootItem.forceActiveFocus()
211 }268 }
212269
213 text: model.text270 text: model.text
@@ -222,23 +279,25 @@
222 }279 }
223280
224 //hasClearButton: false281 //hasClearButton: false
225 focus: false282 focus: true
226283
227 // Ubuntu Keyboard284 // Ubuntu Keyboard
285 // TODO: Disable Enter key if model.text is empty.
228 InputMethod.extensions: {286 InputMethod.extensions: {
229 "enterKeyText": (model.index < (rootItem.model.count - 1)) ? i18n.tr("Next") : i18n.tr("Add")287 "enterKeyText": rootItem.focusOnLastItem ? i18n.tr("Add") : i18n.tr("Next")
230 // TODO: Disable Enter key if model.text is empty.
231 }288 }
289
232 Keys.onReturnPressed: {290 Keys.onReturnPressed: {
233 if ((model.index === (rootItem.model.count - 1)) && model.text !== "") {291 if (rootItem.focusOnLastItem && (model.text !== "")) {
234 // Create a new item.292 // Create a new item.
235 rootItem.model.append({"checked": false, "text": ""})293 rootItem.addItem({"checked": false, "text": ""})
294 } else if (!rootItem.focusOnLastItem) {
295 var nextItem = repeater.itemAt(model.index + 1)
296 if (nextItem) {
297 nextItem.textArea.forceActiveFocus()
298 autoScrollAnimation.makeMeVisible(nextItem)
299 }
236 }300 }
237 repeater.itemAt(model.index + 1).textArea.forceActiveFocus()
238
239 // Focused textArea should be always visible. Move the Flickable as needed.
240 flickable.contentY = rootItem.y + repeater.itemAt(model.index + 1).y
241 flickable.returnToBounds()
242 }301 }
243 }302 }
244303
245304
=== modified file 'app/components/NoteTextField.qml'
--- app/components/NoteTextField.qml 2014-10-04 01:24:43 +0000
+++ app/components/NoteTextField.qml 2015-01-07 18:28:07 +0000
@@ -35,21 +35,19 @@
35 // Prevent data loss35 // Prevent data loss
36 inputMethodHints: Qt.ImhNoPredictiveText36 inputMethodHints: Qt.ImhNoPredictiveText
3737
38 property alias __inverseMouseArea: inverseMouseArea38 signal focusLost()
39 signal focusLost() 39 signal focusReceived()
40
41 onActiveFocusChanged: {
42 if (activeFocus) {
43 focusReceived()
44 } else {
45 focusLost()
46 }
47 }
4048
41 style: TextFieldStyle {49 style: TextFieldStyle {
42 frameSpacing: 050 frameSpacing: 0
43 background: Item { anchors.fill: parent }51 background: Item { anchors.fill: parent }
44 }52 }
45
46 InverseMouseArea {
47 id: inverseMouseArea
48 enabled: textArea.activeFocus
49 anchors.fill: parent
50 onClicked: {
51 textArea.focusLost()
52 mouse.accepted = false
53 }
54 }
55}53}

Subscribers

People subscribed via source and target branches