-
-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split widget callbacks into update and commit so only the latter adds a history state #1584
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this amazing editing improvement.
return; | ||
} | ||
|
||
responses.add(DocumentMessage::StartTransaction); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, i see. I missed this situation, maybe I need to do something like on_update callback
614f909
to
c32103c
Compare
|
I'll give this a detailed code review tomorrow, bedtime now though! Thanks @0HyperCube for the review so far. |
c32103c
to
fdea013
Compare
{/if} | ||
{@const colorInput = narrowWidgetProps(component.props, "ColorButton")} | ||
{#if colorInput} | ||
<ColorButton {...exclude(colorInput)} on:value={({ detail }) => updateLayout(index, detail)} /> | ||
<ColorButton {...exclude(colorInput)} on:value={({ detail }) => updateLayout(index, detail)} on:start={() => commitLayout(index)} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please help me understand why we are committing the layout upon the start of the user's dragging? Why doesn't this happen upon completion of the dragging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it also seems unreasonable to me first. After tried myself, I try to understand like this: for undo history, we always need to commit a undo history and keep a snapshot before we begin new changes. Then upon the start of dragging means commit a undo history before user begin new dragging changes(then we can properly rollback to this history).
Actually we commit the layout of a last status, not a layout changed by this widget. Maybe we could consider change a name of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But doesn't that mean that we don't save a history step upon completing the drag? So if you change a number from 1 to 10 by dragging its NumberInput slider, that value of 10 never gets saved as a history step? So the user could move on to other things, and if they undo several times, the history jumps back two operations at once (the operation that moved from 1 to 10, and whatever the other operation was adjacent to that).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But doesn't that mean that we don't save a history step upon completing the drag?
saving a history step upon completing the drag is a responsibility belongs to the next widget's commit_layout or next action that trigger Document.startTransaction
. That's also why common widgets use updateAndCommitLayout
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if you change a number from 1 to 10 by dragging its NumberInput slider, that value of 10 never gets saved as a history step?
e.g. if user's next action is to add a path using pen tool. During we adding a path, we will trigger Document.StartTransanction
then save a history step. (Our existing history related code have handled this properly I think)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see! I think part of my confusion is because I don't have a full understanding of how StartTransaction
/AbortTransaction
/CommitTransaction
work (since the original author of that never documented them). I did test this all out and it seems to work well so I trust that you're right about this. I'll keep going with my code review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CommitTransaction
is a noop. StartTransaction
clones the document and stores it in a list. AbortTransaction
pops a document from the list and makes it current.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's interesting that CommitTransaction
is a noop. Is there a reason we have it? Do you think we should we just remove it, then find more intuitive names for the remaining two?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your welcome to modify it.
let layout = if let Some(layout) = self.layouts.get_mut(layout_target as usize) { | ||
layout | ||
} else { | ||
warn!("CommitLayout was called referencing an invalid layout. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",); | ||
return; | ||
}; | ||
|
||
let widget_holder = if let Some(widget_holder) = layout.iter_mut().find(|widget| widget.widget_id == widget_id) { | ||
widget_holder | ||
} else { | ||
warn!("CommitLayout was called referencing an invalid widget ID, although the layout target was valid. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",); | ||
return; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can be simplified with let else
syntax.
let layout = if let Some(layout) = self.layouts.get_mut(layout_target as usize) { | |
layout | |
} else { | |
warn!("CommitLayout was called referencing an invalid layout. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",); | |
return; | |
}; | |
let widget_holder = if let Some(widget_holder) = layout.iter_mut().find(|widget| widget.widget_id == widget_id) { | |
widget_holder | |
} else { | |
warn!("CommitLayout was called referencing an invalid widget ID, although the layout target was valid. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",); | |
return; | |
}; | |
let Some(layout) = self.layouts.get_mut(layout_target as usize) else { | |
warn!("CommitLayout was called referencing an invalid layout. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",); | |
return; | |
}; | |
let Some(widget_holder) = layout.iter_mut().find(|widget| widget.widget_id == widget_id) else { | |
warn!("CommitLayout was called referencing an invalid widget ID, although the layout target was valid. `widget_id: {widget_id}`, `layout_target: {layout_target:?}`",); | |
return; | |
}; |
return; | ||
}; | ||
|
||
#[remain::sorted] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of having this match statement for all the widget types exist twice (also on lines 163-291). Would you mind breaking it out into a function and combining the two use cases into one so it does the update or commit logic depending on the function's arguments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, I could refactor it. But not that quick, I will find some time later today.
I have a couple remaining improvements that I have in mind related to this feature but I think it's better to merge this today and save those as follow-ups. But here are my comments for those:
|
2acb858
to
d07bab3
Compare
Closes #972
try to fix ColorButton and NumberInput widgets.