Skip to content
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

Animation Editor- Multiple Frame duration edit feature #1784

Merged
merged 9 commits into from Jan 12, 2018

Conversation

satu0king
Copy link
Contributor

Added a spinBox where the user can select a frame duration.
The Set Frame Time button has two purposes

  1. If no Frame(s) are selected, then it sets the duration of all frames to the duration of the spinBox. It also resets the default Frame duration to that duration.
  2. If frame(s) are selected, then it sets the duration of all those frames to the duration of the spinBox. Default Frame duration is not changed.

Issues: The undo in situation 2 works but not all at a time. Each frame update is registered separately instead of all at a once. I am not sure how to fix this. Apart from this minor bug, everything seems to be all right.

This is the first time I am contributing to open source. I am new to Tiled and QT,However I am not new to programming. Please guide me.

Copy link
Contributor

@ketanhwr ketanhwr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made some comments regarding the coding style.


void addFrame(const Frame &frame);

const Tileset *mTileset;
QVector<Frame> mFrames;
};

int FrameListModel::DEFAULT_DURATION=100;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you can initialise this in the constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think this can be done in a constructor as its a static variable ..

@@ -257,6 +259,13 @@ const QVector<Frame> &FrameListModel::frames() const
{
return mFrames;
}
void FrameListModel::setDefaultFrameTime(int duration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a gap between the above two lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Change has been made.

@@ -257,6 +259,13 @@ const QVector<Frame> &FrameListModel::frames() const
{
return mFrames;
}
void FrameListModel::setDefaultFrameTime(int duration)
{
DEFAULT_DURATION=duration;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coding style: DEFAULT_DURATION = duration;

void FrameListModel::setDefaultFrameTime(int duration)
{
DEFAULT_DURATION=duration;
for(Frame &F:mFrames){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coding style: for (Frame &F:mFrames) {

And since this is a single line statement, you can get rid of the braces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Change has been made.

{
DEFAULT_DURATION=duration;
for(Frame &F:mFrames){
F.duration=duration;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces around the =

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Change has been made.

@@ -391,6 +405,21 @@ void TileAnimationEditor::framesEdited()
mFrameListModel->frames()));
mApplyingChanges = false;
}
void TileAnimationEditor::setFrameTime()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A gap between the two lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Change has been made.

{
QItemSelectionModel *selectionModel = mUi->frameList->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
if (indexes.isEmpty()){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coding stye: if (indexes.isEmpty()) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Change has been made.

Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the first time I am contributing to open source. I am new to Tiled and QT,However I am not new to programming. Please guide me.

Thanks for taking on this issue and welcome to open source! It's a great initiative and I sincerely hope our comments on the pull request won't put you off.

I've provided some more detailed feedback and also commented on the problem you have with the undo.

src/.qmake.stash Outdated
@@ -0,0 +1,42 @@
QMAKE_MAC_SDK.macosx.Path = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't add this file, since it's a build artifact. To help avoid this file getting added I've now pushed an explicit ignore rule for it in change 337670d.

{
DEFAULT_DURATION = duration;
for(Frame &F:mFrames)
F.duration=duration;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put spaces according to the coding style:

for (Frame &frame : mFrames)
    frame.duration = duration;

(also, rename F to frame)

I find this side-effect a little strange for a function called setDefaultFrameTime. Please separate it into another function.

SLOT(setFrameTime()));



Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please leave only one empty line.

void TileAnimationEditor::setFrameTime()
{
QItemSelectionModel *selectionModel = mUi->frameList->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
Copy link
Member

@bjorn bjorn Oct 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please declare as const QModelIndexList. Since you're not modifying the list this avoids potential detaching (deep-copy) of the data.

return;
}
for (const QModelIndex &index : indexes)
mFrameListModel->setData(index,mUi->frameTime->value(),Qt::EditRole);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coding style: should have spaces after the commas.

Regarding the problem with the undo history, each call here emits dataChanged from the model, which is connected to framesEdited, which creates a ChangeTileAnimation undo command. To avoid this, you could introduce a boolean like mSuppressUndo and temporarily set it to true in this function, checking that in framesEdited and setting it to false again before calling framesEdited explicitly.

<property name="value">
<number>100</number>
</property>
</widget>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would generally use Qt Designer or the Design mode in Qt Creator for editing .ui files, but if you do it by hand, please do take care that they are formatted consistently (easiest should be to open the file in Qt Designer and save it again).

<string>ms</string>
</property>
<property name="minimum">
<number>20</number>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is 20 ms the minimum frame time? I would just put it on 1 ms.

<number>10000</number>
</property>
<property name="singleStep">
<number>20</number>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use 10 ms here.

@@ -20,6 +20,35 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="frameTime">
<property name="suffix">
<string>ms</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be " ms" (starting with a space).

<item>
<widget class="QPushButton" name="setFrameTimeButton">
<property name="text">
<string>Set Frame Time</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nicer to use a label "Frame duration:", then the input box, and then the button with just "Apply" on it.

@satu0king
Copy link
Contributor Author

satu0king commented Dec 25, 2017

Really sorry that I didn't make the changes earlier.
I fixed the undo issue the way @bjorn told to do and did all the corrections requested by @bjorn and @ketanhwr.

@satu0king
Copy link
Contributor Author

Can you please check if my PR is alright, if not let me know the mistakes

Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for continuing your work on this!

I've left a few more comments. Also, I think it would be good to make the default frame duration persistent (remembered across Tiled sessions). Check out how persistence is implemented in other dialogs, like the NewMapDialog.

<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Frame-Duration: </string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change to "Frame duration:"

const QModelIndexList indexes = selectionModel->selectedIndexes();

if (indexes.isEmpty()) {
mFrameListModel->setDefaultFrameTime(mUi->frameTime->value());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the default animation time should change immediately when you change the value of the frameTime widget. And of course, without affecting the existing frames.

{
DEFAULT_DURATION = duration;
for(Frame &frame : mFrames)
frame.duration = duration;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my previous review I commented that I don't like this side-effect of setDefaultFrameTime. Please don't change the animation and just set the new default frame time (also this setter can be static then).

const QVector<Frame> &frames() const;

private:
static const int DEFAULT_DURATION = 100;
static int DEFAULT_DURATION;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable used by the in ALL_CAPS because it was a constant. Now that it can be changed, please rename to mDefaultDuration.


if (indexes.isEmpty()) {
mFrameListModel->setDefaultFrameTime(mUi->frameTime->value());
mUi->frameList->setFocus(); // This is necessary for the UI, It does not get updates without this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a hack, which works because it triggers a repaint. The reason the UI isn't updating is that setDefaultFrameTime is modifying the frame durations without emitting the dataChanged signal.

Please write a separate function like FrameListModel::applyFrameTime that sets the duration like currently setDefaultFrameTime is doing, but in addition it should emit dataChanged with appropriate indexes. Something like:

emit dataChanged(index(0), index(mFrames.length() - 1), { Qt::EditRole, Qt::DisplayRole });

(since this will only be valid when there is at least one frame, you need to early-out if mFrames.isEmpty())

Copy link
Contributor Author

@satu0king satu0king Jan 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now understood why it wasn't working and why the hack worked. I am going to use the function that was written previously. It internally emits a data change signal mFrameListModel->setData()

@satu0king
Copy link
Contributor Author

satu0king commented Jan 7, 2018

I think I got it right this time. I did the following things

  • Persistence of Frame Duration across Tiled sessions. (As implemented in NewMapDialog)

  • Removed side effect of setDefaultFrameTime() .

  • Change default time immediately on a change of frame-time widget.

  • Removed the hack and used data emit on changing frame time.

  • Name errors

    @bjorn, please let me know if there are any mistakes.

@bjorn bjorn merged commit 7971fa8 into mapeditor:master Jan 12, 2018
@bjorn
Copy link
Member

bjorn commented Jan 12, 2018

All looking good, thanks for your contribution!

I didn't close #1310 since it had an idea which I think could still be interesting to add, which would be to add the ability to add/subtract/multiply with the duration of the selected animation frames. I could see this being added by way of adding a menu to the "Apply" button with the additional actions, but in that case I think it's a little strange to combine it with the automatic change of default frame duration (maybe that should then become another item in this menu). In any case I'm a little undecided about this, but if you like you could try to fit in that functionality as well.

@satu0king satu0king deleted the TileAnimationEditor branch January 12, 2018 15:28
bjorn added a commit that referenced this pull request Jan 30, 2018
…ames (#1784)"

This reverts commit 7971fa8.

That change was not supposed to be done on the 1.1 branch, which is in
string freeze.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants