Update UI only when event is the last one triggered by UI

This commit is contained in:
Renaud Casenave-Péré 2022-12-19 22:54:16 +01:00
parent 2f4a641874
commit 9164c1a3c3
5 changed files with 98 additions and 77 deletions

View file

@ -94,63 +94,78 @@
(refresh-data index))
new-node))
(defun do-modify-text (index new-text)
(let ((node (goto-index index)))
(setf (raw-text-of node) new-text)
(defun do-modify-text (index new-text update-ui)
(setf (raw-text-of (goto-index index)) new-text)
(when update-ui
(reparse-node index)))
(defun do-join-node (command)
(defun do-join-node (command update-ui)
(let* ((node (goto-index (index-of command)))
(next (next-of node))
(next-next (next-of next)))
(setf (raw-text-of node) (concatenate 'string (previous-text-of command) (next-text-of command))
(line-ending-of node) (next-eol-of command))
(removing-rows ((1+ (index-of command)))
(setf (next-of node) next-next)
(when next-next
(setf (previous-of next-next) node)))
(reparse-node (index-of command) (eq (type-of next) 'org-headline))))
(flet ((relink-nodes (n nn)
(setf (next-of n) nn)
(when nn (setf (previous-of nn) n))))
(if update-ui
(progn
(removing-rows ((1+ (index-of command)))
(relink-nodes node next-next)
(dec-nodes-count))
(reparse-node (index-of command) (eq (type-of next) 'org-headline)))
(progn
(relink-nodes node next-next)
(dec-nodes-count))))))
(defun do-split-node (command)
(defun do-split-node (command update-ui)
(let* ((node (goto-index (index-of command)))
(next (next-of node))
(new-node (make-org-line (next-text-of command) (next-eol-of command))))
(inserting-rows ((1+ (index-of command)))
(setf (next-of node) new-node
(previous-of new-node) node)
(when next
(setf (previous-of next) new-node
(next-of new-node) next)))
(setf (raw-text-of node) (previous-text-of command)
(line-ending-of node) (previous-eol-of command))
(reparse-node (index-of command))
(reparse-node (1+ (index-of command)))))
(flet ((relink-nodes (n nn new)
(setf (next-of n) new
(previous-of new) n)
(when nn
(setf (previous-of nn) new
(next-of new) nn))))
(if update-ui
(progn
(inserting-rows ((1+ (index-of command)))
(relink-nodes node next new-node)
(inc-nodes-count))
(reparse-node (index-of command))
(reparse-node (1+ (index-of command))))
(progn
(relink-nodes node next new-node)
(inc-nodes-count))))))
(defgeneric apply-command (command))
(defgeneric apply-command (command update-ui))
(defmethod apply-command ((command command-modify-text))
(do-modify-text (index-of command) (after-text-of command)))
(defmethod apply-command ((command command-modify-text) update-ui)
(do-modify-text (index-of command) (after-text-of command) update-ui))
(defmethod apply-command ((command command-join-node))
(do-join-node command))
(defmethod apply-command ((command command-join-node) update-ui)
(do-join-node command update-ui))
(defmethod apply-command ((command command-split-node))
(do-split-node command))
(defmethod apply-command ((command command-split-node) update-ui)
(do-split-node command update-ui))
(defgeneric unapply-command (command))
(defgeneric unapply-command (command update-ui))
(defmethod unapply-command ((command command-modify-text))
(do-modify-text (index-of command) (before-text-of command)))
(defmethod unapply-command ((command command-modify-text) update-ui)
(do-modify-text (index-of command) (before-text-of command) update-ui))
(defmethod unapply-command ((command command-join-node))
(do-split-node command))
(defmethod unapply-command ((command command-join-node) update-ui)
(do-split-node command update-ui))
(defmethod unapply-command ((command command-split-node))
(do-join-node command))
(defmethod unapply-command ((command command-split-node) update-ui)
(do-join-node command update-ui))
@ -187,51 +202,54 @@
(defun push-command-modify-text (command index before-text after-text)
(defun push-command-modify-text (command index before-text after-text update-ui)
(let ((next-command (make-instance 'command-modify-text :previous command
:index index
:before-text before-text
:after-text after-text)))
(apply-command next-command)
(apply-command next-command update-ui)
(setf (next-of command) next-command)))
(defun push-command-join-node (command index previous-text previous-eol next-text next-eol)
(defun push-command-join-node (command index previous-text previous-eol next-text next-eol update-ui)
(let ((next-command (make-instance 'command-join-node :previous command
:index index
:previous-text previous-text
:previous-eol previous-eol
:next-text next-text
:next-eol next-eol)))
(apply-command next-command)
(apply-command next-command update-ui)
(setf (next-of command) next-command)))
(defun push-command-split-node (command index previous-text previous-eol next-text next-eol)
(defun push-command-split-node (command index previous-text previous-eol next-text next-eol update-ui)
(let ((next-command (make-instance 'command-split-node :previous command
:index index
:previous-text previous-text
:previous-eol previous-eol
:next-text next-text
:next-eol next-eol)))
(apply-command next-command)
(apply-command next-command update-ui)
(setf (next-of command) next-command)))
(defun modify-text (index text)
(defun modify-text (index text &optional update-ui)
(let ((node (goto-index index)))
(setf *current-state* (push-command-modify-text *current-state* index
(raw-text-of node) text))
(refresh-toolbar)))
(raw-text-of node) text update-ui))
(when update-ui
(refresh-toolbar))))
(defun join-node (index)
(defun join-node (index &optional update-ui)
(let* ((node (goto-index index))
(next (next-of node)))
(setf *current-state* (push-command-join-node *current-state* index
(raw-text-of node) (line-ending-of node)
(raw-text-of next) (line-ending-of next)))
(refresh-toolbar)))
(raw-text-of next) (line-ending-of next)
update-ui))
(when update-ui
(refresh-toolbar))))
(defun split-node (index previous-text next-text)
(defun split-node (index previous-text next-text &optional update-ui)
(let* ((node (goto-index index))
(next-eol (line-ending-of node))
(previous-eol (if (/= (length next-eol) 0)
@ -242,7 +260,9 @@
(coerce #(#\Newline) 'string))))))
(setf *current-state* (push-command-split-node *current-state* index
previous-text previous-eol
next-text next-eol))))
next-text next-eol update-ui)))
(when update-ui
(refresh-toolbar)))
@ -251,7 +271,7 @@
(unless (null previous-state)
(prog1
(index-of *current-state*)
(unapply-command *current-state*)
(unapply-command *current-state* t)
(setf *current-state* previous-state)
(refresh-toolbar)))))
@ -263,7 +283,7 @@
(unless (null next-state)
(prog1
(index-of next-state)
(apply-command next-state)
(apply-command next-state t)
(setf *current-state* next-state)
(refresh-toolbar)))))
@ -360,10 +380,10 @@
((> current-index saved-index)
(dotimes (i (- current-index saved-index))
(setf *current-state* (next-of *current-state*))
(apply-command *current-state*)))
(apply-command *current-state* nil)))
((< current-index saved-index)
(dotimes (i (- saved-index current-index))
(unapply-command *current-state*)
(unapply-command *current-state* nil)
(setf *current-state* (previous-of *current-state*)))))))))))))))))))
(defun save-commands (pathname)

View file

@ -3,6 +3,8 @@
:sextant/models/utils)
(:export #:current-pathname
#:org-document
#:inc-nodes-count
#:dec-nodes-count
#:replace-data
#:refresh-data
#:removing-rows
@ -39,6 +41,12 @@
(defun model-index (index)
(|index| *org-model* index))
(defun inc-nodes-count (&optional (count 1))
(incf *nodes-count* count))
(defun dec-nodes-count (&optional (count 1))
(decf *nodes-count* count))
(defun replace-data (node new-node)
@ -64,7 +72,6 @@
(|beginRemoveRows| sextant/models/org-model::*org-model*
sextant/models/org-model::*empty-model-index* ,start ,end)
,@body
(decf sextant/models/org-model::*nodes-count* (1+ (- ,end ,start)))
(|endRemoveRows| sextant/models/org-model::*org-model*))))
(defmacro inserting-rows ((start &optional (end start)) &body body)
@ -73,7 +80,6 @@
(|beginInsertRows| sextant/models/org-model::*org-model*
sextant/models/org-model::*empty-model-index* ,start ,end)
,@body
(incf sextant/models/org-model::*nodes-count* (1+ (- ,end ,start)))
(|endInsertRows| sextant/models/org-model::*org-model*))))

View file

@ -41,6 +41,6 @@ ListItem {
document.focusedIndex = index
}
function forceCommit () { loader.item.forceCommit() }
function forceCommit (update) { loader.item.forceCommit(update) }
function setCursorPositionAtEnd (fix) { loader.item.setCursorPositionAtEnd(fix) }
}

View file

@ -43,15 +43,15 @@ TextArea {
if (index >= 0) {
if (index > 0 && text[0] != sentinelChar) {
var textEmpty = text.length != 0
forceCommit()
forceCommit(false)
document.focusedIndex = index - 1
document.focusedItem.setCursorPositionAtEnd(textEmpty)
Lisp.call("models:join-node", index - 1)
Lisp.call("models:join-node", index - 1, true)
} else {
var split = text.indexOf("\n")
if (split != -1) {
forceCommit()
Lisp.call("models:split-node", index, text.substring(index > 0 ? 1 : 0, split), text.substring(split + 1))
forceCommit(false)
Lisp.call("models:split-node", index, text.substring(index > 0 ? 1 : 0, split), text.substring(split + 1), true)
document.focusedIndex = index + 1
} else {
lastText = getText()
@ -67,37 +67,32 @@ TextArea {
onActiveFocusChanged: {
if (!activeFocus) {
forceCommit()
if (document.focusedIndex == index)
document.focusedIndex = -1
forceCommit(true)
}
}
onVisibleChanged: {
if (visible) {
forceActiveFocus()
if (index > 0 && cursorPosition == 0)
cursorPosition = 1
}
}
Component.onCompleted: {
if (visible) {
forceActiveFocus()
if (index > 0 && cursorPosition == 0)
cursorPosition = 1
}
}
onVisibleChanged: initFocus()
Component.onCompleted: initFocus()
function getText () {
return index > 0 ? text.substring(1) : text
}
function forceCommit () {
function initFocus() {
if (visible) {
forceActiveFocus()
if (index > 0 && cursorPosition == 0)
cursorPosition = 1
}
}
function forceCommit (update) {
if (textModified) {
Lisp.call("models:modify-text", index, lastText)
textModified = false
Lisp.call("models:modify-text", index, lastText, update)
}
}

View file

@ -19,7 +19,7 @@ Item {
visible: editing
}
function forceCommit () { edit.forceCommit() }
function forceCommit (update) { edit.forceCommit(update) }
function setCursorPositionAt (x, y) { edit.setCursorPositionAt(x, y) }
function setCursorPositionAtEnd (fix) { edit.setCursorPositionAtEnd(fix) }
}