persist preview UI during import wizard

This commit is contained in:
juliandescottes 2017-04-02 19:45:22 +02:00 committed by Julian Descottes
parent 78bbc71e6c
commit a68dccfce0
7 changed files with 165 additions and 151 deletions

View file

@ -13,14 +13,18 @@
} }
.import-step-container { .import-step-container {
display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 10px;
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5); box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5);
background: #444; background: #444;
} }
.import-step-content {
padding: 10px;
}
.import-step-buttons { .import-step-buttons {
position: absolute; position: absolute;
bottom: 10px; bottom: 10px;
@ -36,6 +40,10 @@
* IMAGE IMPORT STEP * IMAGE IMPORT STEP
*/ */
.import-image-container {
padding: 10px;
}
.import-image-loading { .import-image-loading {
opacity: 0.3; opacity: 0.3;
pointer-events: none; pointer-events: none;
@ -148,6 +156,14 @@
.import-info { .import-info {
display: flex; display: flex;
flex-direction: column;
height: 100%;
max-width: 178px;
box-sizing: border-box;
padding: 10px;
border-right: 3px solid gold;
} }
.import-preview canvas { .import-preview canvas {
@ -156,8 +172,7 @@
} }
.import-meta { .import-meta {
width: 50%; margin-top: 10px;
padding-left: 10px;
box-sizing: border-box; box-sizing: border-box;
/*center meta information horizontally*/ /*center meta information horizontally*/
@ -203,10 +218,6 @@
color: #aaa; color: #aaa;
} }
.import-mode {
margin: 15px 0 20px 0;
}
.import-mode-title { .import-mode-title {
margin-bottom: 10px margin-bottom: 10px
} }
@ -228,10 +239,6 @@
/** /**
* ADJUST SIZE * ADJUST SIZE
*/ */
.import-resize-info {
margin: 10px 0 20px 0;
}
.import-resize-anchor-info, .import-resize-anchor-info,
.import-resize-option-label, .import-resize-option-label,
.insert-mode-option-label { .insert-mode-option-label {
@ -242,6 +249,10 @@
margin-bottom: 10px; margin-bottom: 10px;
} }
.import-resize-anchor {
margin-top: 20px;
}
.import-resize-option :checked + span { .import-resize-option :checked + span {
color: var(--highlight-color); color: var(--highlight-color);
} }
@ -255,9 +266,14 @@
*/ */
.insert-mode-container { .insert-mode-container {
margin-top: 20px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.insert-frame-container { .insert-frame-preview {
margin: 10px 0; margin: 10px 0;
} }
.insert-frame-preview .frame-picker-wrapper {
height: 120px;
}

View file

@ -52,6 +52,7 @@
if (this.hasSingleImage_()) { if (this.hasSingleImage_()) {
this.wizard.goTo('IMAGE_IMPORT'); this.wizard.goTo('IMAGE_IMPORT');
} else if (this.hasSinglePiskelFile_()) { } else if (this.hasSinglePiskelFile_()) {
// If a piskel file was provided we can directly go to
pskl.utils.PiskelFileUtils.loadFromFile(this.mergeData.rawFiles[0], pskl.utils.PiskelFileUtils.loadFromFile(this.mergeData.rawFiles[0],
// onSuccess // onSuccess
function (piskel) { function (piskel) {
@ -70,12 +71,12 @@
} }
}; };
ns.ImportWizard.prototype.back = function (stepInstance) { ns.ImportWizard.prototype.back = function () {
this.wizard.back(); this.wizard.back();
this.wizard.getCurrentStep().instance.onShow(); this.wizard.getCurrentStep().instance.onShow();
}; };
ns.ImportWizard.prototype.next = function (stepInstance) { ns.ImportWizard.prototype.next = function () {
var step = this.wizard.getCurrentStep(); var step = this.wizard.getCurrentStep();
if (step.name === 'IMAGE_IMPORT') { if (step.name === 'IMAGE_IMPORT') {
@ -149,11 +150,7 @@
this.piskelController.setPiskel(piskel); this.piskelController.setPiskel(piskel);
this.closeDialog(); this.closeDialog();
} }
} else if (mode === ns.steps.SelectMode.MODES.NEW) {
console.log('import as new: not implemented yet');
} else if (mode === ns.steps.SelectMode.MODES.MERGE) { } else if (mode === ns.steps.SelectMode.MODES.MERGE) {
// Need to also fetch resize options
// and insert location option
var merge = pskl.utils.MergeUtils.merge(this.piskelController.getPiskel(), piskel, { var merge = pskl.utils.MergeUtils.merge(this.piskelController.getPiskel(), piskel, {
insertIndex: this.mergeData.insertIndex, insertIndex: this.mergeData.insertIndex,
insertMode: this.mergeData.insertMode, insertMode: this.mergeData.insertMode,

View file

@ -38,6 +38,30 @@
this.importController.back(this); this.importController.back(this);
}; };
ns.AbstractImportStep.prototype.onShow = Constants.EMPTY_FUNCTION; ns.AbstractImportStep.prototype.onShow = function () {
var mergePiskel = this.mergeData.mergePiskel;
if (!mergePiskel) {
return;
}
if (!this.framePickerWidget) {
var framePickerContainer = this.container.querySelector('.import-preview');
this.framePickerWidget = new pskl.widgets.FramePicker(mergePiskel, framePickerContainer);
this.framePickerWidget.init();
} else if (this.framePickerWidget.piskel != mergePiskel) {
// If the piskel displayed by the frame picker is different from the previous one,
// refresh the widget.
this.framePickerWidget.piskel = mergePiskel;
this.framePickerWidget.setFrameIndex(1);
}
var metaHtml = pskl.utils.Template.getAndReplace('import-meta-content', {
name : mergePiskel.getDescriptor().name,
dimensions : pskl.utils.StringUtils.formatSize(mergePiskel.getWidth(), mergePiskel.getHeight()),
frames : mergePiskel.getFrameCount(),
layers : mergePiskel.getLayers().length
});
this.container.querySelector('.import-meta').innerHTML = metaHtml;
};
})(); })();

View file

@ -34,6 +34,7 @@
ns.AdjustSize.prototype.onShow = function () { ns.AdjustSize.prototype.onShow = function () {
this.refresh_(); this.refresh_();
this.superclass.onShow.call(this);
}; };
ns.AdjustSize.prototype.refresh_ = function () { ns.AdjustSize.prototype.refresh_ = function () {

View file

@ -15,13 +15,13 @@
ns.InsertLocation.prototype.init = function () { ns.InsertLocation.prototype.init = function () {
this.superclass.init.call(this); this.superclass.init.call(this);
this.framePreview = this.container.querySelector('.insert-frame-preview'); this.framePreview = this.container.querySelector('.insert-frame-preview');
this.framePickerWidget = new pskl.widgets.FramePicker( this.currentPiskelFramePickerWidget = new pskl.widgets.FramePicker(
this.piskelController.getPiskel(), this.framePreview); this.piskelController.getPiskel(), this.framePreview);
this.framePickerWidget.init(); this.currentPiskelFramePickerWidget.init();
var currentFrameIndex = this.piskelController.getCurrentFrameIndex(); var currentFrameIndex = this.piskelController.getCurrentFrameIndex();
this.framePickerWidget.setFrameIndex(currentFrameIndex + 1); this.currentPiskelFramePickerWidget.setFrameIndex(currentFrameIndex + 1);
this.framePickerWidget.setFirstFrameIndex(0); this.currentPiskelFramePickerWidget.setFirstFrameIndex(0);
this.insertModeContainer = this.container.querySelector('.insert-mode-container'); this.insertModeContainer = this.container.querySelector('.insert-mode-container');
this.addEventListener(this.insertModeContainer, 'change', this.onInsertModeChange_); this.addEventListener(this.insertModeContainer, 'change', this.onInsertModeChange_);
@ -33,25 +33,25 @@
this.mergeData.insertMode = value; this.mergeData.insertMode = value;
if (this.mergeData.insertMode === ns.InsertLocation.MODES.ADD) { if (this.mergeData.insertMode === ns.InsertLocation.MODES.ADD) {
this.framePickerWidget.setFirstFrameIndex(0); this.currentPiskelFramePickerWidget.setFirstFrameIndex(0);
} else { } else {
this.framePickerWidget.setFirstFrameIndex(1); this.currentPiskelFramePickerWidget.setFirstFrameIndex(1);
} }
}; };
ns.InsertLocation.prototype.onShow = function () { ns.InsertLocation.prototype.onShow = function () {
var count = this.mergeData.mergePiskel.getFrameCount(); // Nothing to do here!
this.container.querySelector('.insert-frames-count').innerText = count; this.superclass.onShow.call(this);
}; };
ns.InsertLocation.prototype.onNextClick = function () { ns.InsertLocation.prototype.onNextClick = function () {
var insertIndex = this.framePickerWidget.getFrameIndex(); var insertIndex = this.currentPiskelFramePickerWidget.getFrameIndex();
this.mergeData.insertIndex = insertIndex; this.mergeData.insertIndex = insertIndex;
this.superclass.onNextClick.call(this); this.superclass.onNextClick.call(this);
}; };
ns.InsertLocation.prototype.destroy = function () { ns.InsertLocation.prototype.destroy = function () {
this.framePickerWidget.destroy(); this.currentPiskelFramePickerWidget.destroy();
this.superclass.destroy.call(this); this.superclass.destroy.call(this);
}; };
})(); })();

View file

@ -6,7 +6,6 @@
}; };
ns.SelectMode.MODES = { ns.SelectMode.MODES = {
NEW : 'new',
REPLACE : 'replace', REPLACE : 'replace',
MERGE : 'merge' MERGE : 'merge'
}; };
@ -25,6 +24,7 @@
ns.SelectMode.prototype.onShow = function () { ns.SelectMode.prototype.onShow = function () {
this.refresh_(); this.refresh_();
this.superclass.onShow.call(this);
}; };
ns.SelectMode.prototype.destroy = function () { ns.SelectMode.prototype.destroy = function () {
@ -37,7 +37,6 @@
ns.SelectMode.prototype.refresh_ = function () { ns.SelectMode.prototype.refresh_ = function () {
var mergePiskel = this.mergeData.mergePiskel; var mergePiskel = this.mergeData.mergePiskel;
if (mergePiskel) { if (mergePiskel) {
this.updateMergeFilePreview_();
this.nextButton.removeAttribute('disabled'); this.nextButton.removeAttribute('disabled');
} else { } else {
this.nextButton.setAttribute('disabled', true); this.nextButton.setAttribute('disabled', true);
@ -52,32 +51,6 @@
} }
}; };
ns.SelectMode.prototype.updateMergeFilePreview_ = function () {
var mergePiskel = this.mergeData.mergePiskel;
var previewFrame = pskl.utils.LayerUtils.mergeFrameAt(mergePiskel.getLayers(), 0);
var image = pskl.utils.FrameUtils.toImage(previewFrame);
if (!this.framePickerWidget) {
var framePickerContainer = this.container.querySelector('.import-preview');
this.framePickerWidget = new pskl.widgets.FramePicker(mergePiskel, framePickerContainer);
this.framePickerWidget.init();
} else if (this.framePickerWidget.piskel != mergePiskel) {
// If the piskel displayed by the frame picker is different from the previous one,
// refresh the widget.
this.framePickerWidget.piskel = mergePiskel;
this.framePickerWidget.setFrameIndex(1);
}
var metaHtml = pskl.utils.Template.getAndReplace('import-meta-content', {
name : mergePiskel.getDescriptor().name,
dimensions : pskl.utils.StringUtils.formatSize(mergePiskel.getWidth(), mergePiskel.getHeight()),
frames : mergePiskel.getFrameCount(),
layers : mergePiskel.getLayers().length
});
this.container.querySelector('.import-meta').innerHTML = metaHtml;
};
ns.SelectMode.prototype.onImportModeChange_ = function () { ns.SelectMode.prototype.onImportModeChange_ = function () {
this.mergeData.importMode = this.getSelectedMode_(); this.mergeData.importMode = this.getSelectedMode_();
this.refresh_(); this.refresh_();

View file

@ -9,48 +9,46 @@
</script> </script>
<script type="text/template" id="import-image-import"> <script type="text/template" id="import-image-import">
<div class="import-step-container"> <div class="import-step-container import-image-container">
<div> <form action="" method="POST" name="import-image-form">
<form action="" method="POST" name="import-image-form"> <div class="import-section">
<div class="import-section"> <span class="dialog-section-title">Name :</span><span class="import-image-file-name"></span>
<span class="dialog-section-title">Name :</span><span class="import-image-file-name"></span> </div>
</div> <div class="import-section">
<div class="import-section"> <div class="import-section-preview"></div>
<div class="import-section-preview"></div> </div>
</div> <div class="import-section">
<div class="import-section"> <label class="dialog-section-radio-label">
<label class="dialog-section-radio-label"> <input class="dialog-section-radio" name="import-type" value="single" type="radio" checked="checked">
<input class="dialog-section-radio" name="import-type" value="single" type="radio" checked="checked"> Import as single image
Import as single image </label>
</label> </div>
</div> <div class="import-section import-subsection">
<div class="import-section import-subsection"> <span class="dialog-section-title">Resize to</span>
<span class="dialog-section-title">Resize to</span> <input type="text" class="textfield import-size-field" name="resize-width"/>x
<input type="text" class="textfield import-size-field" name="resize-width"/>x <input type="text" class="textfield import-size-field" name="resize-height"/>
<input type="text" class="textfield import-size-field" name="resize-height"/> </div>
</div> <div class="import-section import-subsection">
<div class="import-section import-subsection"> <span class="import-section-title">Smooth resize</span>
<span class="import-section-title">Smooth resize</span> <input type="checkbox" class="checkbox-fix" checked="checked" name="smooth-resize-checkbox" value="1"/>
<input type="checkbox" class="checkbox-fix" checked="checked" name="smooth-resize-checkbox" value="1"/> </div>
</div> <div class="import-section">
<div class="import-section"> <label class="dialog-section-radio-label">
<label class="dialog-section-radio-label"> <input class="dialog-section-radio" name="import-type" value="sheet" type="radio">
<input class="dialog-section-radio" name="import-type" value="sheet" type="radio"> Import as spritesheet
Import as spritesheet </label>
</label> </div>
</div> <div class="import-section import-subsection">
<div class="import-section import-subsection"> <span class="dialog-section-title">Frame size</span>
<span class="dialog-section-title">Frame size</span> <input type="text" class="textfield import-size-field" name="frame-size-x"/>x
<input type="text" class="textfield import-size-field" name="frame-size-x"/>x <input type="text" class="textfield import-size-field" name="frame-size-y"/>
<input type="text" class="textfield import-size-field" name="frame-size-y"/> </div>
</div> <div class="import-section import-subsection">
<div class="import-section import-subsection"> <span class="dialog-section-title">Offset</span>
<span class="dialog-section-title">Offset</span> <input type="text" class="textfield import-size-field" name="frame-offset-x"/>x
<input type="text" class="textfield import-size-field" name="frame-offset-x"/>x <input type="text" class="textfield import-size-field" name="frame-offset-y"/>
<input type="text" class="textfield import-size-field" name="frame-offset-y"/> </div>
</div> </form>
</form>
</div>
<div class="import-step-buttons"> <div class="import-step-buttons">
<button class="import-cancel-button button">cancel</button> <button class="import-cancel-button button">cancel</button>
<button class="import-back-button button">back</button> <button class="import-back-button button">back</button>
@ -61,40 +59,34 @@
<script type="text/template" id="import-select-mode"> <script type="text/template" id="import-select-mode">
<div class="import-step-container"> <div class="import-step-container">
<div class="import-mode-title">Preview the imported image</div>
<div class="import-info"> <div class="import-info">
<div class="import-preview"></div> <div class="import-preview"></div>
<div class="import-meta"></div> <div class="import-meta"></div>
</div> </div>
<div class="import-mode"> <div class="import-step-content">
<div class="import-mode-title">How do you want to import the new content?</div> <div class="import-mode">
<label class="import-mode-option"> <div class="import-mode-title">How do you want to import the new content?</div>
<input type="radio" checked="checked" name="import-mode" id="select-mode-replace" value="replace"/> <label class="import-mode-option">
<span>Replace your current sprite</span> <input type="radio" checked="checked" name="import-mode" id="select-mode-replace" value="replace"/>
</label> <span>Replace your current sprite</span>
<!-- label class="import-mode-option"> </label>
<input type="radio" name="import-mode" id="select-mode-new" value="new"/> <label class="import-mode-option">
<span>Create a new sprite</span> <input type="radio" name="import-mode" id="select-mode-import" value="merge"/>
</label --> <span>Merge with your current sprite</span>
<label class="import-mode-option"> </label>
<input type="radio" name="import-mode" id="select-mode-import" value="merge"/> </div>
<span>Merge with your existing sprite</span>
</label>
</div>
<div class="import-step-buttons"> <div class="import-step-buttons">
<button class="import-cancel-button button">cancel</button> <button class="import-cancel-button button">cancel</button>
<button class="import-back-button button">back</button> <button class="import-back-button button">back</button>
<button class="import-next-button button button-primary">next</button> <button class="import-next-button button button-primary">next</button>
</div>
</div> </div>
</div> </div>
</script> </script>
<script type="text/template" id="import-meta-content"> <script type="text/template" id="import-meta-content">
<div class="import-meta-title">
<span class="import-meta-label">Imported content details</span>
</div>
<div class="import-name"> <div class="import-name">
<span class="import-meta-label">Name</span> <span class="import-meta-label">Name</span>
<span class="import-meta-value" title={{name}}>{{name}}</span> <span class="import-meta-value" title={{name}}>{{name}}</span>
@ -115,15 +107,23 @@
<script type="text/template" id="import-adjust-size"> <script type="text/template" id="import-adjust-size">
<div class="import-step-container"> <div class="import-step-container">
<div class="import-resize-info"></div>
<div class="import-resize-anchor import-resize-section"> <div class="import-info">
<div class="import-resize-anchor-info"></div> <div class="import-preview"></div>
<div class="import-resize-anchor-container"></div> <div class="import-meta"></div>
</div> </div>
<div class="import-step-buttons">
<button class="import-cancel-button button">cancel</button> <div class="import-step-content">
<button class="import-back-button button">back</button> <div class="import-resize-info"></div>
<button class="import-next-button button button-primary">next</button> <div class="import-resize-anchor import-resize-section">
<div class="import-resize-anchor-info"></div>
<div class="import-resize-anchor-container"></div>
</div>
<div class="import-step-buttons">
<button class="import-cancel-button button">cancel</button>
<button class="import-back-button button">back</button>
<button class="import-next-button button button-primary">next</button>
</div>
</div> </div>
</div> </div>
</script> </script>
@ -159,29 +159,32 @@
<script type="text/template" id="import-insert-location"> <script type="text/template" id="import-insert-location">
<div class="import-step-container"> <div class="import-step-container">
<div class="insert-mode-container"> <div class="import-info">
<div class="insert-mode-option-label"> <div class="import-preview"></div>
The imported animation contains <span class="insert-frames-count">X</span> frames. <div class="import-meta"></div>
Select how the new frames should be inserted:
</div>
<label class="insert-mode-option">
<input type="radio" name="insert-mode" id="insert-mode-add" value="add" checked="checked"/>
<span>Add new frames</span>
</label>
<label class="insert-mode-option">
<input type="radio" name="insert-mode" id="insert-mode-insert" value="insert"/>
<span>Insert in existing frames</span>
</label>
</div> </div>
<div>Select the frame from which the new content will be added</div>
<div class="insert-frame-container"> <div class="import-step-content">
<div>Select a frame in your current sprite:</div>
<div class="insert-frame-preview"></div> <div class="insert-frame-preview"></div>
<div class="insert-frame-meta"></div> <div class="insert-mode-container">
</div> <div class="insert-mode-option-label">
<div class="import-step-buttons"> How should the imported frames be inserted:
<button class="import-cancel-button button">cancel</button> </div>
<button class="import-back-button button">back</button> <label class="insert-mode-option">
<button class="import-next-button button button-primary">import</button> <input type="radio" name="insert-mode" id="insert-mode-add" value="add" checked="checked"/>
<span>Add new frames</span>
</label>
<label class="insert-mode-option">
<input type="radio" name="insert-mode" id="insert-mode-insert" value="insert"/>
<span>Insert in existing frames</span>
</label>
</div>
<div class="import-step-buttons">
<button class="import-cancel-button button">cancel</button>
<button class="import-back-button button">back</button>
<button class="import-next-button button button-primary">import</button>
</div>
</div> </div>
</div> </div>
</script> </script>