mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-29 19:20:09 +00:00
Merge branch 'master' into beta
This commit is contained in:
commit
396f5fb78f
14
data/gui.xml
14
data/gui.xml
@ -205,7 +205,8 @@
|
|||||||
</key>
|
</key>
|
||||||
|
|
||||||
<!-- Zoom -->
|
<!-- Zoom -->
|
||||||
<key command="Zoom" shortcut="~"><param name="percentage" value="50" /></key>
|
<key command="Zoom" shortcut="~"><param name="percentage" value="50" /></key> <!-- US PC -->
|
||||||
|
<key command="Zoom" shortcut="`"><param name="percentage" value="50" /></key> <!-- US Mac -->
|
||||||
<key command="Zoom" shortcut="1"><param name="percentage" value="100" /></key>
|
<key command="Zoom" shortcut="1"><param name="percentage" value="100" /></key>
|
||||||
<key command="Zoom" shortcut="2"><param name="percentage" value="200" /></key>
|
<key command="Zoom" shortcut="2"><param name="percentage" value="200" /></key>
|
||||||
<key command="Zoom" shortcut="3"><param name="percentage" value="400" /></key>
|
<key command="Zoom" shortcut="3"><param name="percentage" value="400" /></key>
|
||||||
@ -226,6 +227,17 @@
|
|||||||
<param name="action" value="in" />
|
<param name="action" value="in" />
|
||||||
</key>
|
</key>
|
||||||
|
|
||||||
|
<!-- Layer opacity -->
|
||||||
|
<key command="LayerOpacity"><param name="opacity" value="0" /></key>
|
||||||
|
<key command="LayerOpacity"><param name="opacity" value="32" /></key>
|
||||||
|
<key command="LayerOpacity" shortcut="Shift+1"><param name="opacity" value="64" /></key>
|
||||||
|
<key command="LayerOpacity"><param name="opacity" value="96" /></key>
|
||||||
|
<key command="LayerOpacity" shortcut="Shift+2"><param name="opacity" value="128" /></key>
|
||||||
|
<key command="LayerOpacity"><param name="opacity" value="160" /></key>
|
||||||
|
<key command="LayerOpacity" shortcut="Shift+3"><param name="opacity" value="192" /></key>
|
||||||
|
<key command="LayerOpacity"><param name="opacity" value="224" /></key>
|
||||||
|
<key command="LayerOpacity" shortcut="Shift+4"><param name="opacity" value="255" /></key>
|
||||||
|
|
||||||
<!-- Scroll to center -->
|
<!-- Scroll to center -->
|
||||||
<key command="ScrollCenter" shortcut="Shift+C" />
|
<key command="ScrollCenter" shortcut="Shift+C" />
|
||||||
<key command="FitScreen" shortcut="Ctrl+0" mac="Cmd+0" />
|
<key command="FitScreen" shortcut="Ctrl+0" mac="Cmd+0" />
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
<value id="PICK_FGCOLOR" value="1" />
|
<value id="PICK_FGCOLOR" value="1" />
|
||||||
<value id="ERASE" value="2" />
|
<value id="ERASE" value="2" />
|
||||||
<value id="SCROLL" value="3" />
|
<value id="SCROLL" value="3" />
|
||||||
|
<value id="RECTANGULAR_MARQUEE" value="4" />
|
||||||
|
<value id="LASSO" value="5" />
|
||||||
</enum>
|
</enum>
|
||||||
<enum id="OnionskinType">
|
<enum id="OnionskinType">
|
||||||
<value id="MERGE" value="0" />
|
<value id="MERGE" value="0" />
|
||||||
@ -117,6 +119,7 @@
|
|||||||
<option id="right_click_mode" type="RightClickMode" default="RightClickMode::PAINT_BGCOLOR" migrate="Options.RightClickMode" />
|
<option id="right_click_mode" type="RightClickMode" default="RightClickMode::PAINT_BGCOLOR" migrate="Options.RightClickMode" />
|
||||||
<option id="auto_select_layer" type="bool" default="false" migrate="Options.AutoSelectLayer" />
|
<option id="auto_select_layer" type="bool" default="false" migrate="Options.AutoSelectLayer" />
|
||||||
<option id="play_once" type="bool" default="false" />
|
<option id="play_once" type="bool" default="false" />
|
||||||
|
<option id="play_all" type="bool" default="false" />
|
||||||
</section>
|
</section>
|
||||||
<section id="cursor">
|
<section id="cursor">
|
||||||
<option id="use_native_cursor" type="bool" default="false" migrate="experimental.use_native_cursor" />
|
<option id="use_native_cursor" type="bool" default="false" migrate="experimental.use_native_cursor" />
|
||||||
@ -127,6 +130,7 @@
|
|||||||
</section>
|
</section>
|
||||||
<section id="preview" text="Preview">
|
<section id="preview" text="Preview">
|
||||||
<option id="play_once" type="bool" default="false" />
|
<option id="play_once" type="bool" default="false" />
|
||||||
|
<option id="play_all" type="bool" default="false" />
|
||||||
</section>
|
</section>
|
||||||
<section id="theme" text="Theme">
|
<section id="theme" text="Theme">
|
||||||
<option id="selected" type="std::string" default=""default"" migrate="Skin.Selected" />
|
<option id="selected" type="std::string" default=""default"" migrate="Skin.Selected" />
|
||||||
|
@ -231,6 +231,7 @@ add_library(app-lib
|
|||||||
commands/cmd_keyboard_shortcuts.cpp
|
commands/cmd_keyboard_shortcuts.cpp
|
||||||
commands/cmd_launch.cpp
|
commands/cmd_launch.cpp
|
||||||
commands/cmd_layer_from_background.cpp
|
commands/cmd_layer_from_background.cpp
|
||||||
|
commands/cmd_layer_opacity.cpp
|
||||||
commands/cmd_layer_properties.cpp
|
commands/cmd_layer_properties.cpp
|
||||||
commands/cmd_layer_visibility.cpp
|
commands/cmd_layer_visibility.cpp
|
||||||
commands/cmd_link_cels.cpp
|
commands/cmd_link_cels.cpp
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
#include "app/app_menus.h"
|
#include "app/app_menus.h"
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/context.h"
|
#include "app/context.h"
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
#include "app/tools/tool.h"
|
#include "app/tools/tool.h"
|
||||||
|
#include "app/tools/tool_box.h"
|
||||||
#include "app/ui/app_menuitem.h"
|
#include "app/ui/app_menuitem.h"
|
||||||
#include "app/ui/keyboard_shortcuts.h"
|
#include "app/ui/keyboard_shortcuts.h"
|
||||||
#include "app/ui/search_entry.h"
|
#include "app/ui/search_entry.h"
|
||||||
@ -38,8 +40,9 @@
|
|||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
|
||||||
using namespace skin;
|
using namespace skin;
|
||||||
|
using namespace tools;
|
||||||
|
using namespace ui;
|
||||||
|
|
||||||
static int g_sep = 0;
|
static int g_sep = 0;
|
||||||
|
|
||||||
@ -410,7 +413,13 @@ private:
|
|||||||
|
|
||||||
// Load keyboard shortcuts
|
// Load keyboard shortcuts
|
||||||
fillList(this->menus(), AppMenus::instance()->getRootMenu(), 0);
|
fillList(this->menus(), AppMenus::instance()->getRootMenu(), 0);
|
||||||
|
fillList(this->tools(), App::instance()->toolBox());
|
||||||
for (Key* key : *app::KeyboardShortcuts::instance()) {
|
for (Key* key : *app::KeyboardShortcuts::instance()) {
|
||||||
|
if (key->type() == KeyType::Tool ||
|
||||||
|
key->type() == KeyType::Quicktool) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::string text = key->triggerString();
|
std::string text = key->triggerString();
|
||||||
switch (key->keycontext()) {
|
switch (key->keycontext()) {
|
||||||
case KeyContext::SelectionTool:
|
case KeyContext::SelectionTool:
|
||||||
@ -437,16 +446,11 @@ private:
|
|||||||
}
|
}
|
||||||
KeyItem* keyItem = new KeyItem(text, key, NULL, 0);
|
KeyItem* keyItem = new KeyItem(text, key, NULL, 0);
|
||||||
|
|
||||||
ListBox* listBox = NULL;
|
ListBox* listBox = nullptr;
|
||||||
switch (key->type()) {
|
switch (key->type()) {
|
||||||
case KeyType::Command:
|
case KeyType::Command:
|
||||||
listBox = this->commands();
|
listBox = this->commands();
|
||||||
break;
|
break;
|
||||||
case KeyType::Tool:
|
|
||||||
case KeyType::Quicktool: {
|
|
||||||
listBox = this->tools();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case KeyType::Action:
|
case KeyType::Action:
|
||||||
listBox = this->actions();
|
listBox = this->actions();
|
||||||
break;
|
break;
|
||||||
@ -608,6 +612,23 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fillList(ListBox* listbox, ToolBox* toolbox) {
|
||||||
|
for (Tool* tool : *toolbox) {
|
||||||
|
std::string text = tool->getText();
|
||||||
|
|
||||||
|
Key* key = app::KeyboardShortcuts::instance()->tool(tool);
|
||||||
|
KeyItem* keyItem = new KeyItem(text, key, nullptr, 0);
|
||||||
|
m_allKeyItems.push_back(keyItem);
|
||||||
|
listbox->addChild(keyItem);
|
||||||
|
|
||||||
|
text += " (quick)";
|
||||||
|
key = app::KeyboardShortcuts::instance()->quicktool(tool);
|
||||||
|
keyItem = new KeyItem(text, key, nullptr, 0);
|
||||||
|
m_allKeyItems.push_back(keyItem);
|
||||||
|
listbox->addChild(keyItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<KeyItem*> m_allKeyItems;
|
std::vector<KeyItem*> m_allKeyItems;
|
||||||
bool m_searchChange;
|
bool m_searchChange;
|
||||||
};
|
};
|
||||||
|
110
src/app/commands/cmd_layer_opacity.cpp
Normal file
110
src/app/commands/cmd_layer_opacity.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2016 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/app.h"
|
||||||
|
#include "app/cmd/set_layer_opacity.h"
|
||||||
|
#include "app/commands/command.h"
|
||||||
|
#include "app/commands/params.h"
|
||||||
|
#include "app/context.h"
|
||||||
|
#include "app/context_access.h"
|
||||||
|
#include "app/modules/gui.h"
|
||||||
|
#include "app/transaction.h"
|
||||||
|
#include "app/ui/timeline.h"
|
||||||
|
#include "base/convert_to.h"
|
||||||
|
#include "doc/layer.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
class LayerOpacityCommand : public Command {
|
||||||
|
public:
|
||||||
|
LayerOpacityCommand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onLoadParams(const Params& params) override;
|
||||||
|
bool onEnabled(Context* context) override;
|
||||||
|
void onExecute(Context* context) override;
|
||||||
|
std::string onGetFriendlyName() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_opacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
LayerOpacityCommand::LayerOpacityCommand()
|
||||||
|
: Command("LayerOpacity",
|
||||||
|
"Layer Opacity",
|
||||||
|
CmdUIOnlyFlag)
|
||||||
|
{
|
||||||
|
m_opacity = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerOpacityCommand::onLoadParams(const Params& params)
|
||||||
|
{
|
||||||
|
m_opacity = params.get_as<int>("opacity");
|
||||||
|
m_opacity = MID(0, m_opacity, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayerOpacityCommand::onEnabled(Context* context)
|
||||||
|
{
|
||||||
|
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||||
|
ContextFlags::HasActiveLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerOpacityCommand::onExecute(Context* context)
|
||||||
|
{
|
||||||
|
ContextWriter writer(context);
|
||||||
|
Layer* layer = writer.layer();
|
||||||
|
if (!layer ||
|
||||||
|
!layer->isImage() ||
|
||||||
|
static_cast<LayerImage*>(layer)->opacity() == m_opacity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
Transaction transaction(writer.context(), "Set Layer Opacity");
|
||||||
|
|
||||||
|
// TODO the range of selected frames should be in doc::Site.
|
||||||
|
SelectedLayers selLayers;
|
||||||
|
auto range = App::instance()->timeline()->range();
|
||||||
|
if (range.enabled()) {
|
||||||
|
selLayers = range.selectedLayers();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selLayers.insert(writer.layer());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto layer : selLayers) {
|
||||||
|
if (layer->isImage())
|
||||||
|
transaction.execute(
|
||||||
|
new cmd::SetLayerOpacity(static_cast<LayerImage*>(layer), m_opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
update_screen_for_document(writer.document());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LayerOpacityCommand::onGetFriendlyName() const
|
||||||
|
{
|
||||||
|
std::string text = "Set Layer Opacity to ";
|
||||||
|
text += base::convert_to<std::string>(m_opacity);
|
||||||
|
text += " (";
|
||||||
|
text += base::convert_to<std::string>(int(100.0 * m_opacity / 255.0));
|
||||||
|
text += "%)";
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command* CommandFactory::createLayerOpacityCommand()
|
||||||
|
{
|
||||||
|
return new LayerOpacityCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
@ -187,10 +187,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Right-click
|
// Right-click
|
||||||
|
|
||||||
|
static_assert(int(app::gen::RightClickMode::PAINT_BGCOLOR) == 0, "");
|
||||||
|
static_assert(int(app::gen::RightClickMode::PICK_FGCOLOR) == 1, "");
|
||||||
|
static_assert(int(app::gen::RightClickMode::ERASE) == 2, "");
|
||||||
|
static_assert(int(app::gen::RightClickMode::SCROLL) == 3, "");
|
||||||
|
static_assert(int(app::gen::RightClickMode::RECTANGULAR_MARQUEE) == 4, "");
|
||||||
|
static_assert(int(app::gen::RightClickMode::LASSO) == 5, "");
|
||||||
|
|
||||||
rightClickBehavior()->addItem("Paint with background color");
|
rightClickBehavior()->addItem("Paint with background color");
|
||||||
rightClickBehavior()->addItem("Pick foreground color");
|
rightClickBehavior()->addItem("Pick foreground color");
|
||||||
rightClickBehavior()->addItem("Erase");
|
rightClickBehavior()->addItem("Erase");
|
||||||
rightClickBehavior()->addItem("Scroll");
|
rightClickBehavior()->addItem("Scroll");
|
||||||
|
rightClickBehavior()->addItem("Rectangular Marquee");
|
||||||
|
rightClickBehavior()->addItem("Lasso");
|
||||||
rightClickBehavior()->setSelectedItemIndex((int)m_pref.editor.rightClickMode());
|
rightClickBehavior()->setSelectedItemIndex((int)m_pref.editor.rightClickMode());
|
||||||
|
|
||||||
// Zoom with Scroll Wheel
|
// Zoom with Scroll Wheel
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -51,10 +51,9 @@ void PaletteSizeCommand::onLoadParams(const Params& params)
|
|||||||
|
|
||||||
void PaletteSizeCommand::onExecute(Context* context)
|
void PaletteSizeCommand::onExecute(Context* context)
|
||||||
{
|
{
|
||||||
ContextWriter writer(context);
|
ContextReader reader(context);
|
||||||
Sprite* sprite = writer.sprite();
|
frame_t frame = reader.frame();
|
||||||
frame_t frame = writer.frame();
|
Palette palette(*reader.sprite()->palette(frame));
|
||||||
Palette palette(*sprite->palette(frame));
|
|
||||||
|
|
||||||
app::gen::PaletteSize window;
|
app::gen::PaletteSize window;
|
||||||
window.colors()->setTextf("%d", palette.size());
|
window.colors()->setTextf("%d", palette.size());
|
||||||
@ -66,8 +65,9 @@ void PaletteSizeCommand::onExecute(Context* context)
|
|||||||
|
|
||||||
palette.resize(MID(1, ncolors, INT_MAX));
|
palette.resize(MID(1, ncolors, INT_MAX));
|
||||||
|
|
||||||
|
ContextWriter writer(reader);
|
||||||
Transaction transaction(context, "Palette Size", ModifyDocument);
|
Transaction transaction(context, "Palette Size", ModifyDocument);
|
||||||
transaction.execute(new cmd::SetPalette(sprite, frame, &palette));
|
transaction.execute(new cmd::SetPalette(writer.sprite(), frame, &palette));
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
set_current_palette(&palette, false);
|
set_current_palette(&palette, false);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -59,7 +59,8 @@ void PlayAnimationCommand::onExecute(Context* context)
|
|||||||
if (current_editor->isPlaying())
|
if (current_editor->isPlaying())
|
||||||
current_editor->stop();
|
current_editor->stop();
|
||||||
else
|
else
|
||||||
current_editor->play(Preferences::instance().editor.playOnce());
|
current_editor->play(Preferences::instance().editor.playOnce(),
|
||||||
|
Preferences::instance().editor.playAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
Command* CommandFactory::createPlayAnimationCommand()
|
Command* CommandFactory::createPlayAnimationCommand()
|
||||||
|
@ -61,6 +61,7 @@ FOR_EACH_COMMAND(InvertMask)
|
|||||||
FOR_EACH_COMMAND(KeyboardShortcuts)
|
FOR_EACH_COMMAND(KeyboardShortcuts)
|
||||||
FOR_EACH_COMMAND(Launch)
|
FOR_EACH_COMMAND(Launch)
|
||||||
FOR_EACH_COMMAND(LayerFromBackground)
|
FOR_EACH_COMMAND(LayerFromBackground)
|
||||||
|
FOR_EACH_COMMAND(LayerOpacity)
|
||||||
FOR_EACH_COMMAND(LayerProperties)
|
FOR_EACH_COMMAND(LayerProperties)
|
||||||
FOR_EACH_COMMAND(LayerVisibility)
|
FOR_EACH_COMMAND(LayerVisibility)
|
||||||
FOR_EACH_COMMAND(LinkCels)
|
FOR_EACH_COMMAND(LinkCels)
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
#include "base/time.h"
|
#include "base/time.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace crash {
|
namespace crash {
|
||||||
|
|
||||||
@ -53,6 +55,12 @@ DataRecovery::DataRecovery(doc::Context* ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort sessions from the most recent one to the oldest one
|
||||||
|
std::sort(m_sessions.begin(), m_sessions.end(),
|
||||||
|
[](const SessionPtr& a, const SessionPtr& b) {
|
||||||
|
return a->name() > b->name();
|
||||||
|
});
|
||||||
|
|
||||||
// Create a new session
|
// Create a new session
|
||||||
base::pid pid = base::get_current_process_id();
|
base::pid pid = base::get_current_process_id();
|
||||||
std::string newSessionDir;
|
std::string newSessionDir;
|
||||||
|
@ -23,7 +23,7 @@ using namespace base;
|
|||||||
|
|
||||||
class PcxFormat : public FileFormat {
|
class PcxFormat : public FileFormat {
|
||||||
const char* onGetName() const override { return "pcx"; }
|
const char* onGetName() const override { return "pcx"; }
|
||||||
const char* onGetExtensions() const override { return "pcx"; }
|
const char* onGetExtensions() const override { return "pcx,pcc"; }
|
||||||
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::PCX_IMAGE; }
|
docio::FileFormat onGetDocioFormat() const override { return docio::FileFormat::PCX_IMAGE; }
|
||||||
int onGetFlags() const override {
|
int onGetFlags() const override {
|
||||||
return
|
return
|
||||||
|
@ -177,6 +177,14 @@ void ActiveToolManager::pressButton(const Pointer& pointer)
|
|||||||
tool = m_toolbox->getToolById(WellKnownTools::Hand);
|
tool = m_toolbox->getToolById(WellKnownTools::Hand);
|
||||||
ink = m_toolbox->getInkById(tools::WellKnownInks::Scroll);
|
ink = m_toolbox->getInkById(tools::WellKnownInks::Scroll);
|
||||||
break;
|
break;
|
||||||
|
case app::gen::RightClickMode::RECTANGULAR_MARQUEE:
|
||||||
|
tool = m_toolbox->getToolById(WellKnownTools::RectangularMarquee);
|
||||||
|
ink = m_toolbox->getInkById(tools::WellKnownInks::Selection);
|
||||||
|
break;
|
||||||
|
case app::gen::RightClickMode::LASSO:
|
||||||
|
tool = m_toolbox->getToolById(WellKnownTools::Lasso);
|
||||||
|
ink = m_toolbox->getInkById(tools::WellKnownInks::Selection);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +220,8 @@ bool ActiveToolManager::isToolAffectedByRightClickMode(Tool* tool)
|
|||||||
return
|
return
|
||||||
((tool->getInk(0)->isPaint() && !shadingMode) ||
|
((tool->getInk(0)->isPaint() && !shadingMode) ||
|
||||||
(tool->getInk(0)->isEffect())) &&
|
(tool->getInk(0)->isEffect())) &&
|
||||||
(!tool->getInk(0)->isEraser());
|
(!tool->getInk(0)->isEraser()) &&
|
||||||
|
(!tool->getInk(0)->isSelection());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tools
|
} // namespace tools
|
||||||
|
@ -42,6 +42,7 @@ namespace tools {
|
|||||||
using namespace gfx;
|
using namespace gfx;
|
||||||
|
|
||||||
const char* WellKnownTools::RectangularMarquee = "rectangular_marquee";
|
const char* WellKnownTools::RectangularMarquee = "rectangular_marquee";
|
||||||
|
const char* WellKnownTools::Lasso = "lasso";
|
||||||
const char* WellKnownTools::Pencil = "pencil";
|
const char* WellKnownTools::Pencil = "pencil";
|
||||||
const char* WellKnownTools::Eraser = "eraser";
|
const char* WellKnownTools::Eraser = "eraser";
|
||||||
const char* WellKnownTools::Eyedropper = "eyedropper";
|
const char* WellKnownTools::Eyedropper = "eyedropper";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -22,6 +22,7 @@ namespace app {
|
|||||||
|
|
||||||
namespace WellKnownTools {
|
namespace WellKnownTools {
|
||||||
extern const char* RectangularMarquee;
|
extern const char* RectangularMarquee;
|
||||||
|
extern const char* Lasso;
|
||||||
extern const char* Pencil;
|
extern const char* Pencil;
|
||||||
extern const char* Eraser;
|
extern const char* Eraser;
|
||||||
extern const char* Eyedropper;
|
extern const char* Eyedropper;
|
||||||
|
@ -112,7 +112,8 @@ void AniControls::onRightClick(Item* item)
|
|||||||
|
|
||||||
if (item == getItem(ACTION_PLAY) && current_editor)
|
if (item == getItem(ACTION_PLAY) && current_editor)
|
||||||
current_editor->showAnimationSpeedMultiplierPopup(
|
current_editor->showAnimationSpeedMultiplierPopup(
|
||||||
Preferences::instance().editor.playOnce, true);
|
Preferences::instance().editor.playOnce,
|
||||||
|
Preferences::instance().editor.playAll, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* AniControls::getCommandId(int index) const
|
const char* AniControls::getCommandId(int index) const
|
||||||
|
@ -48,7 +48,9 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ColorPopup::ColorPopup(bool canPin)
|
ColorPopup::ColorPopup(bool canPin)
|
||||||
: PopupWindowPin("Color Selector", ClickBehavior::CloseOnClickInOtherWindow)
|
: PopupWindowPin("Color Selector",
|
||||||
|
ClickBehavior::CloseOnClickInOtherWindow,
|
||||||
|
canPin)
|
||||||
, m_vbox(VERTICAL)
|
, m_vbox(VERTICAL)
|
||||||
, m_topBox(HORIZONTAL)
|
, m_topBox(HORIZONTAL)
|
||||||
, m_color(app::Color::fromMask())
|
, m_color(app::Color::fromMask())
|
||||||
@ -77,12 +79,22 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
m_topBox.addChild(&m_colorType);
|
m_topBox.addChild(&m_colorType);
|
||||||
m_topBox.addChild(new Separator("", VERTICAL));
|
m_topBox.addChild(new Separator("", VERTICAL));
|
||||||
m_topBox.addChild(&m_hexColorEntry);
|
m_topBox.addChild(&m_hexColorEntry);
|
||||||
|
|
||||||
|
// Move close button (decorative widget) inside the m_topBox
|
||||||
{
|
{
|
||||||
Box* miniVbox = new Box(VERTICAL);
|
Widget* closeButton = nullptr;
|
||||||
miniVbox->addChild(getPin());
|
WidgetsList decorators;
|
||||||
|
for (auto child : children()) {
|
||||||
|
if (child->isDecorative()) {
|
||||||
|
closeButton = child;
|
||||||
|
removeChild(child);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
m_topBox.addChild(new BoxFiller);
|
m_topBox.addChild(new BoxFiller);
|
||||||
m_topBox.addChild(miniVbox);
|
m_topBox.addChild(closeButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vbox.addChild(&m_topBox);
|
m_vbox.addChild(&m_topBox);
|
||||||
m_vbox.addChild(&m_colorPaletteContainer);
|
m_vbox.addChild(&m_colorPaletteContainer);
|
||||||
m_vbox.addChild(&m_rgbSliders);
|
m_vbox.addChild(&m_rgbSliders);
|
||||||
@ -98,9 +110,6 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||||
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
||||||
|
|
||||||
if (!m_canPin)
|
|
||||||
showPin(false);
|
|
||||||
|
|
||||||
selectColorType(app::Color::RgbType);
|
selectColorType(app::Color::RgbType);
|
||||||
setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
|
setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
|
||||||
|
|
||||||
@ -112,7 +121,6 @@ ColorPopup::ColorPopup(bool canPin)
|
|||||||
|
|
||||||
ColorPopup::~ColorPopup()
|
ColorPopup::~ColorPopup()
|
||||||
{
|
{
|
||||||
getPin()->parent()->removeChild(getPin());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorPopup::setColor(const app::Color& color, SetColorOptions options)
|
void ColorPopup::setColor(const app::Color& color, SetColorOptions options)
|
||||||
|
@ -1195,6 +1195,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setupTooltips(TooltipManager* tooltipManager) {
|
void setupTooltips(TooltipManager* tooltipManager) {
|
||||||
|
// TODO use real shortcuts in tooltips
|
||||||
tooltipManager->addTooltipFor(at(0), "Replace selection", BOTTOM);
|
tooltipManager->addTooltipFor(at(0), "Replace selection", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(at(1), "Add to selection\n(Shift)", BOTTOM);
|
tooltipManager->addTooltipFor(at(1), "Add to selection\n(Shift)", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(at(2), "Subtract from selection\n(Shift+Alt)", BOTTOM);
|
tooltipManager->addTooltipFor(at(2), "Subtract from selection\n(Shift+Alt)", BOTTOM);
|
||||||
@ -1547,7 +1548,8 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
|||||||
// target to implement this new IContextBarUser and ask for
|
// target to implement this new IContextBarUser and ask for
|
||||||
// ContextBar elements.
|
// ContextBar elements.
|
||||||
|
|
||||||
base::ScopedValue<bool> lockFlag(g_updatingFromCode, true, g_updatingFromCode);
|
const bool oldUpdatingFromCode = g_updatingFromCode;
|
||||||
|
base::ScopedValue<bool> lockFlag(g_updatingFromCode, true, oldUpdatingFromCode);
|
||||||
|
|
||||||
ToolPreferences* toolPref = nullptr;
|
ToolPreferences* toolPref = nullptr;
|
||||||
ToolPreferences::Brush* brushPref = nullptr;
|
ToolPreferences::Brush* brushPref = nullptr;
|
||||||
@ -1569,8 +1571,10 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
|||||||
m_brushType->updateBrush(tool);
|
m_brushType->updateBrush(tool);
|
||||||
|
|
||||||
if (brushPref) {
|
if (brushPref) {
|
||||||
m_brushSize->setTextf("%d", brushPref->size());
|
if (!oldUpdatingFromCode) {
|
||||||
m_brushAngle->setTextf("%d", brushPref->angle());
|
m_brushSize->setTextf("%d", brushPref->size());
|
||||||
|
m_brushAngle->setTextf("%d", brushPref->angle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_brushPatternField->setBrushPattern(
|
m_brushPatternField->setBrushPattern(
|
||||||
|
@ -25,10 +25,13 @@
|
|||||||
#include "ui/listitem.h"
|
#include "ui/listitem.h"
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
#include "ui/resize_event.h"
|
#include "ui/resize_event.h"
|
||||||
|
#include "ui/separator.h"
|
||||||
#include "ui/size_hint_event.h"
|
#include "ui/size_hint_event.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
@ -39,137 +42,61 @@ namespace {
|
|||||||
class Item : public ListItem {
|
class Item : public ListItem {
|
||||||
public:
|
public:
|
||||||
Item(crash::Session* session, crash::Session::Backup* backup)
|
Item(crash::Session* session, crash::Session::Backup* backup)
|
||||||
: ListItem(backup ? " > " + backup->description(): session->name())
|
: ListItem(backup->description())
|
||||||
, m_session(session)
|
, m_session(session)
|
||||||
, m_backup(backup)
|
, m_backup(backup)
|
||||||
, m_openButton(backup ? "Open": "Open All")
|
|
||||||
, m_deleteButton(backup ? "Delete": "Delete All")
|
|
||||||
{
|
{
|
||||||
m_hbox.setBgColor(gfx::ColorNone);
|
|
||||||
m_hbox.setTransparent(true);
|
|
||||||
m_hbox.addChild(&m_openButton);
|
|
||||||
m_hbox.addChild(&m_deleteButton);
|
|
||||||
addChild(&m_hbox);
|
|
||||||
|
|
||||||
m_openButton.Click.connect(base::Bind(&Item::onOpen, this));
|
|
||||||
m_openButton.DropDownClick.connect(base::Bind<void>(&Item::onOpenMenu, this));
|
|
||||||
m_deleteButton.Click.connect(base::Bind(&Item::onDelete, this));
|
|
||||||
|
|
||||||
setup_mini_look(&m_openButton);
|
|
||||||
setup_mini_look(&m_deleteButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obs::signal<void()> Regenerate;
|
crash::Session* session() const { return m_session; }
|
||||||
|
crash::Session::Backup* backup() const { return m_backup; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
void onSizeHint(SizeHintEvent& ev) override {
|
void onSizeHint(SizeHintEvent& ev) override {
|
||||||
gfx::Size sz = m_deleteButton.sizeHint();
|
ListItem::onSizeHint(ev);
|
||||||
|
gfx::Size sz = ev.sizeHint();
|
||||||
sz.h += 4*guiscale();
|
sz.h += 4*guiscale();
|
||||||
ev.setSizeHint(sz);
|
ev.setSizeHint(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onResize(ResizeEvent& ev) override {
|
|
||||||
ListItem::onResize(ev);
|
|
||||||
|
|
||||||
gfx::Rect rc = ev.bounds();
|
|
||||||
gfx::Size sz = m_hbox.sizeHint();
|
|
||||||
m_hbox.setBounds(
|
|
||||||
gfx::Rect(
|
|
||||||
rc.x+rc.w-sz.w-2*guiscale(), rc.y+rc.h/2-sz.h/2, sz.w, sz.h));
|
|
||||||
}
|
|
||||||
|
|
||||||
void onOpen() {
|
|
||||||
if (m_backup)
|
|
||||||
m_session->restoreBackup(m_backup);
|
|
||||||
else
|
|
||||||
for (auto backup : m_session->backups())
|
|
||||||
m_session->restoreBackup(backup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onOpenRaw(crash::RawImagesAs as) {
|
|
||||||
if (m_backup)
|
|
||||||
m_session->restoreRawImages(m_backup, as);
|
|
||||||
else
|
|
||||||
for (auto backup : m_session->backups())
|
|
||||||
m_session->restoreRawImages(backup, as);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onOpenMenu() {
|
|
||||||
gfx::Rect bounds = m_openButton.bounds();
|
|
||||||
|
|
||||||
Menu menu;
|
|
||||||
MenuItem rawFrames("Raw Images as Frames");
|
|
||||||
MenuItem rawLayers("Raw Images as Layers");
|
|
||||||
menu.addChild(&rawFrames);
|
|
||||||
menu.addChild(&rawLayers);
|
|
||||||
|
|
||||||
rawFrames.Click.connect(base::Bind(&Item::onOpenRaw, this, crash::RawImagesAs::kFrames));
|
|
||||||
rawLayers.Click.connect(base::Bind(&Item::onOpenRaw, this, crash::RawImagesAs::kLayers));
|
|
||||||
|
|
||||||
menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
|
|
||||||
}
|
|
||||||
|
|
||||||
void onDelete() {
|
|
||||||
Widget* parent = this->parent();
|
|
||||||
|
|
||||||
if (m_backup) {
|
|
||||||
// Delete one backup
|
|
||||||
if (Alert::show(PACKAGE
|
|
||||||
"<<Do you really want to delete this backup?"
|
|
||||||
"||&Yes||&No") != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_session->deleteBackup(m_backup);
|
|
||||||
|
|
||||||
Widget* parent = this->parent(); // TODO remove this line
|
|
||||||
parent->removeChild(this);
|
|
||||||
deferDelete();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Delete the whole session
|
|
||||||
if (!m_session->isEmpty()) {
|
|
||||||
if (Alert::show(PACKAGE
|
|
||||||
"<<Do you want to delete the whole session?"
|
|
||||||
"<<You will lost all backups related to this session."
|
|
||||||
"||&Yes||&No") != 1)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
crash::Session::Backups backups = m_session->backups();
|
|
||||||
for (auto backup : backups)
|
|
||||||
m_session->deleteBackup(backup);
|
|
||||||
|
|
||||||
m_session->removeFromDisk();
|
|
||||||
Regenerate();
|
|
||||||
}
|
|
||||||
|
|
||||||
parent->layout();
|
|
||||||
View::getView(parent)->updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
crash::Session* m_session;
|
crash::Session* m_session;
|
||||||
crash::Session::Backup* m_backup;
|
crash::Session::Backup* m_backup;
|
||||||
ui::HBox m_hbox;
|
|
||||||
DropDownButton m_openButton;
|
|
||||||
ui::Button m_deleteButton;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
DataRecoveryView::DataRecoveryView(crash::DataRecovery* dataRecovery)
|
DataRecoveryView::DataRecoveryView(crash::DataRecovery* dataRecovery)
|
||||||
: Box(VERTICAL)
|
: m_dataRecovery(dataRecovery)
|
||||||
, m_dataRecovery(dataRecovery)
|
, m_openButton("Recover Sprite")
|
||||||
|
, m_deleteButton("Delete")
|
||||||
{
|
{
|
||||||
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||||
setBgColor(theme->colors.workspace());
|
setBgColor(theme->colors.workspace());
|
||||||
|
|
||||||
addChild(&m_view);
|
m_openButton.mainButton()->setSizeHint(
|
||||||
|
gfx::Size(std::max(m_openButton.mainButton()->sizeHint().w, 100*guiscale()),
|
||||||
|
m_openButton.mainButton()->sizeHint().h));
|
||||||
|
|
||||||
|
m_listBox.setMultiselect(true);
|
||||||
m_view.setExpansive(true);
|
m_view.setExpansive(true);
|
||||||
m_view.attachToView(&m_listBox);
|
m_view.attachToView(&m_listBox);
|
||||||
m_view.setProperty(SkinStylePropertyPtr(new SkinStyleProperty(theme->styles.workspaceView())));
|
m_view.setProperty(SkinStylePropertyPtr(new SkinStyleProperty(theme->styles.workspaceView())));
|
||||||
|
|
||||||
|
HBox* hbox = new HBox;
|
||||||
|
hbox->setBorder(gfx::Border(2, 0, 2, 0)*guiscale());
|
||||||
|
hbox->addChild(&m_openButton);
|
||||||
|
hbox->addChild(&m_deleteButton);
|
||||||
|
addChild(hbox);
|
||||||
|
addChild(&m_view);
|
||||||
|
|
||||||
fillList();
|
fillList();
|
||||||
|
onChangeSelection();
|
||||||
|
|
||||||
|
m_openButton.Click.connect(base::Bind(&DataRecoveryView::onOpen, this));
|
||||||
|
m_openButton.DropDownClick.connect(base::Bind<void>(&DataRecoveryView::onOpenMenu, this));
|
||||||
|
m_deleteButton.Click.connect(base::Bind(&DataRecoveryView::onDelete, this));
|
||||||
|
m_listBox.Change.connect(base::Bind(&DataRecoveryView::onChangeSelection, this));
|
||||||
|
m_listBox.DoubleClickItem.connect(base::Bind(&DataRecoveryView::onOpen, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRecoveryView::~DataRecoveryView()
|
DataRecoveryView::~DataRecoveryView()
|
||||||
@ -188,13 +115,13 @@ void DataRecoveryView::fillList()
|
|||||||
if (session->isEmpty())
|
if (session->isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Item* item = new Item(session.get(), nullptr);
|
auto sep = new Separator(session->name(), HORIZONTAL);
|
||||||
item->Regenerate.connect(&DataRecoveryView::fillList, this);
|
sep->setBgColor(SkinTheme::instance()->colors.background());
|
||||||
m_listBox.addChild(item);
|
sep->setBorder(sep->border() + gfx::Border(0, 8, 0, 8)*guiscale());
|
||||||
|
m_listBox.addChild(sep);
|
||||||
|
|
||||||
for (auto& backup : session->backups()) {
|
for (auto& backup : session->backups()) {
|
||||||
item = new Item(session.get(), backup);
|
auto item = new Item(session.get(), backup);
|
||||||
item->Regenerate.connect(&DataRecoveryView::fillList, this);
|
|
||||||
m_listBox.addChild(item);
|
m_listBox.addChild(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,4 +159,101 @@ void DataRecoveryView::onTabPopup(Workspace* workspace)
|
|||||||
menu->showPopup(ui::get_mouse_position());
|
menu->showPopup(ui::get_mouse_position());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataRecoveryView::onOpen()
|
||||||
|
{
|
||||||
|
for (auto widget : m_listBox.children()) {
|
||||||
|
if (!widget->isSelected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (auto item = dynamic_cast<Item*>(widget)) {
|
||||||
|
if (item->backup())
|
||||||
|
item->session()->restoreBackup(item->backup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataRecoveryView::onOpenRaw(crash::RawImagesAs as)
|
||||||
|
{
|
||||||
|
for (auto widget : m_listBox.children()) {
|
||||||
|
if (!widget->isSelected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (auto item = dynamic_cast<Item*>(widget)) {
|
||||||
|
if (item->backup())
|
||||||
|
item->session()->restoreRawImages(item->backup(), as);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataRecoveryView::onOpenMenu()
|
||||||
|
{
|
||||||
|
gfx::Rect bounds = m_openButton.bounds();
|
||||||
|
|
||||||
|
Menu menu;
|
||||||
|
MenuItem rawFrames("Raw Images as Frames");
|
||||||
|
MenuItem rawLayers("Raw Images as Layers");
|
||||||
|
menu.addChild(&rawFrames);
|
||||||
|
menu.addChild(&rawLayers);
|
||||||
|
|
||||||
|
rawFrames.Click.connect(base::Bind(&DataRecoveryView::onOpenRaw, this, crash::RawImagesAs::kFrames));
|
||||||
|
rawLayers.Click.connect(base::Bind(&DataRecoveryView::onOpenRaw, this, crash::RawImagesAs::kLayers));
|
||||||
|
|
||||||
|
menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataRecoveryView::onDelete()
|
||||||
|
{
|
||||||
|
std::vector<Item*> items;
|
||||||
|
|
||||||
|
for (auto widget : m_listBox.children()) {
|
||||||
|
if (!widget->isSelected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (auto item = dynamic_cast<Item*>(widget)) {
|
||||||
|
if (item->backup())
|
||||||
|
items.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Delete one backup
|
||||||
|
if (Alert::show(PACKAGE
|
||||||
|
"<<Do you really want to delete the selected %d backup(s)?"
|
||||||
|
"||&Yes||&No",
|
||||||
|
int(items.size())) != 1)
|
||||||
|
return; // Cancel
|
||||||
|
|
||||||
|
for (auto item : items) {
|
||||||
|
item->session()->deleteBackup(item->backup());
|
||||||
|
m_listBox.removeChild(item);
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
onChangeSelection();
|
||||||
|
|
||||||
|
m_listBox.layout();
|
||||||
|
m_view.updateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataRecoveryView::onChangeSelection()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (auto widget : m_listBox.children()) {
|
||||||
|
if (!widget->isSelected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dynamic_cast<Item*>(widget)) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_deleteButton.setEnabled(count > 0);
|
||||||
|
m_openButton.setEnabled(count > 0);
|
||||||
|
if (count < 2)
|
||||||
|
m_openButton.mainButton()->setText("Recover Sprite");
|
||||||
|
else
|
||||||
|
m_openButton.mainButton()->setTextf("Recover %d Sprites", count);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
#define APP_UI_DATA_RECOVERY_VIEW_H_INCLUDED
|
#define APP_UI_DATA_RECOVERY_VIEW_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "app/crash/raw_images_as.h"
|
||||||
|
#include "app/ui/drop_down_button.h"
|
||||||
#include "app/ui/tabs.h"
|
#include "app/ui/tabs.h"
|
||||||
#include "app/ui/workspace_view.h"
|
#include "app/ui/workspace_view.h"
|
||||||
#include "ui/box.h"
|
#include "ui/box.h"
|
||||||
|
#include "ui/button.h"
|
||||||
#include "ui/listbox.h"
|
#include "ui/listbox.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
|
||||||
@ -19,7 +22,7 @@ namespace app {
|
|||||||
class DataRecovery;
|
class DataRecovery;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataRecoveryView : public ui::Box
|
class DataRecoveryView : public ui::VBox
|
||||||
, public TabView
|
, public TabView
|
||||||
, public WorkspaceView {
|
, public WorkspaceView {
|
||||||
public:
|
public:
|
||||||
@ -43,9 +46,17 @@ namespace app {
|
|||||||
private:
|
private:
|
||||||
void fillList();
|
void fillList();
|
||||||
|
|
||||||
|
void onOpen();
|
||||||
|
void onOpenRaw(crash::RawImagesAs as);
|
||||||
|
void onOpenMenu();
|
||||||
|
void onDelete();
|
||||||
|
void onChangeSelection();
|
||||||
|
|
||||||
crash::DataRecovery* m_dataRecovery;
|
crash::DataRecovery* m_dataRecovery;
|
||||||
ui::View m_view;
|
ui::View m_view;
|
||||||
ui::ListBox m_listBox;
|
ui::ListBox m_listBox;
|
||||||
|
DropDownButton m_openButton;
|
||||||
|
ui::Button m_deleteButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -273,6 +273,17 @@ void Editor::setStateInternal(const EditorStatePtr& newState)
|
|||||||
else {
|
else {
|
||||||
m_state->onBeforePopState(this);
|
m_state->onBeforePopState(this);
|
||||||
|
|
||||||
|
// Save the current state into "m_deletedStates" just to keep a
|
||||||
|
// reference to it to avoid delete it right now. We'll delete it
|
||||||
|
// in the next Editor::onProcessMessage().
|
||||||
|
//
|
||||||
|
// This is necessary for PlayState because it removes itself
|
||||||
|
// calling Editor::stop() from PlayState::onPlaybackTick(). If we
|
||||||
|
// delete the PlayState inside the "Tick" timer signal, the
|
||||||
|
// program will crash (because we're iterating the
|
||||||
|
// PlayState::m_playTimer slots).
|
||||||
|
m_deletedStates.push(m_state);
|
||||||
|
|
||||||
m_statesHistory.pop();
|
m_statesHistory.pop();
|
||||||
m_state = m_statesHistory.top();
|
m_state = m_statesHistory.top();
|
||||||
}
|
}
|
||||||
@ -1221,10 +1232,17 @@ void Editor::updateToolLoopModifiersIndicators()
|
|||||||
action = m_customizationDelegate->getPressedKeyAction(KeyContext::SelectionTool);
|
action = m_customizationDelegate->getPressedKeyAction(KeyContext::SelectionTool);
|
||||||
|
|
||||||
gen::SelectionMode mode = Preferences::instance().selection.mode();
|
gen::SelectionMode mode = Preferences::instance().selection.mode();
|
||||||
if (int(action & KeyAction::AddSelection))
|
if (int(action & KeyAction::SubtractSelection) ||
|
||||||
mode = gen::SelectionMode::ADD;
|
// Don't use "subtract" mode if the selection was activated
|
||||||
if (int(action & KeyAction::SubtractSelection) || m_secondaryButton)
|
// with the "right click mode = a selection-like tool"
|
||||||
|
(m_secondaryButton &&
|
||||||
|
App::instance()->activeToolManager()->selectedTool() &&
|
||||||
|
App::instance()->activeToolManager()->selectedTool()->getInk(0)->isSelection())) {
|
||||||
mode = gen::SelectionMode::SUBTRACT;
|
mode = gen::SelectionMode::SUBTRACT;
|
||||||
|
}
|
||||||
|
else if (int(action & KeyAction::AddSelection)) {
|
||||||
|
mode = gen::SelectionMode::ADD;
|
||||||
|
}
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case gen::SelectionMode::DEFAULT: modifiers |= int(tools::ToolLoopModifiers::kReplaceSelection); break;
|
case gen::SelectionMode::DEFAULT: modifiers |= int(tools::ToolLoopModifiers::kReplaceSelection); break;
|
||||||
case gen::SelectionMode::ADD: modifiers |= int(tools::ToolLoopModifiers::kAddSelection); break;
|
case gen::SelectionMode::ADD: modifiers |= int(tools::ToolLoopModifiers::kAddSelection); break;
|
||||||
@ -1277,6 +1295,10 @@ app::Color Editor::getColorByPosition(const gfx::Point& mousePos)
|
|||||||
|
|
||||||
bool Editor::onProcessMessage(Message* msg)
|
bool Editor::onProcessMessage(Message* msg)
|
||||||
{
|
{
|
||||||
|
// Delete states
|
||||||
|
if (!m_deletedStates.empty())
|
||||||
|
m_deletedStates.clear();
|
||||||
|
|
||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
|
|
||||||
case kTimerMessage:
|
case kTimerMessage:
|
||||||
@ -1313,14 +1335,17 @@ bool Editor::onProcessMessage(Message* msg)
|
|||||||
m_oldPos = mouseMsg->position();
|
m_oldPos = mouseMsg->position();
|
||||||
updateToolByTipProximity(mouseMsg->pointerType());
|
updateToolByTipProximity(mouseMsg->pointerType());
|
||||||
|
|
||||||
if (!m_secondaryButton && mouseMsg->right()) {
|
// Only when we right-click with the regular "paint bg-color
|
||||||
m_secondaryButton = mouseMsg->right();
|
// right-click mode" we will mark indicate that the secondary
|
||||||
|
// button was used (m_secondaryButton == true).
|
||||||
updateToolLoopModifiersIndicators();
|
if (mouseMsg->right() && !m_secondaryButton) {
|
||||||
updateQuicktool();
|
m_secondaryButton = true;
|
||||||
setCursor(mouseMsg->position());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateToolLoopModifiersIndicators();
|
||||||
|
updateQuicktool();
|
||||||
|
setCursor(mouseMsg->position());
|
||||||
|
|
||||||
App::instance()->activeToolManager()
|
App::instance()->activeToolManager()
|
||||||
->pressButton(pointer_from_msg(this, mouseMsg));
|
->pressButton(pointer_from_msg(this, mouseMsg));
|
||||||
|
|
||||||
@ -1740,14 +1765,15 @@ void Editor::notifyZoomChanged()
|
|||||||
m_observers.notifyZoomChanged(this);
|
m_observers.notifyZoomChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::play(bool playOnce)
|
void Editor::play(const bool playOnce,
|
||||||
|
const bool playAll)
|
||||||
{
|
{
|
||||||
ASSERT(m_state);
|
ASSERT(m_state);
|
||||||
if (!m_state)
|
if (!m_state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!dynamic_cast<PlayState*>(m_state.get()))
|
if (!dynamic_cast<PlayState*>(m_state.get()))
|
||||||
setState(EditorStatePtr(new PlayState(playOnce)));
|
setState(EditorStatePtr(new PlayState(playOnce, playAll)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::stop()
|
void Editor::stop()
|
||||||
@ -1766,9 +1792,10 @@ bool Editor::isPlaying() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
||||||
bool withStopBehaviorOptions)
|
Option<bool>& playAll,
|
||||||
|
const bool withStopBehaviorOptions)
|
||||||
{
|
{
|
||||||
double options[] = { 0.25, 0.5, 1.0, 1.5, 2.0, 3.0 };
|
const double options[] = { 0.25, 0.5, 1.0, 1.5, 2.0, 3.0 };
|
||||||
Menu menu;
|
Menu menu;
|
||||||
|
|
||||||
for (double option : options) {
|
for (double option : options) {
|
||||||
@ -1791,6 +1818,17 @@ void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
|||||||
menu.addChild(item);
|
menu.addChild(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Play all option
|
||||||
|
{
|
||||||
|
MenuItem* item = new MenuItem("Play All Frames (Ignore Tags)");
|
||||||
|
item->Click.connect(
|
||||||
|
[&playAll]() {
|
||||||
|
playAll(!playAll());
|
||||||
|
});
|
||||||
|
item->setSelected(playAll());
|
||||||
|
menu.addChild(item);
|
||||||
|
}
|
||||||
|
|
||||||
if (withStopBehaviorOptions) {
|
if (withStopBehaviorOptions) {
|
||||||
MenuItem* item = new MenuItem("Rewind on Stop");
|
MenuItem* item = new MenuItem("Rewind on Stop");
|
||||||
item->Click.connect(
|
item->Click.connect(
|
||||||
@ -1804,6 +1842,13 @@ void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
|||||||
}
|
}
|
||||||
|
|
||||||
menu.showPopup(ui::get_mouse_position());
|
menu.showPopup(ui::get_mouse_position());
|
||||||
|
|
||||||
|
if (isPlaying()) {
|
||||||
|
// Re-play
|
||||||
|
stop();
|
||||||
|
play(playOnce(),
|
||||||
|
playAll());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Editor::getAnimationSpeedMultiplier() const
|
double Editor::getAnimationSpeedMultiplier() const
|
||||||
|
@ -206,13 +206,15 @@ namespace app {
|
|||||||
void notifyZoomChanged();
|
void notifyZoomChanged();
|
||||||
|
|
||||||
// Animation control
|
// Animation control
|
||||||
void play(bool playOnce);
|
void play(const bool playOnce,
|
||||||
|
const bool playAll);
|
||||||
void stop();
|
void stop();
|
||||||
bool isPlaying() const;
|
bool isPlaying() const;
|
||||||
|
|
||||||
// Shows a popup menu to change the editor animation speed.
|
// Shows a popup menu to change the editor animation speed.
|
||||||
void showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
void showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
||||||
bool withStopBehaviorOptions);
|
Option<bool>& playAll,
|
||||||
|
const bool withStopBehaviorOptions);
|
||||||
double getAnimationSpeedMultiplier() const;
|
double getAnimationSpeedMultiplier() const;
|
||||||
void setAnimationSpeedMultiplier(double speed);
|
void setAnimationSpeedMultiplier(double speed);
|
||||||
|
|
||||||
@ -273,6 +275,7 @@ namespace app {
|
|||||||
|
|
||||||
// Stack of states. The top element in the stack is the current state (m_state).
|
// Stack of states. The top element in the stack is the current state (m_state).
|
||||||
EditorStatesHistory m_statesHistory;
|
EditorStatesHistory m_statesHistory;
|
||||||
|
EditorStatesHistory m_deletedStates;
|
||||||
|
|
||||||
// Current editor state (it can be shared between several editors to
|
// Current editor state (it can be shared between several editors to
|
||||||
// the same document). This member cannot be NULL.
|
// the same document). This member cannot be NULL.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -21,6 +21,8 @@ namespace app {
|
|||||||
EditorStatesHistory();
|
EditorStatesHistory();
|
||||||
~EditorStatesHistory();
|
~EditorStatesHistory();
|
||||||
|
|
||||||
|
bool empty() const { return m_states.empty(); }
|
||||||
|
|
||||||
// Gets the current state.
|
// Gets the current state.
|
||||||
EditorStatePtr top();
|
EditorStatePtr top();
|
||||||
|
|
||||||
|
@ -525,8 +525,15 @@ void MovingPixelsState::onBeforeCommandExecution(CommandExecutionEvent& ev)
|
|||||||
if (command->id() != CommandId::Copy) {
|
if (command->id() != CommandId::Copy) {
|
||||||
m_pixelsMovement->trim();
|
m_pixelsMovement->trim();
|
||||||
|
|
||||||
|
// Should we keep the mask after an Edit > Clear command?
|
||||||
|
auto keepMask = PixelsMovement::DontKeepMask;
|
||||||
|
if (command->id() == CommandId::Clear &&
|
||||||
|
Preferences::instance().selection.keepSelectionAfterClear()) {
|
||||||
|
keepMask = PixelsMovement::KeepMask;
|
||||||
|
}
|
||||||
|
|
||||||
// Discard the dragged image.
|
// Discard the dragged image.
|
||||||
m_pixelsMovement->discardImage();
|
m_pixelsMovement->discardImage(PixelsMovement::CommitChanges, keepMask);
|
||||||
m_discarded = true;
|
m_discarded = true;
|
||||||
|
|
||||||
// Quit from MovingPixelsState, back to standby.
|
// Quit from MovingPixelsState, back to standby.
|
||||||
@ -610,7 +617,7 @@ void MovingPixelsState::onDropPixels(ContextBarObserver::DropAction action)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ContextBarObserver::CancelDrag:
|
case ContextBarObserver::CancelDrag:
|
||||||
m_pixelsMovement->discardImage(false);
|
m_pixelsMovement->discardImage(PixelsMovement::DontCommitChanges);
|
||||||
m_discarded = true;
|
m_discarded = true;
|
||||||
|
|
||||||
// Quit from MovingPixelsState, back to standby.
|
// Quit from MovingPixelsState, back to standby.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2015 David Capello
|
// Copyright (C) 2015-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -29,10 +29,6 @@ MovingSymmetryState::MovingSymmetryState(Editor* editor, MouseMessage* msg,
|
|||||||
editor->captureMouse();
|
editor->captureMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
MovingSymmetryState::~MovingSymmetryState()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MovingSymmetryState::onMouseUp(Editor* editor, MouseMessage* msg)
|
bool MovingSymmetryState::onMouseUp(Editor* editor, MouseMessage* msg)
|
||||||
{
|
{
|
||||||
editor->backToPreviousState();
|
editor->backToPreviousState();
|
||||||
|
@ -19,7 +19,6 @@ namespace app {
|
|||||||
MovingSymmetryState(Editor* editor, ui::MouseMessage* msg,
|
MovingSymmetryState(Editor* editor, ui::MouseMessage* msg,
|
||||||
app::gen::SymmetryMode mode,
|
app::gen::SymmetryMode mode,
|
||||||
Option<int>& symmetryAxis);
|
Option<int>& symmetryAxis);
|
||||||
virtual ~MovingSymmetryState();
|
|
||||||
|
|
||||||
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
|
@ -581,14 +581,16 @@ void PixelsMovement::dropImage()
|
|||||||
m_document->setExtraCel(ExtraCelRef(nullptr));
|
m_document->setExtraCel(ExtraCelRef(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelsMovement::discardImage(bool commit)
|
void PixelsMovement::discardImage(const CommitChangesOption commit,
|
||||||
|
const KeepMaskOption keepMask)
|
||||||
{
|
{
|
||||||
m_isDragging = false;
|
m_isDragging = false;
|
||||||
|
|
||||||
// Deselect the mask (here we don't stamp the image)
|
// Deselect the mask (here we don't stamp the image)
|
||||||
m_transaction.execute(new cmd::DeselectMask(m_document));
|
if (keepMask == DontKeepMask)
|
||||||
|
m_transaction.execute(new cmd::DeselectMask(m_document));
|
||||||
|
|
||||||
if (commit)
|
if (commit == CommitChanges)
|
||||||
m_transaction.commit();
|
m_transaction.commit();
|
||||||
|
|
||||||
// Destroy the extra cel and regenerate the mask boundaries (we've
|
// Destroy the extra cel and regenerate the mask boundaries (we've
|
||||||
|
@ -47,6 +47,16 @@ namespace app {
|
|||||||
ScaleFromPivot = 32,
|
ScaleFromPivot = 32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CommitChangesOption {
|
||||||
|
DontCommitChanges,
|
||||||
|
CommitChanges,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KeepMaskOption {
|
||||||
|
DontKeepMask,
|
||||||
|
KeepMask,
|
||||||
|
};
|
||||||
|
|
||||||
PixelsMovement(Context* context,
|
PixelsMovement(Context* context,
|
||||||
Site site,
|
Site site,
|
||||||
const Image* moveThis,
|
const Image* moveThis,
|
||||||
@ -76,7 +86,8 @@ namespace app {
|
|||||||
|
|
||||||
void dropImageTemporarily();
|
void dropImageTemporarily();
|
||||||
void dropImage();
|
void dropImage();
|
||||||
void discardImage(bool commit = true);
|
void discardImage(const CommitChangesOption commit = CommitChanges,
|
||||||
|
const KeepMaskOption keepMask = DontKeepMask);
|
||||||
bool isDragging() const;
|
bool isDragging() const;
|
||||||
|
|
||||||
gfx::Rect getImageBounds();
|
gfx::Rect getImageBounds();
|
||||||
|
@ -27,13 +27,17 @@ namespace app {
|
|||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
PlayState::PlayState(bool playOnce)
|
PlayState::PlayState(const bool playOnce,
|
||||||
|
const bool playAll)
|
||||||
: m_editor(nullptr)
|
: m_editor(nullptr)
|
||||||
, m_playOnce(playOnce)
|
, m_playOnce(playOnce)
|
||||||
|
, m_playAll(playAll)
|
||||||
, m_toScroll(false)
|
, m_toScroll(false)
|
||||||
, m_playTimer(10)
|
, m_playTimer(10)
|
||||||
, m_nextFrameTime(-1)
|
, m_nextFrameTime(-1)
|
||||||
, m_pingPongForward(true)
|
, m_pingPongForward(true)
|
||||||
|
, m_refFrame(0)
|
||||||
|
, m_tag(nullptr)
|
||||||
{
|
{
|
||||||
m_playTimer.Tick.connect(&PlayState::onPlaybackTick, this);
|
m_playTimer.Tick.connect(&PlayState::onPlaybackTick, this);
|
||||||
|
|
||||||
@ -52,16 +56,18 @@ void PlayState::onEnterState(Editor* editor)
|
|||||||
m_refFrame = editor->frame();
|
m_refFrame = editor->frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the tag
|
||||||
|
if (!m_playAll)
|
||||||
|
m_tag = get_animation_tag(m_editor->sprite(), m_refFrame);
|
||||||
|
|
||||||
// Go to the first frame of the animation or active frame tag
|
// Go to the first frame of the animation or active frame tag
|
||||||
if (m_playOnce) {
|
if (m_playOnce) {
|
||||||
frame_t frame = 0;
|
frame_t frame = 0;
|
||||||
|
|
||||||
doc::FrameTag* tag = get_animation_tag(
|
if (m_tag) {
|
||||||
m_editor->sprite(), m_refFrame);
|
frame = (m_tag->aniDir() == AniDir::REVERSE ?
|
||||||
if (tag) {
|
m_tag->toFrame():
|
||||||
frame = (tag->aniDir() == AniDir::REVERSE ?
|
m_tag->fromFrame());
|
||||||
tag->toFrame():
|
|
||||||
tag->fromFrame());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_editor->setFrame(frame);
|
m_editor->setFrame(frame);
|
||||||
@ -147,24 +153,23 @@ void PlayState::onPlaybackTick()
|
|||||||
m_nextFrameTime -= (base::current_tick() - m_curFrameTick);
|
m_nextFrameTime -= (base::current_tick() - m_curFrameTick);
|
||||||
|
|
||||||
doc::Sprite* sprite = m_editor->sprite();
|
doc::Sprite* sprite = m_editor->sprite();
|
||||||
doc::FrameTag* tag = get_animation_tag(sprite, m_refFrame);
|
|
||||||
|
|
||||||
while (m_nextFrameTime <= 0) {
|
while (m_nextFrameTime <= 0) {
|
||||||
doc::frame_t frame = m_editor->frame();
|
doc::frame_t frame = m_editor->frame();
|
||||||
|
|
||||||
if (m_playOnce) {
|
if (m_playOnce) {
|
||||||
bool atEnd = false;
|
bool atEnd = false;
|
||||||
if (tag) {
|
if (m_tag) {
|
||||||
switch (tag->aniDir()) {
|
switch (m_tag->aniDir()) {
|
||||||
case AniDir::FORWARD:
|
case AniDir::FORWARD:
|
||||||
atEnd = (frame == tag->toFrame());
|
atEnd = (frame == m_tag->toFrame());
|
||||||
break;
|
break;
|
||||||
case AniDir::REVERSE:
|
case AniDir::REVERSE:
|
||||||
atEnd = (frame == tag->fromFrame());
|
atEnd = (frame == m_tag->fromFrame());
|
||||||
break;
|
break;
|
||||||
case AniDir::PING_PONG:
|
case AniDir::PING_PONG:
|
||||||
atEnd = (!m_pingPongForward &&
|
atEnd = (!m_pingPongForward &&
|
||||||
frame == tag->fromFrame());
|
frame == m_tag->fromFrame());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +183,7 @@ void PlayState::onPlaybackTick()
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame = calculate_next_frame(
|
frame = calculate_next_frame(
|
||||||
sprite, frame, frame_t(1), tag,
|
sprite, frame, frame_t(1), m_tag,
|
||||||
m_pingPongForward);
|
m_pingPongForward);
|
||||||
|
|
||||||
m_editor->setFrame(frame);
|
m_editor->setFrame(frame);
|
||||||
|
@ -14,13 +14,18 @@
|
|||||||
#include "obs/connection.h"
|
#include "obs/connection.h"
|
||||||
#include "ui/timer.h"
|
#include "ui/timer.h"
|
||||||
|
|
||||||
|
namespace doc {
|
||||||
|
class FrameTag;
|
||||||
|
}
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
class CommandExecutionEvent;
|
class CommandExecutionEvent;
|
||||||
|
|
||||||
class PlayState : public StateWithWheelBehavior {
|
class PlayState : public StateWithWheelBehavior {
|
||||||
public:
|
public:
|
||||||
PlayState(bool playOnce);
|
PlayState(const bool playOnce,
|
||||||
|
const bool playAll);
|
||||||
|
|
||||||
void onEnterState(Editor* editor) override;
|
void onEnterState(Editor* editor) override;
|
||||||
LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
|
LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
|
||||||
@ -40,6 +45,7 @@ namespace app {
|
|||||||
|
|
||||||
Editor* m_editor;
|
Editor* m_editor;
|
||||||
bool m_playOnce;
|
bool m_playOnce;
|
||||||
|
bool m_playAll;
|
||||||
bool m_toScroll;
|
bool m_toScroll;
|
||||||
ui::Timer m_playTimer;
|
ui::Timer m_playTimer;
|
||||||
|
|
||||||
@ -50,6 +56,7 @@ namespace app {
|
|||||||
|
|
||||||
bool m_pingPongForward;
|
bool m_pingPongForward;
|
||||||
doc::frame_t m_refFrame;
|
doc::frame_t m_refFrame;
|
||||||
|
doc::FrameTag* m_tag;
|
||||||
|
|
||||||
obs::scoped_connection m_ctxConn;
|
obs::scoped_connection m_ctxConn;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -27,10 +27,6 @@ ScrollingState::ScrollingState()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollingState::~ScrollingState()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScrollingState::onMouseDown(Editor* editor, MouseMessage* msg)
|
bool ScrollingState::onMouseDown(Editor* editor, MouseMessage* msg)
|
||||||
{
|
{
|
||||||
m_oldPos = msg->position();
|
m_oldPos = msg->position();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -16,7 +16,6 @@ namespace app {
|
|||||||
class ScrollingState : public EditorState {
|
class ScrollingState : public EditorState {
|
||||||
public:
|
public:
|
||||||
ScrollingState();
|
ScrollingState();
|
||||||
virtual ~ScrollingState();
|
|
||||||
virtual bool isTemporalState() const override { return true; }
|
virtual bool isTemporalState() const override { return true; }
|
||||||
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "app/document_range.h"
|
#include "app/document_range.h"
|
||||||
#include "app/ini_file.h"
|
#include "app/ini_file.h"
|
||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/tools/active_tool.h"
|
||||||
#include "app/tools/ink.h"
|
#include "app/tools/ink.h"
|
||||||
#include "app/tools/pick_ink.h"
|
#include "app/tools/pick_ink.h"
|
||||||
#include "app/tools/tool.h"
|
#include "app/tools/tool.h"
|
||||||
@ -254,7 +255,16 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickedInk->isSelection()) {
|
// Only if the selected tool or quick tool is selection, we give the
|
||||||
|
// possibility to transform/move the selection. In other case,
|
||||||
|
// e.g. when selection is used with right-click mode, the
|
||||||
|
// transformation is disabled.
|
||||||
|
auto activeToolManager = App::instance()->activeToolManager();
|
||||||
|
if (clickedInk->isSelection() &&
|
||||||
|
((activeToolManager->selectedTool() &&
|
||||||
|
activeToolManager->selectedTool()->getInk(0)->isSelection()) ||
|
||||||
|
(activeToolManager->quickTool() &&
|
||||||
|
activeToolManager->quickTool()->getInk(0)->isSelection()))) {
|
||||||
// Transform selected pixels
|
// Transform selected pixels
|
||||||
if (editor->isActive() &&
|
if (editor->isActive() &&
|
||||||
document->isMaskVisible() &&
|
document->isMaskVisible() &&
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -34,10 +34,6 @@ ZoomingState::ZoomingState()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoomingState::~ZoomingState()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZoomingState::onMouseDown(Editor* editor, MouseMessage* msg)
|
bool ZoomingState::onMouseDown(Editor* editor, MouseMessage* msg)
|
||||||
{
|
{
|
||||||
m_startPos = msg->position();
|
m_startPos = msg->position();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -17,7 +17,6 @@ namespace app {
|
|||||||
class ZoomingState : public EditorState {
|
class ZoomingState : public EditorState {
|
||||||
public:
|
public:
|
||||||
ZoomingState();
|
ZoomingState();
|
||||||
virtual ~ZoomingState();
|
|
||||||
virtual bool isTemporalState() const override { return true; }
|
virtual bool isTemporalState() const override { return true; }
|
||||||
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
|
@ -26,39 +26,20 @@ namespace app {
|
|||||||
using namespace app::skin;
|
using namespace app::skin;
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
PopupWindowPin::PopupWindowPin(const std::string& text, ClickBehavior clickBehavior)
|
PopupWindowPin::PopupWindowPin(const std::string& text,
|
||||||
: PopupWindow(text, clickBehavior)
|
const ClickBehavior clickBehavior,
|
||||||
, m_pin("")
|
const bool canPin)
|
||||||
|
: PopupWindow(text, clickBehavior,
|
||||||
|
EnterBehavior::CloseOnEnter, canPin)
|
||||||
|
, m_pinned(false)
|
||||||
{
|
{
|
||||||
SkinTheme* theme = SkinTheme::instance();
|
|
||||||
|
|
||||||
m_pin.setFocusStop(false);
|
|
||||||
m_pin.Click.connect(&PopupWindowPin::onPinClick, this);
|
|
||||||
m_pin.setIconInterface(
|
|
||||||
new ButtonIconImpl(theme->parts.unpinned(),
|
|
||||||
theme->parts.pinned(),
|
|
||||||
theme->parts.unpinned(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupWindowPin::showPin(bool state)
|
void PopupWindowPin::setPinned(const bool pinned)
|
||||||
{
|
{
|
||||||
m_pin.setVisible(state);
|
m_pinned = pinned;
|
||||||
}
|
if (m_pinned)
|
||||||
|
|
||||||
void PopupWindowPin::setPinned(bool pinned)
|
|
||||||
{
|
|
||||||
m_pin.setSelected(pinned);
|
|
||||||
|
|
||||||
Event ev(this);
|
|
||||||
onPinClick(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PopupWindowPin::onPinClick(Event& ev)
|
|
||||||
{
|
|
||||||
if (m_pin.isSelected()) {
|
|
||||||
makeFloating();
|
makeFloating();
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
gfx::Rect rc = bounds();
|
gfx::Rect rc = bounds();
|
||||||
rc.enlarge(8);
|
rc.enlarge(8);
|
||||||
@ -72,8 +53,16 @@ bool PopupWindowPin::onProcessMessage(Message* msg)
|
|||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
|
|
||||||
case kOpenMessage: {
|
case kOpenMessage: {
|
||||||
if (!isPinned())
|
if (!m_pinned)
|
||||||
makeFixed();
|
setPinned(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kCloseMessage: {
|
||||||
|
// If the closer() wasn't the hot region or the window, it might
|
||||||
|
// be because the user pressed the close button.
|
||||||
|
if (closer() && closer() != this)
|
||||||
|
m_pinned = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +77,7 @@ void PopupWindowPin::onWindowMovement()
|
|||||||
|
|
||||||
// If the window isn't pinned and we move it, we can automatically
|
// If the window isn't pinned and we move it, we can automatically
|
||||||
// pin it.
|
// pin it.
|
||||||
if (!m_pin.isSelected())
|
if (!m_pinned)
|
||||||
setPinned(true);
|
setPinned(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,25 +15,19 @@ namespace app {
|
|||||||
|
|
||||||
class PopupWindowPin : public ui::PopupWindow {
|
class PopupWindowPin : public ui::PopupWindow {
|
||||||
public:
|
public:
|
||||||
PopupWindowPin(const std::string& text, ClickBehavior clickBehavior);
|
PopupWindowPin(const std::string& text,
|
||||||
|
const ClickBehavior clickBehavior,
|
||||||
|
const bool canPin = false);
|
||||||
|
|
||||||
void showPin(bool state);
|
bool isPinned() const { return m_pinned; }
|
||||||
bool isPinned() const { return m_pin.isSelected(); }
|
void setPinned(const bool pinned);
|
||||||
void setPinned(bool pinned);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool onProcessMessage(ui::Message* msg) override;
|
virtual bool onProcessMessage(ui::Message* msg) override;
|
||||||
virtual void onWindowMovement() override;
|
virtual void onWindowMovement() override;
|
||||||
|
|
||||||
// The pin. Your derived class must add this pin in some place of
|
|
||||||
// the frame as a children, and you must to remove the pin from the
|
|
||||||
// parent in your class's dtor.
|
|
||||||
ui::CheckBox* getPin() { return &m_pin; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onPinClick(ui::Event& ev);
|
bool m_pinned;
|
||||||
|
|
||||||
ui::CheckBox m_pin;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -299,7 +299,8 @@ void PreviewEditorWindow::onPlayClicked()
|
|||||||
|
|
||||||
if (m_playButton->isPlaying()) {
|
if (m_playButton->isPlaying()) {
|
||||||
m_refFrame = miniEditor->frame();
|
m_refFrame = miniEditor->frame();
|
||||||
miniEditor->play(Preferences::instance().preview.playOnce());
|
miniEditor->play(Preferences::instance().preview.playOnce(),
|
||||||
|
Preferences::instance().preview.playAll());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
miniEditor->stop();
|
miniEditor->stop();
|
||||||
@ -311,8 +312,12 @@ void PreviewEditorWindow::onPopupSpeed()
|
|||||||
if (!miniEditor || !miniEditor->document())
|
if (!miniEditor || !miniEditor->document())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto& pref = Preferences::instance();
|
||||||
|
|
||||||
miniEditor->showAnimationSpeedMultiplierPopup(
|
miniEditor->showAnimationSpeedMultiplierPopup(
|
||||||
Preferences::instance().preview.playOnce, false);
|
pref.preview.playOnce,
|
||||||
|
pref.preview.playAll,
|
||||||
|
false);
|
||||||
m_aniSpeed = miniEditor->getAnimationSpeedMultiplier();
|
m_aniSpeed = miniEditor->getAnimationSpeedMultiplier();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +388,8 @@ void PreviewEditorWindow::updateUsingEditor(Editor* editor)
|
|||||||
if (!miniEditor->isPlaying())
|
if (!miniEditor->isPlaying())
|
||||||
miniEditor->setFrame(m_refFrame = editor->frame());
|
miniEditor->setFrame(m_refFrame = editor->frame());
|
||||||
|
|
||||||
miniEditor->play(Preferences::instance().preview.playOnce());
|
miniEditor->play(Preferences::instance().preview.playOnce(),
|
||||||
|
Preferences::instance().preview.playAll());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void onSizeHint(SizeHintEvent& ev) override {
|
||||||
|
ev.setSizeHint(SkinTheme::instance()->parts.windowCloseButtonNormal()->size());
|
||||||
|
}
|
||||||
|
|
||||||
void onClick(Event& ev) override {
|
void onClick(Event& ev) override {
|
||||||
Button::onClick(ev);
|
Button::onClick(ev);
|
||||||
closeWindow();
|
closeWindow();
|
||||||
@ -1666,6 +1671,7 @@ void SkinTheme::paintWindowButton(ui::PaintEvent& ev)
|
|||||||
else
|
else
|
||||||
part = parts.windowCloseButtonNormal();
|
part = parts.windowCloseButtonNormal();
|
||||||
|
|
||||||
|
g->fillRect(BGCOLOR, rc);
|
||||||
g->drawRgbaSurface(part->bitmap(0), rc.x, rc.y);
|
g->drawRgbaSurface(part->bitmap(0), rc.x, rc.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,8 @@ void Timeline::setFrame(frame_t frame, bool byUser)
|
|||||||
m_editor->setFrame(m_frame);
|
m_editor->setFrame(m_frame);
|
||||||
|
|
||||||
if (isPlaying)
|
if (isPlaying)
|
||||||
m_editor->play(false);
|
m_editor->play(false,
|
||||||
|
Preferences::instance().editor.playAll());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -32,6 +32,7 @@ using namespace ui;
|
|||||||
|
|
||||||
ZoomEntry::ZoomEntry()
|
ZoomEntry::ZoomEntry()
|
||||||
: IntEntry(0, render::Zoom::linearValues()-1, this)
|
: IntEntry(0, render::Zoom::linearValues()-1, this)
|
||||||
|
, m_locked(false)
|
||||||
{
|
{
|
||||||
setSuffix("%");
|
setSuffix("%");
|
||||||
setup_mini_look(this);
|
setup_mini_look(this);
|
||||||
@ -41,11 +42,15 @@ ZoomEntry::ZoomEntry()
|
|||||||
|
|
||||||
void ZoomEntry::setZoom(const render::Zoom& zoom)
|
void ZoomEntry::setZoom(const render::Zoom& zoom)
|
||||||
{
|
{
|
||||||
|
if (m_locked)
|
||||||
|
return;
|
||||||
|
|
||||||
setText(onGetTextFromValue(zoom.linearScale()));
|
setText(onGetTextFromValue(zoom.linearScale()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoomEntry::onValueChange()
|
void ZoomEntry::onValueChange()
|
||||||
{
|
{
|
||||||
|
base::ScopedValue<bool> lock(m_locked, true, m_locked);
|
||||||
IntEntry::onValueChange();
|
IntEntry::onValueChange();
|
||||||
|
|
||||||
render::Zoom zoom = render::Zoom::fromLinearScale(getValue());
|
render::Zoom zoom = render::Zoom::fromLinearScale(getValue());
|
||||||
|
@ -29,6 +29,8 @@ namespace app {
|
|||||||
int onGetValueFromText(const std::string& text) override;
|
int onGetValueFromText(const std::string& text) override;
|
||||||
|
|
||||||
void onValueChange() override;
|
void onValueChange() override;
|
||||||
|
|
||||||
|
bool m_locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -119,7 +119,8 @@ FileFormat detect_format_by_file_extension(const std::string& filename)
|
|||||||
if (ext == "pal")
|
if (ext == "pal")
|
||||||
return FileFormat::PAL_PALETTE;
|
return FileFormat::PAL_PALETTE;
|
||||||
|
|
||||||
if (ext == "pcx")
|
if (ext == "pcx" ||
|
||||||
|
ext == "pcc")
|
||||||
return FileFormat::PCX_IMAGE;
|
return FileFormat::PCX_IMAGE;
|
||||||
|
|
||||||
if (ext == "anim")
|
if (ext == "anim")
|
||||||
|
@ -118,10 +118,13 @@ bool IntEntry::onProcessMessage(Message* msg)
|
|||||||
if (hasFocus() && !isReadOnly()) {
|
if (hasFocus() && !isReadOnly()) {
|
||||||
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
|
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
|
||||||
int chr = keymsg->unicodeChar();
|
int chr = keymsg->unicodeChar();
|
||||||
if (chr && (chr < '0' || chr > '9')) {
|
if (chr >= 32 && (chr < '0' || chr > '9')) {
|
||||||
// By-pass Entry::onProcessMessage()
|
// "Eat" all keys that aren't number
|
||||||
return Widget::onProcessMessage(msg);
|
return true;
|
||||||
}
|
}
|
||||||
|
// Else we use the default Entry processing function which
|
||||||
|
// will process keys like Left/Right arrows, clipboard
|
||||||
|
// handling, etc.
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ bool ListBox::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pick_item) {
|
if (pick_item) {
|
||||||
Widget* picked;
|
Widget* picked = nullptr;
|
||||||
|
|
||||||
if (view) {
|
if (view) {
|
||||||
picked = view->viewport()->pick(mousePos);
|
picked = view->viewport()->pick(mousePos);
|
||||||
@ -239,11 +239,8 @@ bool ListBox::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the picked widget is a child of the list, select it
|
// If the picked widget is a child of the list, select it
|
||||||
if (picked && hasChild(picked)) {
|
if (picked && hasChild(picked))
|
||||||
if (ListItem* pickedItem = dynamic_cast<ListItem*>(picked)) {
|
selectChild(picked, msg);
|
||||||
selectChild(pickedItem, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -365,7 +362,7 @@ void ListBox::onSizeHint(SizeHintEvent& ev)
|
|||||||
int w = 0, h = 0;
|
int w = 0, h = 0;
|
||||||
|
|
||||||
UI_FOREACH_WIDGET_WITH_END(children(), it, end) {
|
UI_FOREACH_WIDGET_WITH_END(children(), it, end) {
|
||||||
Size reqSize = static_cast<ListItem*>(*it)->sizeHint();
|
Size reqSize = (*it)->sizeHint();
|
||||||
|
|
||||||
w = MAX(w, reqSize.w);
|
w = MAX(w, reqSize.w);
|
||||||
h += reqSize.h + (it+1 != end ? this->childSpacing(): 0);
|
h += reqSize.h + (it+1 != end ? this->childSpacing(): 0);
|
||||||
|
@ -20,8 +20,9 @@ namespace ui {
|
|||||||
using namespace gfx;
|
using namespace gfx;
|
||||||
|
|
||||||
PopupWindow::PopupWindow(const std::string& text,
|
PopupWindow::PopupWindow(const std::string& text,
|
||||||
ClickBehavior clickBehavior,
|
const ClickBehavior clickBehavior,
|
||||||
EnterBehavior enterBehavior)
|
const EnterBehavior enterBehavior,
|
||||||
|
const bool withCloseButton)
|
||||||
: Window(text.empty() ? WithoutTitleBar: WithTitleBar, text)
|
: Window(text.empty() ? WithoutTitleBar: WithTitleBar, text)
|
||||||
, m_clickBehavior(clickBehavior)
|
, m_clickBehavior(clickBehavior)
|
||||||
, m_enterBehavior(enterBehavior)
|
, m_enterBehavior(enterBehavior)
|
||||||
@ -33,7 +34,8 @@ PopupWindow::PopupWindow(const std::string& text,
|
|||||||
setWantFocus(false);
|
setWantFocus(false);
|
||||||
setAlign(LEFT | TOP);
|
setAlign(LEFT | TOP);
|
||||||
|
|
||||||
removeDecorativeWidgets();
|
if (!withCloseButton)
|
||||||
|
removeDecorativeWidgets();
|
||||||
|
|
||||||
initTheme();
|
initTheme();
|
||||||
noBorderNoChildSpacing();
|
noBorderNoChildSpacing();
|
||||||
|
@ -26,8 +26,9 @@ namespace ui {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PopupWindow(const std::string& text = "",
|
PopupWindow(const std::string& text = "",
|
||||||
ClickBehavior clickBehavior = ClickBehavior::CloseOnClickOutsideHotRegion,
|
const ClickBehavior clickBehavior = ClickBehavior::CloseOnClickOutsideHotRegion,
|
||||||
EnterBehavior enterBehavior = EnterBehavior::CloseOnEnter);
|
const EnterBehavior enterBehavior = EnterBehavior::CloseOnEnter,
|
||||||
|
const bool withCloseButton = false);
|
||||||
~PopupWindow();
|
~PopupWindow();
|
||||||
|
|
||||||
// Sets the hot region. This region indicates the area where the
|
// Sets the hot region. This region indicates the area where the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user