-
Notifications
You must be signed in to change notification settings - Fork 828
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
Piskel Resize prompt for any new animations + ability to set name and subfolder of new animations! #522
Conversation
This makes the resize pop up show up whenever the user opens a brand new piskel animation
- this adds ability to set name of new piskel frames - it also paves the way to transfer the name set in piskel back to gdevelop
Added ability to set name of animation - It only affects the name of frames created in piskel- it will not rename any imported files from gdevelop, but should help with organizing! I also made it so the user cant use any input characters that would lead to an invalid basepath Now I am trying to figure out how to use the name fetched from piskel to set the changed animation's optional name - @4ian should i somehow pass it to the onchangessaved function? |
Yes I think you can pass it and use it to pass it to a function that will change the animation name. |
newIDE/app/package.json
Outdated
@@ -21,6 +21,7 @@ | |||
"classnames": "2.2.5", | |||
"create-react-context": "^0.1.6", | |||
"date-fns": "^1.29.0", | |||
"electron": "^2.0.2", |
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.
You should not commit any changes that you made to package.json or package-lock.json. Can you try to remove these?
You may want to read about git add
(if you're using command line) (and git add -p
, which is super useful to choose the part to add in your commit). If you're using a graphical client you should also be able to choose the files to include in your commits.
In general, only commit the changes related to your feature - otherwise I'll have to edit your commits and remove these :)
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.
ah sorry, i thought it was in the gitignore
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.
The gitignore contains the file that are not in the git repository at all.
It's a bit a pain at the beginning but once you know how to choose the files to commit, you can make much cleaner commits :) (by not selecting files like package.json or package-lock.json, or files with irrelevant changes)
guess the subfolder via the path of the first loaded resource
@4ian can you help me in changing it (the animation name)? I am not sure how to pass it through the onchangessaved function. I got piskel to send it back to gdevelop, but can't figure out how to tell gdevelop to change it. I also want to send the name to piskel too - so piskel uses the animation name if the user has entered a name- instead of the object name. The object name is the backup option |
First, let's pass the name from Piskel back to GD:
EDIT: In fact you've already done what I've said above ;) Here is the more interesting part then: Now, you have the name (or whatever more complex object) in GDevelop The job is mainly to be able to use React "props" to pass the function down to the EDIT : (If you're unfamiliar with props, maybe you can take a look at this React doc: https://reactjs.org/docs/handling-events.html) |
...but not both. This will make more sense when the animation name on new animations is set in piskel and piskel sends it back to gdevelop
@4ian Thank you for the explanation :) Btw I love the way you have designed gdevelop's new editor, it's a beautiful thing 👍 |
Cool, let me know how it goes! You can see that
Thanks! It's the way how everything is architectured in the IDE with React: components are handling some part of the interface and use props to pass or get information to their children or parent components - where the real work is done. Need a bit of reading to find where to add new code, but the result is clean and really modular. |
@4ian how would one export the function changeAnimationName from a class that is not exported in index.js? I tried everything,including importing and using onChangeAnimationName, and it still says that it is not a function Do I need to edit multiple files to get access to that function in spriteList.js? Can you show me just in this instance how one would import it in the best way? |
So you need to call The answer is no, there is no such props that we can use that is passed by You can see being passed to another component here: https://github.com/4ian/GD/blob/af4cdcd48542fcda671704fe5800f517ab02ca83/newIDE/app/src/ObjectEditor/Editors/SpriteEditor/index.js#L122 Seems that its usage is quite simple: call it why the new name of the function as argument. Typing is helping us to ensure that this is the case: So let's pass it to SpritesList! At the end of Once you've added this props, it becames available in SpritesList. You can use it anywhere in the Something like this: When you call this function in SpritesList, the original function React will update any children component using the animation name so that the change is reflected everywhere. |
Following my previous explanation, the last thing you need to do is to "register" the new prop Add your new prop: |
@4ian I did it by adding this line to spriteList's return function (index.js): That allowed me to use it like this in SpriteList.js
but I also did as you said- registering it like this
So if the user hasnt set any optional animation name- piskel will automatically set it in gdevelop, depending on what was set in piskel when the animation was created |
Btw thank you for explaining this. Passing functions between modules confused me at first |
Yes that looks correct! :) Passing functions in "props" is the React way to "export" functions to other components. It is what makes all component reusable because you can easily plug any function to any props and all will behave properly. Much like assembling bricks and plugging them together :) |
...if there is no animation name used
@4ian ready for review now :) We can now:
For support of saving layers -i need to do that in another pull- when we figure how to approach that |
Great! Will try to check this today, posting comments as usual and we'll merge this when it is ready then. Thanks for your work so far 👍 |
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've left various comments about different things, that will help for clarity and maintainability. Thanks again for your work so far :)
Let me know if you have any question!
@@ -4,12 +4,52 @@ const path = require('path'); | |||
const fs = require('fs'); | |||
const async = require('async'); | |||
const remote = electron.remote; | |||
const { dialog } = require('electron').remote; |
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.
nitpicking: You can do const { dialog } = remote
, as remote is defined on the previous line.
if (!projectBasePath) { | ||
projectBasePath = piskelOptions.projectPath; | ||
} | ||
var selectedDir = dialog.showOpenDialog(remote.getCurrentWindow(), { |
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.
nitpicking: can you use const instead of var? :)
return; | ||
} | ||
piskelOptions.projectPath = selectedDir; | ||
alert('New frames will be saved in:\n' + piskelOptions.projectPath); |
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.
Do you think this alert is necessary? I'm thinking it can be a bit redundant. If the user clicked on the folder and chose a new folder, the UI will be updated with the new path, I think it's clear enough.
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 will remove it. You are right - it might get annoying after the first time :)
|
||
const editorContentWindow = document.getElementById('piskel-frame') | ||
.contentWindow; | ||
let baseExportPath; | ||
let piskelOptions; // The options received from GDevelop | ||
|
||
let saveFolderLabel, |
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.
nitpicking: you're set piskelAnimationNameInput
to an empty object, while later your making it a reference to a DOM input element (as the name properly implies).
It's best to then avoid using an object (which confuses the source code reader) and set it explicitly to null
, null meaning that "this input is not yet created". You may have to update one or two other places to ensure that piskelAnimationNameInput
is not null then before doing a change.
Objects are more to store data.
); // Don't allow the user to enter any characters that would lead to an invalid path | ||
piskelOptions.name = piskelAnimationNameInput.value; | ||
baseExportPath = piskelOptions.projectPath + '/' + piskelOptions.name; | ||
saveFolderLabel.innerHTML = piskelOptions.projectPath + '\\'; |
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.
Avoid innerHTML
as much as possible, consider using .textContent
. It will first avoid you to have to escape characters, and above all it avoid XSS injections attacks that are possible when using innerHTML
.
(All of this is not needed with a UI framework like React - which one of the many reason why it's great :))
More interesting information available here: https://stackoverflow.com/questions/24427621/innertext-vs-innerhtml-vs-label-vs-text-vs-textcontent-vs-outertext
objectName, | ||
animationName, | ||
animationName, |
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.
nitpicking: there is a useless extra space at the end of the line ;)
isLooping: direction.isLooping(), | ||
}, | ||
onChangesSaved: resources => { | ||
onChangesSaved: (resources,newAnimationName) => { |
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.
nitpicking: missing a space before the comma, be sure to run prettier to fix this
@@ -54,8 +54,7 @@ export const openPiskel = ({ | |||
resourcesManager.addResource(imageResource); | |||
imageResource.delete(); | |||
}); | |||
|
|||
onChangesSaved(outputResources); | |||
onChangesSaved(outputResources,newAnimationName); |
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.
nitpicking: missing space after the comma
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.
ah sorry, I will run format document on all the files again
@@ -11,7 +11,7 @@ export type ExternalEditorOpenOptions = {| | |||
singleFrame: boolean, // If set to true, edition should be limited to a single frame | |||
resourceNames: Array<string>, | |||
onChangesSaved: ( | |||
Array<{ path: string, name: string, originalIndex: ?number }> | |||
Array<{ path: string, name: string, originalIndex: ?number }>, newName: string |
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.
👍 great, thanks for updating flow!
); | ||
updatePiskelBasePath(); //update the path label | ||
// Disable changing path and naming convention by user - on animations imported from gdevelop | ||
saveFolderLabel.removeEventListener('click', selectBaseFolderPath); |
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.
Maybe move this part (all the logic to disable folder choosing) in another function? Will help to achieve clarity by avoiding mixing the loading logic with the UI updating logic. :)
Applied all requested changes :) Comit coming later today 👍 |
@4ian pull submited =) |
Will double check this this evening :) Thanks! |
Looks ok like this. Will merge this week-end! |
@4ian 'm sorry, I tried to remove it, but gitkraken wont let me unstage it, because it is in previous commits :( |
This answer says that you have to reset the file in your pull request branch and make a new commit: https://stackoverflow.com/questions/39459467/remove-a-modified-file-from-pull-request |
This reverts commit f316b37.
@Lizard-13 @4ian I solved it by reverting the comit in which it was introduced Thank you for the help :) |
Good job with reverting the commit :) |
@4ian thank you for reviewing this and the patience! Now the piskel implementation in gdevelop is almost feature complete. Only thing missing is the ability to preserve layer data |
This makes the resize pop up show up whenever the user opens a brand new piskel animation
It also enables the ability to select the folder where you want piskel to create new frames, as well as the name of the files:
Note:
This also makes sure that the user doesnt put any symbols in the animation name that would lead to an invalid filepath