Add a special dialog for File > Export command

With this change we have moved all the file selector customization to
a new special FileExportWindow. So the file selector is used only to
select the output file (no more FileSelectorDelegate = now we can use
the native file selector for File > Export).
This commit is contained in:
David Capello 2018-03-15 20:34:01 -03:00
parent 10590da7c1
commit 8014c828af
13 changed files with 323 additions and 434 deletions

View File

@ -449,6 +449,16 @@ duplicate = Duplicate:
as = As:
merged_layers = Duplicate merged layers only
[export_file]
title = Export File
output_file = Output File:
resize = Resize:
layers = Layers:
frames = Frames:
pixel_ratio = Apply pixel ratio
export = &Export
cancel = &Cancel
[export_sprite_sheet]
title = Export Sprite Sheet
sheet_type = Sheet Type:
@ -483,15 +493,6 @@ go_up_button_tooltip = Up to parent folder
new_folder_button_tooltip = New folder
file_name = File name:
file_type = File type:
resize = Resize:
layeres = Layers:
frames = Frames:
[file_selector_extras]
resize = Resize:
layers = Layers:
frames = Frames:
pixel_ratio = Apply pixel ratio
[font_popup]
load = Load

View File

@ -0,0 +1,42 @@
<!-- Aseprite -->
<!-- Copyright (C) 2016-2018 by David Capello -->
<gui>
<window id="export_file" text="@.title">
<grid columns="2">
<label text="@.output_file" />
<button id="output_filename" cell_align="horizontal" maxwidth="256" />
<label id="resize_label" text="@.resize" />
<combobox id="resize" cell_align="horizontal">
<listitem text="25%" value="0.25" />
<listitem text="50%" value="0.5" />
<listitem text="100%" value="1" />
<listitem text="200%" value="2" />
<listitem text="300%" value="3" />
<listitem text="400%" value="4" />
<listitem text="500%" value="5" />
<listitem text="600%" value="6" />
<listitem text="700%" value="7" />
<listitem text="800%" value="8" />
<listitem text="900%" value="9" />
<listitem text="1000%" value="10" />
</combobox>
<label id="layers_label" text="@.layers" />
<combobox id="layers" text="" cell_align="horizontal" />
<label id="frames_label" text="@.frames" />
<combobox id="frames" text="" cell_align="horizontal" />
<check id="pixel_ratio" text="@.pixel_ratio" cell_hspan="2" />
<hbox cell_hspan="2">
<boxfiller />
<hbox homogeneous="true">
<button text="@.export" minwidth="60" closewindow="true" id="ok" magnet="true" />
<button text="@.cancel" minwidth="60" closewindow="true" />
</hbox>
</hbox>
</grid>
</window>
</gui>

View File

@ -1,5 +1,5 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="file_selector" text="">
<vbox id="main">
@ -20,11 +20,6 @@
<label text="@.file_type" />
<hbox cell_align="horizontal">
<combobox id="file_type" minwidth="70" />
<vbox>
<boxfiller />
<link id="extra_options" text="" />
<boxfiller />
</vbox>
<boxfiller />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" width="60" />

View File

@ -1,31 +0,0 @@
<!-- Aseprite -->
<!-- Copyright (C) 2016-2017 by David Capello -->
<gui>
<vbox id="file_selector_extras">
<grid columns="2">
<label id="resize_label" text="@.resize" />
<combobox id="resize" cell_align="horizontal">
<listitem text="25%" value="0.25" />
<listitem text="50%" value="0.5" />
<listitem text="100%" value="1" />
<listitem text="200%" value="2" />
<listitem text="300%" value="3" />
<listitem text="400%" value="4" />
<listitem text="500%" value="5" />
<listitem text="600%" value="6" />
<listitem text="700%" value="7" />
<listitem text="800%" value="8" />
<listitem text="900%" value="9" />
<listitem text="1000%" value="10" />
</combobox>
<label id="layers_label" text="@.layers" />
<combobox id="layers" text="" cell_align="horizontal" />
<label id="frames_label" text="@.frames" />
<combobox id="frames" text="" cell_align="horizontal" />
<check id="pixel_ratio" text="@.pixel_ratio" cell_hspan="2" />
</grid>
</vbox>
</gui>

View File

@ -480,6 +480,7 @@ add_library(app-lib
ui/editor/tool_loop_impl.cpp
ui/editor/transform_handles.cpp
ui/editor/zooming_state.cpp
ui/export_file_window.cpp
ui/file_list.cpp
ui/file_list_view.cpp
ui/file_selector.cpp

View File

@ -24,6 +24,7 @@
#include "app/pref/preferences.h"
#include "app/recent_files.h"
#include "app/restore_visible_layers.h"
#include "app/ui/export_file_window.h"
#include "app/ui/layer_frame_comboboxes.h"
#include "app/ui/status_bar.h"
#include "base/bind.h"
@ -37,70 +38,6 @@
namespace app {
class SaveAsCopyDelegate : public FileSelectorDelegate {
public:
SaveAsCopyDelegate(const Sprite* sprite,
const double scale,
const std::string& layer,
const std::string& frame,
const bool applyPixelRatio)
: m_sprite(sprite),
m_resizeScale(scale),
m_layer(layer),
m_frame(frame),
m_applyPixelRatio(applyPixelRatio) { }
bool hasResizeCombobox() override {
return true;
}
double getResizeScale() override {
return m_resizeScale;
}
void setResizeScale(double scale) override {
m_resizeScale = scale;
}
void fillLayersComboBox(ui::ComboBox* layers) override {
fill_layers_combobox(m_sprite, layers, m_layer);
}
void fillFramesComboBox(ui::ComboBox* frames) override {
fill_frames_combobox(m_sprite, frames, m_frame);
}
std::string getLayers() override { return m_layer; }
std::string getFrames() override { return m_frame; }
void setLayers(const std::string& layer) override {
m_layer = layer;
}
void setFrames(const std::string& frame) override {
m_frame = frame;
}
void setApplyPixelRatio(bool applyPixelRatio) override {
m_applyPixelRatio = applyPixelRatio;
}
bool applyPixelRatio() const override {
return m_applyPixelRatio;
}
doc::PixelRatio pixelRatio() override {
return m_sprite->pixelRatio();
}
private:
const Sprite* m_sprite;
double m_resizeScale;
std::string m_layer;
std::string m_frame;
bool m_applyPixelRatio;
};
class SaveFileJob : public Job, public IFileOpProgress {
public:
SaveFileJob(FileOp* fop)
@ -173,36 +110,31 @@ bool SaveFileBaseCommand::onEnabled(Context* context)
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
}
bool SaveFileBaseCommand::saveAsDialog(
std::string SaveFileBaseCommand::saveAsDialog(
Context* context,
const std::string& dlgTitle,
const std::string& forbiddenFilename,
FileSelectorDelegate* delegate)
const std::string& initialFilename,
const bool markAsSaved,
const bool saveInBackground,
const std::string& forbiddenFilename)
{
const Document* document = context->activeDocument();
Document* document = context->activeDocument();
std::string filename;
// If there is a delegate, we're doing a "Save Copy As/Export", so we don't
// have to mark the file as saved.
const bool isExport = (delegate != nullptr);
const bool markAsSaved = (!isExport);
double xscale = 1.0;
double yscale = 1.0;
if (!m_filename.empty()) {
filename = m_filename;
}
else {
base::paths exts = get_writable_extensions();
filename = document->filename();
filename = initialFilename;
again:;
base::paths newfilename;
if (!app::show_file_selector(
dlgTitle, filename, exts,
FileSelectorType::Save, newfilename,
delegate))
return false;
FileSelectorType::Save,
newfilename))
return std::string();
filename = newfilename.front();
if (!forbiddenFilename.empty() &&
@ -211,110 +143,29 @@ bool SaveFileBaseCommand::saveAsDialog(
ui::Alert::show(Strings::alerts_cannot_file_overwrite_on_export());
goto again;
}
if (delegate &&
delegate->hasResizeCombobox()) {
xscale = yscale = delegate->getResizeScale();
}
}
std::string oldFilename;
{
ContextWriter writer(context);
Document* documentWriter = writer.document();
oldFilename = documentWriter->filename();
// Change the document file name
documentWriter->setFilename(filename.c_str());
m_selectedFilename = filename;
if (saveInBackground) {
saveDocumentInBackground(
context, document,
filename, markAsSaved);
}
// Pixel ratio
if (delegate &&
delegate->applyPixelRatio()) {
doc::PixelRatio pr = delegate->pixelRatio();
xscale *= pr.w;
yscale *= pr.h;
}
// Apply scale
bool undoResize = false;
if (xscale != 1.0 || yscale != 1.0) {
Command* resizeCmd = Commands::instance()->byId(CommandId::SpriteSize());
ASSERT(resizeCmd);
if (resizeCmd) {
int width = document->sprite()->width();
int height = document->sprite()->height();
int newWidth = int(double(width) * xscale);
int newHeight = int(double(height) * yscale);
if (newWidth < 1) newWidth = 1;
if (newHeight < 1) newHeight = 1;
if (width != newWidth || height != newHeight) {
Params params;
params.set("use-ui", "false");
params.set("width", base::convert_to<std::string>(newWidth).c_str());
params.set("height", base::convert_to<std::string>(newHeight).c_str());
params.set("resize-method", "nearest-neighbor"); // TODO add algorithm in the UI?
context->executeCommand(resizeCmd, params);
undoResize = true;
}
}
}
{
RestoreVisibleLayers layersVisibility;
if (delegate) {
Site site = context->activeSite();
// Selected layers to export
calculate_visible_layers(site,
delegate->getLayers(),
layersVisibility);
// Selected frames to export
SelectedFrames selFrames;
FrameTag* frameTag = calculate_selected_frames(
site, delegate->getFrames(), selFrames);
if (frameTag)
m_frameTag = frameTag->name();
m_selFrames = selFrames;
m_adjustFramesByFrameTag = false;
}
// Save the document
saveDocumentInBackground(context, const_cast<Document*>(document), markAsSaved);
}
// Undo resize
if (undoResize) {
Command* undoCmd = Commands::instance()->byId(CommandId::Undo());
if (undoCmd)
context->executeCommand(undoCmd);
}
{
ContextWriter writer(context);
Document* documentWriter = writer.document();
if (document->isModified())
documentWriter->setFilename(oldFilename);
else
documentWriter->incrementVersion();
}
return true;
return filename;
}
void SaveFileBaseCommand::saveDocumentInBackground(const Context* context,
const app::Document* document,
bool markAsSaved) const
void SaveFileBaseCommand::saveDocumentInBackground(
const Context* context,
app::Document* document,
const std::string& filename,
const bool markAsSaved) const
{
base::UniquePtr<FileOp> fop(
FileOp::createSaveDocumentOperation(
context,
FileOpROI(document, m_slice, m_frameTag,
m_selFrames, m_adjustFramesByFrameTag),
document->filename(),
filename,
m_filenameFormat));
if (!fop)
return;
@ -328,20 +179,22 @@ void SaveFileBaseCommand::saveDocumentInBackground(const Context* context,
// We don't know if the file was saved correctly or not. So mark
// it as it should be saved again.
const_cast<Document*>(document)->impossibleToBackToSavedState();
document->impossibleToBackToSavedState();
}
// If the job was cancelled, mark the document as modified.
else if (fop->isStop()) {
const_cast<Document*>(document)->impossibleToBackToSavedState();
document->impossibleToBackToSavedState();
}
else if (context->isUIAvailable()) {
App::instance()->recentFiles()->addRecentFile(document->filename().c_str());
if (markAsSaved)
const_cast<Document*>(document)->markAsSaved();
App::instance()->recentFiles()->addRecentFile(filename);
if (markAsSaved) {
document->markAsSaved();
document->setFilename(filename);
document->incrementVersion();
}
StatusBar::instance()
->setStatusText(2000, "File %s, saved.",
document->name().c_str());
->setStatusText(2000, "File <%s> saved.",
base::get_file_name(filename).c_str());
}
}
@ -373,13 +226,16 @@ void SaveFileCommand::onExecute(Context* context)
const ContextReader reader(context);
const Document* documentReader = reader.document();
saveDocumentInBackground(context, documentReader, true);
saveDocumentInBackground(
context, document,
documentReader->filename(), true);
}
// If the document isn't associated to a file, we must to show the
// save-as dialog to the user to select for first time the file-name
// for this document.
else {
saveAsDialog(context, "Save File");
saveAsDialog(context, "Save File",
document->filename(), true);
}
}
@ -399,7 +255,9 @@ SaveFileAsCommand::SaveFileAsCommand()
void SaveFileAsCommand::onExecute(Context* context)
{
saveAsDialog(context, "Save As");
Document* document = context->activeDocument();
saveAsDialog(context, "Save As",
document->filename(), true);
}
class SaveFileCopyAsCommand : public SaveFileBaseCommand {
@ -418,46 +276,86 @@ SaveFileCopyAsCommand::SaveFileCopyAsCommand()
void SaveFileCopyAsCommand::onExecute(Context* context)
{
const Document* document = context->activeDocument();
std::string oldFilename = document->filename();
Document* doc = context->activeDocument();
ExportFileWindow win(doc);
// show "Save As" dialog
DocumentPreferences& docPref = Preferences::instance().document(document);
win.SelectOutputFile.connect(
[this, &win, context, doc]{
return saveAsDialog(
context, "Export",
win.outputFilenameValue(), false, false,
(doc->isAssociatedToFile() ? doc->filename():
std::string()));
});
base::UniquePtr<SaveAsCopyDelegate> delegate;
if (context->isUIAvailable()) {
delegate.reset(
new SaveAsCopyDelegate(
document->sprite(),
docPref.saveCopy.resizeScale(),
docPref.saveCopy.layer(),
docPref.saveCopy.frameTag(),
docPref.saveCopy.applyPixelRatio()));
if (!win.show())
return;
// Save the preferences used to export the file, so if we open the
// window again, we will have the same options.
win.savePref();
double xscale, yscale;
xscale = yscale = win.resizeValue();
// Pixel ratio
if (win.applyPixelRatio()) {
doc::PixelRatio pr = doc->sprite()->pixelRatio();
xscale *= pr.w;
yscale *= pr.h;
}
// Is a default output filename in the preferences?
if (!docPref.saveCopy.filename().empty()) {
ContextWriter writer(context);
writer.document()->setFilename(
docPref.saveCopy.filename());
}
if (saveAsDialog(context, "Export",
(document->isAssociatedToFile() ? oldFilename: std::string()),
delegate)) {
docPref.saveCopy.filename(document->filename());
if (delegate) {
docPref.saveCopy.resizeScale(delegate->getResizeScale());
docPref.saveCopy.layer(delegate->getLayers());
docPref.saveCopy.frameTag(delegate->getFrames());
docPref.saveCopy.applyPixelRatio(delegate->applyPixelRatio());
// Apply scale
bool undoResize = false;
if (xscale != 1.0 || yscale != 1.0) {
Command* resizeCmd = Commands::instance()->byId(CommandId::SpriteSize());
ASSERT(resizeCmd);
if (resizeCmd) {
int width = doc->sprite()->width();
int height = doc->sprite()->height();
int newWidth = int(double(width) * xscale);
int newHeight = int(double(height) * yscale);
if (newWidth < 1) newWidth = 1;
if (newHeight < 1) newHeight = 1;
if (width != newWidth || height != newHeight) {
Params params;
params.set("use-ui", "false");
params.set("width", base::convert_to<std::string>(newWidth).c_str());
params.set("height", base::convert_to<std::string>(newHeight).c_str());
params.set("resize-method", "nearest-neighbor"); // TODO add algorithm in the UI?
context->executeCommand(resizeCmd, params);
undoResize = true;
}
}
}
// Restore the file name.
{
ContextWriter writer(context);
writer.document()->setFilename(oldFilename.c_str());
RestoreVisibleLayers layersVisibility;
Site site = context->activeSite();
// Selected layers to export
calculate_visible_layers(site,
win.layersValue(),
layersVisibility);
// Selected frames to export
SelectedFrames selFrames;
FrameTag* frameTag = calculate_selected_frames(
site, win.framesValue(), selFrames);
if (frameTag)
m_frameTag = frameTag->name();
m_selFrames = selFrames;
m_adjustFramesByFrameTag = false;
saveDocumentInBackground(
context, doc, win.outputFilenameValue(), false);
}
// Undo resize
if (undoResize) {
Command* undoCmd = Commands::instance()->byId(CommandId::Undo());
if (undoCmd)
context->executeCommand(undoCmd);
}
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -15,31 +15,30 @@
namespace app {
class Document;
class FileSelectorDelegate;
class SaveFileBaseCommand : public Command {
public:
SaveFileBaseCommand(const char* id, CommandFlags flags);
std::string selectedFilename() const {
return m_selectedFilename;
}
protected:
void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override;
bool saveAsDialog(Context* context,
const std::string& dlgTitle,
const std::string& forbiddenFilename = std::string(),
FileSelectorDelegate* delegate = nullptr);
void saveDocumentInBackground(const Context* context,
const app::Document* document,
bool markAsSaved) const;
std::string saveAsDialog(
Context* context,
const std::string& dlgTitle,
const std::string& filename,
const bool markAsSaved,
const bool saveInBackground = true,
const std::string& forbiddenFilename = std::string());
void saveDocumentInBackground(
const Context* context,
app::Document* document,
const std::string& filename,
const bool markAsSaved) const;
std::string m_filename;
std::string m_filenameFormat;
std::string m_selectedFilename;
std::string m_frameTag;
std::string m_slice;
doc::SelectedFrames m_selFrames;

View File

@ -24,8 +24,7 @@ bool show_file_selector(
const std::string& initialPath,
const base::paths& extensions,
FileSelectorType type,
base::paths& output,
FileSelectorDelegate* delegate)
base::paths& output)
{
const std::string defExtension =
Preferences::instance().saveFile.defaultExtension();
@ -71,7 +70,7 @@ bool show_file_selector(
}
}
FileSelector fileSelector(type, delegate);
FileSelector fileSelector(type);
if (!defExtension.empty())
fileSelector.setDefaultExtension(defExtension);

View File

@ -21,34 +21,12 @@ namespace app {
enum class FileSelectorType { Open, OpenMultiple, Save };
class FileSelectorDelegate {
public:
virtual ~FileSelectorDelegate() { }
virtual bool hasResizeCombobox() = 0;
virtual double getResizeScale() = 0;
virtual void setResizeScale(double scale) = 0;
// TODO refactor this to avoid using a ui::ComboBox,
// mainly to re-use this in the native file selector
virtual void fillLayersComboBox(ui::ComboBox* layers) = 0;
virtual void fillFramesComboBox(ui::ComboBox* frames) = 0;
virtual std::string getLayers() = 0;
virtual std::string getFrames() = 0;
virtual void setLayers(const std::string& layers) = 0;
virtual void setFrames(const std::string& frames) = 0;
virtual void setApplyPixelRatio(bool applyPixelRatio) = 0;
virtual bool applyPixelRatio() const = 0;
virtual doc::PixelRatio pixelRatio() = 0;
};
bool show_file_selector(
const std::string& title,
const std::string& initialPath,
const base::paths& extensions,
FileSelectorType type,
base::paths& output,
FileSelectorDelegate* delegate = nullptr);
base::paths& output);
} // namespace app

View File

@ -0,0 +1,96 @@
// Aseprite
// Copyright (C) 2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/ui/export_file_window.h"
#include "app/document.h"
#include "app/ui/layer_frame_comboboxes.h"
#include "base/bind.h"
#include "base/convert_to.h"
#include "base/fs.h"
namespace app {
ExportFileWindow::ExportFileWindow(const Document* doc)
: m_doc(doc)
, m_docPref(Preferences::instance().document(doc))
{
// Is a default output filename in the preferences?
if (!m_docPref.saveCopy.filename().empty()) {
outputFilename()->setText(m_docPref.saveCopy.filename());
}
else {
std::string newFn = base::replace_extension(
doc->filename(),
doc->sprite()->totalFrames() > 1 ? "gif": "png");
if (newFn == doc->filename()) {
newFn = base::join_path(
base::get_file_path(newFn),
base::get_file_title(newFn) + "-export." + base::get_file_extension(newFn));
}
outputFilename()->setText(newFn);
}
// Default export configuration
resize()->setValue(
base::convert_to<std::string>(m_docPref.saveCopy.resizeScale()));
fill_layers_combobox(m_doc->sprite(), layers(), m_docPref.saveCopy.layer());
fill_frames_combobox(m_doc->sprite(), frames(), m_docPref.saveCopy.frameTag());
pixelRatio()->setSelected(m_docPref.saveCopy.applyPixelRatio());
outputFilename()->Click.connect(base::Bind<void>(
[this]{
std::string fn = SelectOutputFile();
if (!fn.empty())
outputFilename()->setText(fn);
}));
}
bool ExportFileWindow::show()
{
openWindowInForeground();
return (closer() == ok());
}
void ExportFileWindow::savePref()
{
m_docPref.saveCopy.filename(outputFilenameValue());
m_docPref.saveCopy.resizeScale(resizeValue());
m_docPref.saveCopy.layer(layersValue());
m_docPref.saveCopy.frameTag(framesValue());
m_docPref.saveCopy.applyPixelRatio(applyPixelRatio());
}
std::string ExportFileWindow::outputFilenameValue() const
{
return outputFilename()->text();
}
double ExportFileWindow::resizeValue() const
{
return base::convert_to<double>(resize()->getValue());
}
std::string ExportFileWindow::layersValue() const
{
return layers()->getValue();
}
std::string ExportFileWindow::framesValue() const
{
return frames()->getValue();
}
bool ExportFileWindow::applyPixelRatio() const
{
return pixelRatio()->isSelected();
}
} // namespace app

View File

@ -0,0 +1,43 @@
// Aseprite
// Copyright (C) 2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_UI_EXPORT_FILE_WINDOW_H_INCLUDED
#define APP_UI_EXPORT_FILE_WINDOW_H_INCLUDED
#pragma once
#include "app/pref/preferences.h"
#include "obs/signal.h"
#include "export_file.xml.h"
#include <string>
namespace app {
class Document;
class ExportFileWindow : protected app::gen::ExportFile {
public:
ExportFileWindow(const Document* doc);
bool show();
void savePref();
std::string outputFilenameValue() const;
double resizeValue() const;
std::string layersValue() const;
std::string framesValue() const;
bool applyPixelRatio() const;
obs::signal<std::string()> SelectOutputFile;
private:
const Document* m_doc;
DocumentPreferences& m_docPref;
};
}
#endif

View File

@ -261,90 +261,10 @@ private:
FileSelector* m_filesel;
};
class FileSelector::ExtrasWindow : public PopupWindow {
public:
ExtrasWindow(FileSelectorDelegate* delegate)
: PopupWindow("",
ClickBehavior::CloseOnClickInOtherWindow,
EnterBehavior::CloseOnEnter)
, m_delegate(delegate)
, m_extras(new gen::FileSelectorExtras) {
setAutoRemap(false);
setBorder(gfx::Border(4*guiscale()));
addChild(m_extras);
m_extras->resize()->setValue(
base::convert_to<std::string>(m_delegate->getResizeScale()));
m_delegate->fillLayersComboBox(m_extras->layers());
m_delegate->fillFramesComboBox(m_extras->frames());
m_extras->pixelRatio()->setSelected(m_delegate->applyPixelRatio());
m_extras->resize()->Change.connect(&ExtrasWindow::onUpdateExtras, this);
m_extras->layers()->Change.connect(&ExtrasWindow::onUpdateExtras, this);
m_extras->frames()->Change.connect(&ExtrasWindow::onUpdateExtras, this);
m_extras->pixelRatio()->Click.connect(base::Bind<void>(&ExtrasWindow::onUpdateExtras, this));
}
std::string extrasLabel() const {
std::string label = "Resize: " + m_extras->resize()->getSelectedItem()->text();
auto layerItem = dynamic_cast<ListItem*>(m_extras->layers()->getSelectedItem());
if (layerItem &&
!layerItem->getValue().empty())
label += ", " + layerItem->text();
auto frameItem = dynamic_cast<ListItem*>(m_extras->frames()->getSelectedItem());
if (frameItem && !frameItem->getValue().empty())
label += ", " + frameItem->text();
if (m_extras->pixelRatio()->isSelected()) {
PixelRatio pr = m_delegate->pixelRatio();
label += " (";
label += base::convert_to<std::string>(pr.w);
label += ":";
label += base::convert_to<std::string>(pr.h);
label += ")";
}
return label;
}
double resizeValue() const {
return base::convert_to<double>(m_extras->resize()->getValue());
}
std::string layersValue() const {
return m_extras->layers()->getValue();
}
std::string framesValue() const {
return m_extras->frames()->getValue();
}
bool applyPixelRatio() const {
return m_extras->pixelRatio()->isSelected();
}
obs::signal<void()> UpdateExtras;
private:
void onUpdateExtras() {
UpdateExtras();
}
FileSelectorDelegate* m_delegate;
gen::FileSelectorExtras* m_extras;
};
FileSelector::FileSelector(FileSelectorType type, FileSelectorDelegate* delegate)
FileSelector::FileSelector(FileSelectorType type)
: m_type(type)
, m_delegate(delegate)
, m_extras(nullptr)
, m_navigationLocked(false)
{
bool withResizeOptions = (delegate && delegate->hasResizeCombobox());
addChild(new ArrowNavigator(this));
m_fileName = new CustomFileNameEntry;
@ -374,15 +294,6 @@ FileSelector::FileSelector(FileSelectorType type, FileSelectorDelegate* delegate
m_fileList->FileSelected.connect(base::Bind<void>(&FileSelector::onFileListFileSelected, this));
m_fileList->FileAccepted.connect(base::Bind<void>(&FileSelector::onFileListFileAccepted, this));
m_fileList->CurrentFolderChanged.connect(base::Bind<void>(&FileSelector::onFileListCurrentFolderChanged, this));
if (withResizeOptions) {
extraOptions()->Click.connect(base::Bind<void>(&FileSelector::onExtraOptions, this));
m_extras = new ExtrasWindow(m_delegate);
m_extras->UpdateExtras.connect(base::Bind<void>(&FileSelector::updateExtraLabel, this));
}
updateExtraLabel();
}
void FileSelector::setDefaultExtension(const std::string& extension)
@ -392,7 +303,6 @@ void FileSelector::setDefaultExtension(const std::string& extension)
FileSelector::~FileSelector()
{
delete m_extras;
}
void FileSelector::goBack()
@ -722,15 +632,6 @@ again:
std::string lastpath = folder->keyName();
set_config_string("FileSelect", "CurrentDirectory",
lastpath.c_str());
if (m_delegate &&
m_delegate->hasResizeCombobox() &&
m_extras) {
m_delegate->setResizeScale(m_extras->resizeValue());
m_delegate->setLayers(m_extras->layersValue());
m_delegate->setFrames(m_extras->framesValue());
m_delegate->setApplyPixelRatio(m_extras->applyPixelRatio());
}
}
return (!output.empty());
@ -995,18 +896,6 @@ void FileSelector::onFileListCurrentFolderChanged()
m_fileName->closeListBox();
}
void FileSelector::onExtraOptions()
{
ASSERT(m_extras);
m_extras->remapWindow();
gfx::Rect bounds = m_extras->bounds();
ui::fit_bounds(BOTTOM, extraOptions()->bounds(), bounds);
m_extras->moveWindow(bounds);
m_extras->openWindow();
}
std::string FileSelector::getSelectedExtension() const
{
auto selExtItem = dynamic_cast<CustomFileExtensionItem*>(fileType()->getSelectedItem());
@ -1016,20 +905,4 @@ std::string FileSelector::getSelectedExtension() const
return m_defExtension;
}
void FileSelector::updateExtraLabel()
{
if (!m_extras) {
extraOptions()->setVisible(false);
return;
}
extraOptions()->setVisible(true);
std::string newLabel = m_extras->extrasLabel();
if (extraOptions()->text() != newLabel) {
extraOptions()->setText(newLabel);
extraOptions()->window()->layout();
}
}
} // namespace app

View File

@ -29,7 +29,7 @@ namespace app {
class FileSelector : public app::gen::FileSelector {
public:
FileSelector(FileSelectorType type, FileSelectorDelegate* delegate);
FileSelector(FileSelectorType type);
~FileSelector();
void setDefaultExtension(const std::string& extension);
@ -58,24 +58,19 @@ namespace app {
void onFileListFileSelected();
void onFileListFileAccepted();
void onFileListCurrentFolderChanged();
void onExtraOptions();
std::string getSelectedExtension() const;
void updateExtraLabel();
class ArrowNavigator;
class CustomFileNameItem;
class CustomFolderNameItem;
class CustomFileNameEntry;
class CustomFileExtensionItem;
class ExtrasWindow;
FileSelectorType m_type;
FileSelectorDelegate* m_delegate;
std::string m_defExtension;
CustomFileNameEntry* m_fileName;
FileList* m_fileList;
FileListView* m_fileView;
ExtrasWindow* m_extras;
// If true the navigation_history isn't
// modified if the current folder changes