mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-01 01:13:40 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
8d2863a58b
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -71,7 +71,7 @@
|
|||||||
url = https://github.com/aseprite/curl.git
|
url = https://github.com/aseprite/curl.git
|
||||||
[submodule "third_party/IXWebSocket"]
|
[submodule "third_party/IXWebSocket"]
|
||||||
path = third_party/IXWebSocket
|
path = third_party/IXWebSocket
|
||||||
url = https://github.com/machinezone/IXWebSocket
|
url = https://github.com/aseprite/IXWebSocket.git
|
||||||
[submodule "third_party/cityhash"]
|
[submodule "third_party/cityhash"]
|
||||||
path = third_party/cityhash
|
path = third_party/cityhash
|
||||||
url = https://github.com/aseprite/cityhash.git
|
url = https://github.com/aseprite/cityhash.git
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
# Aseprite
|
# Aseprite
|
||||||
# Copyright (C) 2018-2021 Igara Studio S.A.
|
# Copyright (C) 2018-2022 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2018 David Capello
|
# Copyright (C) 2001-2018 David Capello
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.4)
|
cmake_minimum_required(VERSION 3.4)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF) # We use -std=c++14 instead of -std=gnu++14 in macOS
|
set(CMAKE_CXX_EXTENSIONS OFF) # We use -std=c++17 instead of -std=gnu++17 in macOS
|
||||||
|
|
||||||
if(COMMAND cmake_policy)
|
if(COMMAND cmake_policy)
|
||||||
# CMP0003: Libraries linked via full path no longer produce linker search paths.
|
# CMP0003: Libraries linked via full path no longer produce linker search paths.
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
@ -192,6 +192,8 @@
|
|||||||
<part id="combobox_arrow_right" x="99" y="196" w="9" h="9" />
|
<part id="combobox_arrow_right" x="99" y="196" w="9" h="9" />
|
||||||
<part id="combobox_arrow_right_selected" x="115" y="196" w="9" h="9" />
|
<part id="combobox_arrow_right_selected" x="115" y="196" w="9" h="9" />
|
||||||
<part id="combobox_arrow_right_disabled" x="131" y="196" w="9" h="9" />
|
<part id="combobox_arrow_right_disabled" x="131" y="196" w="9" h="9" />
|
||||||
|
<part id="arrow_circle_cw" x="99" y="243" w="10" h="10" />
|
||||||
|
<part id="arrow_circle_cw_selected" x="115" y="243" w="10" h="10" />
|
||||||
<part id="newfolder" x="99" y="211" w="9" h="9" />
|
<part id="newfolder" x="99" y="211" w="9" h="9" />
|
||||||
<part id="newfolder_selected" x="115" y="211" w="9" h="9" />
|
<part id="newfolder_selected" x="115" y="211" w="9" h="9" />
|
||||||
<part id="list_view" x="96" y="224" w="9" h="9" />
|
<part id="list_view" x="96" y="224" w="9" h="9" />
|
||||||
@ -647,6 +649,10 @@
|
|||||||
<icon part="combobox_arrow_up_selected" state="selected" />
|
<icon part="combobox_arrow_up_selected" state="selected" />
|
||||||
<icon part="combobox_arrow_up_disabled" state="disabled" />
|
<icon part="combobox_arrow_up_disabled" state="disabled" />
|
||||||
</style>
|
</style>
|
||||||
|
<style id="refresh_button" extends="mini_button">
|
||||||
|
<icon part="arrow_circle_cw" />
|
||||||
|
<icon part="arrow_circle_cw_selected" state="selected" />
|
||||||
|
</style>
|
||||||
<style id="new_folder_button" extends="mini_button">
|
<style id="new_folder_button" extends="mini_button">
|
||||||
<icon part="newfolder" />
|
<icon part="newfolder" />
|
||||||
<icon part="newfolder_selected" state="selected" />
|
<icon part="newfolder_selected" state="selected" />
|
||||||
|
@ -158,6 +158,7 @@
|
|||||||
<option id="show_menu_bar" type="bool" default="true" />
|
<option id="show_menu_bar" type="bool" default="true" />
|
||||||
<option id="recent_items" type="int" default="16" />
|
<option id="recent_items" type="int" default="16" />
|
||||||
<option id="osx_async_view" type="bool" default="true" />
|
<option id="osx_async_view" type="bool" default="true" />
|
||||||
|
<option id="x11_stylus_id" type="std::string" />
|
||||||
</section>
|
</section>
|
||||||
<section id="undo" text="Undo">
|
<section id="undo" text="Undo">
|
||||||
<option id="size_limit" type="int" default="0" />
|
<option id="size_limit" type="int" default="0" />
|
||||||
@ -170,6 +171,7 @@
|
|||||||
<option id="zoom_with_slide" type="bool" default="false" />
|
<option id="zoom_with_slide" type="bool" default="false" />
|
||||||
<option id="zoom_from_center_with_wheel" type="bool" default="false" />
|
<option id="zoom_from_center_with_wheel" type="bool" default="false" />
|
||||||
<option id="zoom_from_center_with_keys" type="bool" default="false" />
|
<option id="zoom_from_center_with_keys" type="bool" default="false" />
|
||||||
|
<option id="invert_brush_size_wheel" type="bool" default="false" />
|
||||||
<option id="show_scrollbars" type="bool" default="true" />
|
<option id="show_scrollbars" type="bool" default="true" />
|
||||||
<option id="auto_scroll" type="bool" default="true" />
|
<option id="auto_scroll" type="bool" default="true" />
|
||||||
<option id="right_click_mode" type="RightClickMode" default="RightClickMode::PAINT_BGCOLOR" />
|
<option id="right_click_mode" type="RightClickMode" default="RightClickMode::PAINT_BGCOLOR" />
|
||||||
|
@ -728,6 +728,7 @@ generating = Generating...
|
|||||||
go_back_button_tooltip = Go back one folder
|
go_back_button_tooltip = Go back one folder
|
||||||
go_forward_button_tooltip = Go forward one folder
|
go_forward_button_tooltip = Go forward one folder
|
||||||
go_up_button_tooltip = Up to parent folder
|
go_up_button_tooltip = Up to parent folder
|
||||||
|
refresh_button_tooltip = Refresh folder view
|
||||||
new_folder_button_tooltip = New folder
|
new_folder_button_tooltip = New folder
|
||||||
list_view_button_tooltip = List View
|
list_view_button_tooltip = List View
|
||||||
small_icon_view_button_tooltip = Small Icons View
|
small_icon_view_button_tooltip = Small Icons View
|
||||||
@ -851,6 +852,7 @@ section_drag_value = Drag Value
|
|||||||
default_wheel_behavior = Default
|
default_wheel_behavior = Default
|
||||||
custom_wheel_behavior = Custom
|
custom_wheel_behavior = Custom
|
||||||
slide_as_wheel = Interpret two fingers slide on Trackpad as mouse wheel
|
slide_as_wheel = Interpret two fingers slide on Trackpad as mouse wheel
|
||||||
|
invert_brush_size_wheel = Invert the mouse wheel direction for increasing the brush size
|
||||||
drag_angle = Angle:
|
drag_angle = Angle:
|
||||||
drag_angle_tooltip = Direction of the mouse to indicate an increment of the value
|
drag_angle_tooltip = Direction of the mouse to indicate an increment of the value
|
||||||
drag_distance = Distance:
|
drag_distance = Distance:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!-- Aseprite -->
|
<!-- Aseprite -->
|
||||||
<!-- Copyright (C) 2019 Igara Studio S.A. -->
|
<!-- Copyright (C) 2019-2022 Igara Studio S.A. -->
|
||||||
<!-- Copyright (C) 2001-2018 David Capello -->
|
<!-- Copyright (C) 2001-2018 David Capello -->
|
||||||
<gui>
|
<gui>
|
||||||
<window id="file_selector" text="">
|
<window id="file_selector" text="">
|
||||||
@ -21,6 +21,8 @@
|
|||||||
<item icon="big_icon_view" tooltip="@.big_icon_view_button_tooltip" tooltip_dir="bottom" />
|
<item icon="big_icon_view" tooltip="@.big_icon_view_button_tooltip" tooltip_dir="bottom" />
|
||||||
</buttonset>
|
</buttonset>
|
||||||
<combobox id="location" expansive="true" />
|
<combobox id="location" expansive="true" />
|
||||||
|
<button text="" id="refresh_button" style="refresh_button"
|
||||||
|
tooltip="@.refresh_button_tooltip" tooltip_dir="bottom" />
|
||||||
</box>
|
</box>
|
||||||
<vbox id="file_view_placeholder" expansive="true" />
|
<vbox id="file_view_placeholder" expansive="true" />
|
||||||
<grid columns="2">
|
<grid columns="2">
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
pref="editor.zoom_with_wheel" />
|
pref="editor.zoom_with_wheel" />
|
||||||
<check text="@options.slide_zoom" id="slide_zoom"
|
<check text="@options.slide_zoom" id="slide_zoom"
|
||||||
pref="editor.zoom_with_slide" />
|
pref="editor.zoom_with_slide" />
|
||||||
|
<check text="@.invert_brush_size_wheel" id="invert_brush_size_scroll"
|
||||||
|
pref="editor.invert_brush_size_wheel" />
|
||||||
<view expansive="true">
|
<view expansive="true">
|
||||||
<listbox id="wheel_actions" />
|
<listbox id="wheel_actions" />
|
||||||
</view>
|
</view>
|
||||||
|
2
laf
2
laf
@ -1 +1 @@
|
|||||||
Subproject commit df53f4ac0cecada789bf84b4283947d2591833bd
|
Subproject commit 8f9e7892e0da31e423e224b199f53d8ffefce32b
|
@ -71,6 +71,8 @@
|
|||||||
|
|
||||||
#if LAF_MACOS
|
#if LAF_MACOS
|
||||||
#include "os/osx/system.h"
|
#include "os/osx/system.h"
|
||||||
|
#elif LAF_LINUX
|
||||||
|
#include "os/x11/system.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -95,6 +97,7 @@ namespace {
|
|||||||
|
|
||||||
class ConsoleEngineDelegate : public script::EngineDelegate {
|
class ConsoleEngineDelegate : public script::EngineDelegate {
|
||||||
public:
|
public:
|
||||||
|
ConsoleEngineDelegate(Console& console) : m_console(console) { }
|
||||||
void onConsoleError(const char* text) override {
|
void onConsoleError(const char* text) override {
|
||||||
onConsolePrint(text);
|
onConsolePrint(text);
|
||||||
}
|
}
|
||||||
@ -102,7 +105,7 @@ public:
|
|||||||
m_console.printf("%s\n", text);
|
m_console.printf("%s\n", text);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Console m_console;
|
Console& m_console;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@ -236,6 +239,7 @@ int App::initialize(const AppOptions& options)
|
|||||||
m_coreModules = new CoreModules;
|
m_coreModules = new CoreModules;
|
||||||
|
|
||||||
#if LAF_WINDOWS
|
#if LAF_WINDOWS
|
||||||
|
|
||||||
if (options.disableWintab() ||
|
if (options.disableWintab() ||
|
||||||
!preferences().experimental.loadWintabDriver() ||
|
!preferences().experimental.loadWintabDriver() ||
|
||||||
preferences().tablet.api() == "pointer") {
|
preferences().tablet.api() == "pointer") {
|
||||||
@ -245,11 +249,20 @@ int App::initialize(const AppOptions& options)
|
|||||||
system->setTabletAPI(os::TabletAPI::WintabPackets);
|
system->setTabletAPI(os::TabletAPI::WintabPackets);
|
||||||
else // preferences().tablet.api() == "wintab"
|
else // preferences().tablet.api() == "wintab"
|
||||||
system->setTabletAPI(os::TabletAPI::Wintab);
|
system->setTabletAPI(os::TabletAPI::Wintab);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LAF_MACOS
|
#elif LAF_MACOS
|
||||||
|
|
||||||
if (!preferences().general.osxAsyncView())
|
if (!preferences().general.osxAsyncView())
|
||||||
os::osx_set_async_view(false);
|
os::osx_set_async_view(false);
|
||||||
|
|
||||||
|
#elif LAF_LINUX
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string& stylusId = preferences().general.x11StylusId();
|
||||||
|
if (!stylusId.empty())
|
||||||
|
os::x11_set_user_defined_string_to_detect_stylus(stylusId);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
system->setAppName(get_app_name());
|
system->setAppName(get_app_name());
|
||||||
@ -485,7 +498,7 @@ void App::run()
|
|||||||
Console console;
|
Console console;
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
// Use the app::Console() for script errors
|
// Use the app::Console() for script errors
|
||||||
ConsoleEngineDelegate delegate;
|
ConsoleEngineDelegate delegate(console);
|
||||||
script::ScopedEngineDelegate setEngineDelegate(m_engine.get(), &delegate);
|
script::ScopedEngineDelegate setEngineDelegate(m_engine.get(), &delegate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -206,6 +206,7 @@ bool FilterManagerImpl::applyStep()
|
|||||||
|
|
||||||
void FilterManagerImpl::apply()
|
void FilterManagerImpl::apply()
|
||||||
{
|
{
|
||||||
|
CommandResult result;
|
||||||
bool cancelled = false;
|
bool cancelled = false;
|
||||||
|
|
||||||
begin();
|
begin();
|
||||||
@ -257,7 +258,15 @@ void FilterManagerImpl::apply()
|
|||||||
position()));
|
position()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = CommandResult(CommandResult::kOk);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
result = CommandResult(CommandResult::kCanceled);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(m_reader.context());
|
||||||
|
m_reader.context()->setCommandResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterManagerImpl::applyToTarget()
|
void FilterManagerImpl::applyToTarget()
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/commands/filters/filter_manager_impl.h"
|
#include "app/commands/filters/filter_manager_impl.h"
|
||||||
#include "app/console.h"
|
#include "app/console.h"
|
||||||
#include "app/context_access.h"
|
|
||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
#include "app/ini_file.h"
|
#include "app/ini_file.h"
|
||||||
#include "app/modules/editors.h"
|
#include "app/modules/editors.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -14,6 +14,7 @@
|
|||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/context.h"
|
#include "app/context.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
|
#include "app/ui/main_window.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
@ -24,21 +25,39 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#define TRACE_CON(...) // TRACEARGS(__VA_ARGS__)
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
class Console::ConsoleWindow : public Window {
|
Console::ConsoleWindow* Console::m_console = nullptr;
|
||||||
|
|
||||||
|
class Console::ConsoleWindow final : public Window {
|
||||||
public:
|
public:
|
||||||
ConsoleWindow() : Window(Window::WithTitleBar, "Console"),
|
ConsoleWindow() : Window(Window::WithTitleBar, "Console"),
|
||||||
m_textbox("", WORDWRAP),
|
m_textbox("", WORDWRAP),
|
||||||
m_button("Cancel") {
|
m_button("Cancel") {
|
||||||
|
TRACE_CON("CON: ConsoleWindow this=", this);
|
||||||
|
|
||||||
m_button.Click.connect([this]{ closeWindow(&m_button); });
|
m_button.Click.connect([this]{ closeWindow(&m_button); });
|
||||||
|
|
||||||
|
// When the main window is closed, we should close the console (in
|
||||||
|
// other case the main message loop will continue running for the
|
||||||
|
// console too).
|
||||||
|
m_mainWindowClosedConn =
|
||||||
|
App::instance()->mainWindow()->Close.connect(
|
||||||
|
[this]{ closeWindow(nullptr); });
|
||||||
|
|
||||||
// When the window is closed, we clear the text
|
// When the window is closed, we clear the text
|
||||||
Close.connect(
|
Close.connect(
|
||||||
[this]{
|
[this]{
|
||||||
|
m_mainWindowClosedConn.disconnect();
|
||||||
m_textbox.setText(std::string());
|
m_textbox.setText(std::string());
|
||||||
|
|
||||||
|
Console::m_console->deferDelete();
|
||||||
|
Console::m_console = nullptr;
|
||||||
|
TRACE_CON("CON: Close signal");
|
||||||
});
|
});
|
||||||
|
|
||||||
m_view.attachToView(&m_textbox);
|
m_view.attachToView(&m_textbox);
|
||||||
@ -55,17 +74,33 @@ public:
|
|||||||
initTheme();
|
initTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~ConsoleWindow() {
|
||||||
|
TRACE_CON("CON: ~ConsoleWindow this=", this);
|
||||||
|
}
|
||||||
|
|
||||||
void addMessage(const std::string& msg) {
|
void addMessage(const std::string& msg) {
|
||||||
if (!m_hasText) {
|
if (!m_hasText) {
|
||||||
m_hasText = true;
|
m_hasText = true;
|
||||||
centerConsole();
|
centerConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::Size maxSize = m_view.getScrollableSize();
|
||||||
|
gfx::Size visible = m_view.visibleSize();
|
||||||
|
gfx::Point pt = m_view.viewScroll();
|
||||||
|
const bool autoScroll = (pt.y >= maxSize.h - visible.h);
|
||||||
|
|
||||||
m_textbox.setText(m_textbox.text() + msg);
|
m_textbox.setText(m_textbox.text() + msg);
|
||||||
|
|
||||||
|
if (autoScroll) {
|
||||||
|
maxSize = m_view.getScrollableSize();
|
||||||
|
visible = m_view.visibleSize();
|
||||||
|
pt.y = maxSize.h - visible.h;
|
||||||
|
m_view.setViewScroll(pt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isConsoleVisible() const {
|
bool hasConsoleText() const {
|
||||||
return (m_hasText && isVisible());
|
return m_hasText;
|
||||||
}
|
}
|
||||||
|
|
||||||
void centerConsole() {
|
void centerConsole() {
|
||||||
@ -83,19 +118,66 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// As Esc key activates the close button only on foreground windows,
|
||||||
|
// we have to override this method to allow pressing the window
|
||||||
|
// close button using Esc key even in this window (which runs in the
|
||||||
|
// background).
|
||||||
|
bool shouldProcessEscKeyToCloseWindow() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool onProcessMessage(ui::Message* msg) override {
|
bool onProcessMessage(ui::Message* msg) override {
|
||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
|
|
||||||
case ui::kKeyDownMessage:
|
case ui::kKeyDownMessage: {
|
||||||
|
auto scancode = static_cast<KeyMessage*>(msg)->scancode();
|
||||||
|
|
||||||
#if defined __APPLE__
|
#if defined __APPLE__
|
||||||
if (msg->onlyCmdPressed())
|
if (msg->onlyCmdPressed())
|
||||||
#else
|
#else
|
||||||
if (msg->onlyCtrlPressed())
|
if (msg->onlyCtrlPressed())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyC)
|
if (scancode == kKeyC)
|
||||||
set_clipboard_text(m_textbox.text());
|
set_clipboard_text(m_textbox.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Esc to close the window.
|
||||||
|
if (auto closeButton = this->closeButton()) {
|
||||||
|
bool p = msg->propagateToParent();
|
||||||
|
msg->setPropagateToParent(false);
|
||||||
|
|
||||||
|
if (closeButton->sendMessage(msg))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
msg->setPropagateToParent(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send Enter key to the Close button, Tab to change focus
|
||||||
|
if ((scancode == kKeyEnter) ||
|
||||||
|
(scancode == kKeyEnterPad))
|
||||||
|
return m_button.sendMessage(msg);
|
||||||
|
|
||||||
|
if (scancode == kKeyTab) {
|
||||||
|
if (auto mgr = manager())
|
||||||
|
return mgr->processFocusMovementMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All keys are used if we have this window focused (so they
|
||||||
|
// don't trigger commands)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ui::kKeyUpMessage:
|
||||||
|
if (auto closeButton = this->closeButton()) {
|
||||||
|
bool p = msg->propagateToParent();
|
||||||
|
msg->setPropagateToParent(false);
|
||||||
|
|
||||||
|
if (closeButton->sendMessage(msg))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
msg->setPropagateToParent(p);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return Window::onProcessMessage(msg);
|
return Window::onProcessMessage(msg);
|
||||||
@ -107,18 +189,18 @@ private:
|
|||||||
m_button.setMinSize(gfx::Size(60*ui::guiscale(), 0));
|
m_button.setMinSize(gfx::Size(60*ui::guiscale(), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obs::scoped_connection m_mainWindowClosedConn;
|
||||||
View m_view;
|
View m_view;
|
||||||
TextBox m_textbox;
|
TextBox m_textbox;
|
||||||
Button m_button;
|
Button m_button;
|
||||||
bool m_hasText = false;
|
bool m_hasText = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
int Console::m_consoleCounter = 0;
|
|
||||||
std::unique_ptr<Console::ConsoleWindow> Console::m_console = nullptr;
|
|
||||||
|
|
||||||
Console::Console(Context* ctx)
|
Console::Console(Context* ctx)
|
||||||
: m_withUI(false)
|
: m_withUI(false)
|
||||||
{
|
{
|
||||||
|
TRACE_CON("CON: Console this=", this, "ctx=", ctx, "is_ui_thread=", ui::is_ui_thread(), "{");
|
||||||
|
|
||||||
if (!ui::is_ui_thread())
|
if (!ui::is_ui_thread())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -136,27 +218,26 @@ Console::Console(Context* ctx)
|
|||||||
if (!m_withUI)
|
if (!m_withUI)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
++m_consoleCounter;
|
TRACE_CON("CON: -> withUI=", m_withUI);
|
||||||
if (m_console || m_consoleCounter > 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_console.reset(new ConsoleWindow);
|
if (!m_console)
|
||||||
|
m_console = new ConsoleWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::~Console()
|
Console::~Console()
|
||||||
{
|
{
|
||||||
|
TRACE_CON("CON: } ~Console this=", this, "withUI=", m_withUI);
|
||||||
|
|
||||||
if (!m_withUI)
|
if (!m_withUI)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
--m_consoleCounter;
|
if (m_console &&
|
||||||
|
m_console->hasConsoleText() &&
|
||||||
if (m_console && m_console->isConsoleVisible()) {
|
!m_console->isVisible()) {
|
||||||
m_console->manager()->attractFocus(m_console.get());
|
m_console->manager()->attractFocus(m_console);
|
||||||
m_console->openWindowInForeground();
|
m_console->openWindow();
|
||||||
|
TRACE_CON("CON: openWindow");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_consoleCounter == 0)
|
|
||||||
m_console.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::printf(const char* format, ...)
|
void Console::printf(const char* format, ...)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -10,7 +10,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
class Context;
|
class Context;
|
||||||
@ -29,8 +28,7 @@ namespace app {
|
|||||||
class ConsoleWindow;
|
class ConsoleWindow;
|
||||||
|
|
||||||
bool m_withUI;
|
bool m_withUI;
|
||||||
static int m_consoleCounter;
|
static ConsoleWindow* m_console;
|
||||||
static std::unique_ptr<Console::ConsoleWindow> m_console;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -165,6 +165,8 @@ void Context::executeCommand(Command* command, const Params& params)
|
|||||||
if (!command)
|
if (!command)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_result.reset();
|
||||||
|
|
||||||
Console console;
|
Console console;
|
||||||
LOG(VERBOSE, "CTXT: Executing command %s\n", command->id().c_str());
|
LOG(VERBOSE, "CTXT: Executing command %s\n", command->id().c_str());
|
||||||
try {
|
try {
|
||||||
@ -213,17 +215,23 @@ void Context::executeCommand(Command* command, const Params& params)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
catch (base::Exception& e) {
|
catch (base::Exception& e) {
|
||||||
|
m_result = CommandResult(CommandResult::kError);
|
||||||
|
|
||||||
LOG(ERROR, "CTXT: Exception caught executing %s command\n%s\n",
|
LOG(ERROR, "CTXT: Exception caught executing %s command\n%s\n",
|
||||||
command->id().c_str(), e.what());
|
command->id().c_str(), e.what());
|
||||||
Console::showException(e);
|
Console::showException(e);
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
|
m_result = CommandResult(CommandResult::kError);
|
||||||
|
|
||||||
LOG(ERROR, "CTXT: std::exception caught executing %s command\n%s\n",
|
LOG(ERROR, "CTXT: std::exception caught executing %s command\n%s\n",
|
||||||
command->id().c_str(), e.what());
|
command->id().c_str(), e.what());
|
||||||
console.printf("An error ocurred executing the command.\n\nDetails:\n%s", e.what());
|
console.printf("An error ocurred executing the command.\n\nDetails:\n%s", e.what());
|
||||||
}
|
}
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
catch (...) {
|
catch (...) {
|
||||||
|
m_result = CommandResult(CommandResult::kError);
|
||||||
|
|
||||||
LOG(ERROR, "CTXT: Unknown exception executing %s command\n",
|
LOG(ERROR, "CTXT: Unknown exception executing %s command\n",
|
||||||
command->id().c_str());
|
command->id().c_str());
|
||||||
|
|
||||||
@ -236,6 +244,11 @@ void Context::executeCommand(Command* command, const Params& params)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::setCommandResult(const CommandResult& result)
|
||||||
|
{
|
||||||
|
m_result = result;
|
||||||
|
}
|
||||||
|
|
||||||
void Context::onAddDocument(Doc* doc)
|
void Context::onAddDocument(Doc* doc)
|
||||||
{
|
{
|
||||||
m_lastSelectedDoc = doc;
|
m_lastSelectedDoc = doc;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -37,6 +37,24 @@ namespace app {
|
|||||||
class DocView;
|
class DocView;
|
||||||
class Preferences;
|
class Preferences;
|
||||||
|
|
||||||
|
class CommandResult {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
kOk,
|
||||||
|
// Exception throw (e.g. cannot lock sprite)
|
||||||
|
kError,
|
||||||
|
// Canceled by user.
|
||||||
|
kCanceled,
|
||||||
|
};
|
||||||
|
|
||||||
|
CommandResult(Type type = Type::kOk) : m_type(type) { }
|
||||||
|
Type type() const { return m_type; }
|
||||||
|
void reset() { m_type = Type::kOk; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type;
|
||||||
|
};
|
||||||
|
|
||||||
class CommandPreconditionException : public base::Exception {
|
class CommandPreconditionException : public base::Exception {
|
||||||
public:
|
public:
|
||||||
CommandPreconditionException() throw()
|
CommandPreconditionException() throw()
|
||||||
@ -100,6 +118,9 @@ namespace app {
|
|||||||
void executeCommandFromMenuOrShortcut(Command* command, const Params& params = Params());
|
void executeCommandFromMenuOrShortcut(Command* command, const Params& params = Params());
|
||||||
virtual void executeCommand(Command* command, const Params& params = Params());
|
virtual void executeCommand(Command* command, const Params& params = Params());
|
||||||
|
|
||||||
|
void setCommandResult(const CommandResult& result);
|
||||||
|
const CommandResult& commandResult() { return m_result; }
|
||||||
|
|
||||||
virtual DocView* getFirstDocView(Doc* document) const {
|
virtual DocView* getFirstDocView(Doc* document) const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -134,6 +155,9 @@ namespace app {
|
|||||||
Doc* m_lastSelectedDoc;
|
Doc* m_lastSelectedDoc;
|
||||||
mutable std::unique_ptr<Preferences> m_preferences;
|
mutable std::unique_ptr<Preferences> m_preferences;
|
||||||
|
|
||||||
|
// Result of the execution of a command.
|
||||||
|
CommandResult m_result;
|
||||||
|
|
||||||
DISABLE_COPYING(Context);
|
DISABLE_COPYING(Context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -333,9 +333,10 @@ private:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
ObjectId palId = read32(s);
|
ObjectId palId = read32(s);
|
||||||
Palette* pal = loadObject<Palette*>("pal", palId, &Reader::readPalette);
|
std::unique_ptr<Palette> pal(
|
||||||
|
loadObject<Palette*>("pal", palId, &Reader::readPalette));
|
||||||
if (pal)
|
if (pal)
|
||||||
spr->setPalette(pal, true);
|
spr->setPalette(pal.get(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2018 David Capello
|
// Copyright (C) 2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -52,6 +52,15 @@ int Command_call(lua_State* L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx->executeCommand(command, params);
|
ctx->executeCommand(command, params);
|
||||||
|
|
||||||
|
if (ctx->commandResult().type() == CommandResult::kOk) {
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO rollback/cancel the whole current transaction?
|
||||||
|
// or just throw an luaL_error()?
|
||||||
|
lua_pushboolean(L, false);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +270,18 @@ void StateWithWheelBehavior::processWheelAction(
|
|||||||
ToolPreferences::Brush& brush =
|
ToolPreferences::Brush& brush =
|
||||||
Preferences::instance().tool(tool).brush;
|
Preferences::instance().tool(tool).brush;
|
||||||
|
|
||||||
|
#if LAF_WINDOWS || LAF_LINUX
|
||||||
|
// By default on macOS the mouse wheel is correct, up increase
|
||||||
|
// brush size, and down decrease it. But on Windows and Linux
|
||||||
|
// it's inverted.
|
||||||
|
dz = -dz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// We can configure the mouse wheel for brush size to behave as
|
||||||
|
// in previous versions.
|
||||||
|
if (Preferences::instance().editor.invertBrushSizeWheel())
|
||||||
|
dz = -dz;
|
||||||
|
|
||||||
brush.size(
|
brush.size(
|
||||||
base::clamp(
|
base::clamp(
|
||||||
int(initialBrushSize()+dz),
|
int(initialBrushSize()+dz),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -282,6 +282,9 @@ protected:
|
|||||||
bool back = (msg->altPressed() && scancode == kKeyLeft);
|
bool back = (msg->altPressed() && scancode == kKeyLeft);
|
||||||
bool forward = (msg->altPressed() && scancode == kKeyRight);
|
bool forward = (msg->altPressed() && scancode == kKeyRight);
|
||||||
#endif
|
#endif
|
||||||
|
bool refresh = (scancode == kKeyF5 ||
|
||||||
|
(msg->ctrlPressed() && scancode == kKeyR) ||
|
||||||
|
(msg->cmdPressed() && scancode == kKeyR));
|
||||||
|
|
||||||
if (up) {
|
if (up) {
|
||||||
m_filesel->goUp();
|
m_filesel->goUp();
|
||||||
@ -299,6 +302,9 @@ protected:
|
|||||||
m_filesel->goForward();
|
m_filesel->goForward();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (refresh) {
|
||||||
|
m_filesel->refreshCurrentFolder();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,6 +328,7 @@ FileSelector::FileSelector(FileSelectorType type)
|
|||||||
goBackButton()->setFocusStop(false);
|
goBackButton()->setFocusStop(false);
|
||||||
goForwardButton()->setFocusStop(false);
|
goForwardButton()->setFocusStop(false);
|
||||||
goUpButton()->setFocusStop(false);
|
goUpButton()->setFocusStop(false);
|
||||||
|
refreshButton()->setFocusStop(false);
|
||||||
newFolderButton()->setFocusStop(false);
|
newFolderButton()->setFocusStop(false);
|
||||||
viewType()->setFocusStop(false);
|
viewType()->setFocusStop(false);
|
||||||
for (auto child : viewType()->children())
|
for (auto child : viewType()->children())
|
||||||
@ -340,6 +347,7 @@ FileSelector::FileSelector(FileSelectorType type)
|
|||||||
goBackButton()->Click.connect([this]{ onGoBack(); });
|
goBackButton()->Click.connect([this]{ onGoBack(); });
|
||||||
goForwardButton()->Click.connect([this]{ onGoForward(); });
|
goForwardButton()->Click.connect([this]{ onGoForward(); });
|
||||||
goUpButton()->Click.connect([this]{ onGoUp(); });
|
goUpButton()->Click.connect([this]{ onGoUp(); });
|
||||||
|
refreshButton()->Click.connect([this] { onRefreshFolder(); });
|
||||||
newFolderButton()->Click.connect([this]{ onNewFolder(); });
|
newFolderButton()->Click.connect([this]{ onNewFolder(); });
|
||||||
viewType()->ItemChange.connect([this]{ onChangeViewType(); });
|
viewType()->ItemChange.connect([this]{ onChangeViewType(); });
|
||||||
location()->CloseListBox.connect([this]{ onLocationCloseListBox(); });
|
location()->CloseListBox.connect([this]{ onLocationCloseListBox(); });
|
||||||
@ -382,6 +390,11 @@ void FileSelector::goInsideFolder()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileSelector::refreshCurrentFolder()
|
||||||
|
{
|
||||||
|
onRefreshFolder();
|
||||||
|
}
|
||||||
|
|
||||||
bool FileSelector::show(
|
bool FileSelector::show(
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& initialPath,
|
const std::string& initialPath,
|
||||||
@ -876,6 +889,14 @@ void FileSelector::onGoUp()
|
|||||||
m_fileList->goUp();
|
m_fileList->goUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileSelector::onRefreshFolder()
|
||||||
|
{
|
||||||
|
auto fs = FileSystemModule::instance();
|
||||||
|
fs->refresh();
|
||||||
|
|
||||||
|
m_fileList->setCurrentFolder(m_fileList->currentFolder());
|
||||||
|
}
|
||||||
|
|
||||||
void FileSelector::onNewFolder()
|
void FileSelector::onNewFolder()
|
||||||
{
|
{
|
||||||
app::gen::NewFolderWindow window;
|
app::gen::NewFolderWindow window;
|
||||||
|
@ -37,6 +37,7 @@ namespace app {
|
|||||||
void goForward();
|
void goForward();
|
||||||
void goUp();
|
void goUp();
|
||||||
void goInsideFolder();
|
void goInsideFolder();
|
||||||
|
void refreshCurrentFolder();
|
||||||
|
|
||||||
// Shows the dialog to select a file in the program.
|
// Shows the dialog to select a file in the program.
|
||||||
bool show(const std::string& title,
|
bool show(const std::string& title,
|
||||||
@ -60,6 +61,7 @@ namespace app {
|
|||||||
void onFileListFileSelected();
|
void onFileListFileSelected();
|
||||||
void onFileListFileAccepted();
|
void onFileListFileAccepted();
|
||||||
void onFileListCurrentFolderChanged();
|
void onFileListCurrentFolderChanged();
|
||||||
|
void onRefreshFolder();
|
||||||
std::string getSelectedExtension() const;
|
std::string getSelectedExtension() const;
|
||||||
|
|
||||||
class ArrowNavigator;
|
class ArrowNavigator;
|
||||||
|
@ -83,7 +83,7 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case kKeyDownMessage:
|
case kKeyDownMessage:
|
||||||
if (window()->isForeground() &&
|
if (window()->shouldProcessEscKeyToCloseWindow() &&
|
||||||
static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
|
static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
|
||||||
setSelected(true);
|
setSelected(true);
|
||||||
return true;
|
return true;
|
||||||
@ -91,7 +91,7 @@ protected:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kKeyUpMessage:
|
case kKeyUpMessage:
|
||||||
if (window()->isForeground() &&
|
if (window()->shouldProcessEscKeyToCloseWindow() &&
|
||||||
static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
|
static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
|
||||||
if (isSelected()) {
|
if (isSelected()) {
|
||||||
setSelected(false);
|
setSelected(false);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -72,11 +72,20 @@ namespace ui {
|
|||||||
gfx::Rect lastNativeFrame() const { return m_lastFrame; }
|
gfx::Rect lastNativeFrame() const { return m_lastFrame; }
|
||||||
void loadNativeFrame(const gfx::Rect& frame);
|
void loadNativeFrame(const gfx::Rect& frame);
|
||||||
|
|
||||||
|
// Esc key closes the current window (presses the little close
|
||||||
|
// button decorator) only on foreground windows, but you can
|
||||||
|
// override this to allow this behavior in other kind of windows.
|
||||||
|
virtual bool shouldProcessEscKeyToCloseWindow() const {
|
||||||
|
return isForeground();
|
||||||
|
}
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
obs::signal<void (Event&)> Open;
|
obs::signal<void (Event&)> Open;
|
||||||
obs::signal<void (CloseEvent&)> Close;
|
obs::signal<void (CloseEvent&)> Close;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ButtonBase* closeButton() { return m_closeButton; }
|
||||||
|
|
||||||
virtual bool onProcessMessage(Message* msg) override;
|
virtual bool onProcessMessage(Message* msg) override;
|
||||||
virtual void onInvalidateRegion(const gfx::Region& region) override;
|
virtual void onInvalidateRegion(const gfx::Region& region) override;
|
||||||
virtual void onResize(ResizeEvent& ev) override;
|
virtual void onResize(ResizeEvent& ev) override;
|
||||||
|
2
third_party/IXWebSocket
vendored
2
third_party/IXWebSocket
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 9bbd1f1b30bfa6fb52bf1388ab336ef39d0faead
|
Subproject commit b6f36191c2022f5936f272da82dcaa36b9114918
|
Loading…
x
Reference in New Issue
Block a user