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
|
||||
[submodule "third_party/IXWebSocket"]
|
||||
path = third_party/IXWebSocket
|
||||
url = https://github.com/machinezone/IXWebSocket
|
||||
url = https://github.com/aseprite/IXWebSocket.git
|
||||
[submodule "third_party/cityhash"]
|
||||
path = third_party/cityhash
|
||||
url = https://github.com/aseprite/cityhash.git
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Aseprite
|
||||
# Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
# Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
# Copyright (C) 2001-2018 David Capello
|
||||
|
||||
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_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)
|
||||
# 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_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="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_selected" x="115" y="211" 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_disabled" state="disabled" />
|
||||
</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">
|
||||
<icon part="newfolder" />
|
||||
<icon part="newfolder_selected" state="selected" />
|
||||
|
@ -158,6 +158,7 @@
|
||||
<option id="show_menu_bar" type="bool" default="true" />
|
||||
<option id="recent_items" type="int" default="16" />
|
||||
<option id="osx_async_view" type="bool" default="true" />
|
||||
<option id="x11_stylus_id" type="std::string" />
|
||||
</section>
|
||||
<section id="undo" text="Undo">
|
||||
<option id="size_limit" type="int" default="0" />
|
||||
@ -170,6 +171,7 @@
|
||||
<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_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="auto_scroll" type="bool" default="true" />
|
||||
<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_forward_button_tooltip = Go forward one folder
|
||||
go_up_button_tooltip = Up to parent folder
|
||||
refresh_button_tooltip = Refresh folder view
|
||||
new_folder_button_tooltip = New folder
|
||||
list_view_button_tooltip = List View
|
||||
small_icon_view_button_tooltip = Small Icons View
|
||||
@ -851,6 +852,7 @@ section_drag_value = Drag Value
|
||||
default_wheel_behavior = Default
|
||||
custom_wheel_behavior = Custom
|
||||
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_tooltip = Direction of the mouse to indicate an increment of the value
|
||||
drag_distance = Distance:
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2019 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2019-2022 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2001-2018 David Capello -->
|
||||
<gui>
|
||||
<window id="file_selector" text="">
|
||||
@ -21,6 +21,8 @@
|
||||
<item icon="big_icon_view" tooltip="@.big_icon_view_button_tooltip" tooltip_dir="bottom" />
|
||||
</buttonset>
|
||||
<combobox id="location" expansive="true" />
|
||||
<button text="" id="refresh_button" style="refresh_button"
|
||||
tooltip="@.refresh_button_tooltip" tooltip_dir="bottom" />
|
||||
</box>
|
||||
<vbox id="file_view_placeholder" expansive="true" />
|
||||
<grid columns="2">
|
||||
|
@ -50,6 +50,8 @@
|
||||
pref="editor.zoom_with_wheel" />
|
||||
<check text="@options.slide_zoom" id="slide_zoom"
|
||||
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">
|
||||
<listbox id="wheel_actions" />
|
||||
</view>
|
||||
|
2
laf
2
laf
@ -1 +1 @@
|
||||
Subproject commit df53f4ac0cecada789bf84b4283947d2591833bd
|
||||
Subproject commit 8f9e7892e0da31e423e224b199f53d8ffefce32b
|
@ -71,6 +71,8 @@
|
||||
|
||||
#if LAF_MACOS
|
||||
#include "os/osx/system.h"
|
||||
#elif LAF_LINUX
|
||||
#include "os/x11/system.h"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@ -95,6 +97,7 @@ namespace {
|
||||
|
||||
class ConsoleEngineDelegate : public script::EngineDelegate {
|
||||
public:
|
||||
ConsoleEngineDelegate(Console& console) : m_console(console) { }
|
||||
void onConsoleError(const char* text) override {
|
||||
onConsolePrint(text);
|
||||
}
|
||||
@ -102,7 +105,7 @@ public:
|
||||
m_console.printf("%s\n", text);
|
||||
}
|
||||
private:
|
||||
Console m_console;
|
||||
Console& m_console;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
@ -236,6 +239,7 @@ int App::initialize(const AppOptions& options)
|
||||
m_coreModules = new CoreModules;
|
||||
|
||||
#if LAF_WINDOWS
|
||||
|
||||
if (options.disableWintab() ||
|
||||
!preferences().experimental.loadWintabDriver() ||
|
||||
preferences().tablet.api() == "pointer") {
|
||||
@ -245,11 +249,20 @@ int App::initialize(const AppOptions& options)
|
||||
system->setTabletAPI(os::TabletAPI::WintabPackets);
|
||||
else // preferences().tablet.api() == "wintab"
|
||||
system->setTabletAPI(os::TabletAPI::Wintab);
|
||||
#endif
|
||||
|
||||
#if LAF_MACOS
|
||||
#elif LAF_MACOS
|
||||
|
||||
if (!preferences().general.osxAsyncView())
|
||||
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
|
||||
|
||||
system->setAppName(get_app_name());
|
||||
@ -485,7 +498,7 @@ void App::run()
|
||||
Console console;
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
// Use the app::Console() for script errors
|
||||
ConsoleEngineDelegate delegate;
|
||||
ConsoleEngineDelegate delegate(console);
|
||||
script::ScopedEngineDelegate setEngineDelegate(m_engine.get(), &delegate);
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -206,6 +206,7 @@ bool FilterManagerImpl::applyStep()
|
||||
|
||||
void FilterManagerImpl::apply()
|
||||
{
|
||||
CommandResult result;
|
||||
bool cancelled = false;
|
||||
|
||||
begin();
|
||||
@ -257,7 +258,15 @@ void FilterManagerImpl::apply()
|
||||
position()));
|
||||
}
|
||||
}
|
||||
|
||||
result = CommandResult(CommandResult::kOk);
|
||||
}
|
||||
else {
|
||||
result = CommandResult(CommandResult::kCanceled);
|
||||
}
|
||||
|
||||
ASSERT(m_reader.context());
|
||||
m_reader.context()->setCommandResult(result);
|
||||
}
|
||||
|
||||
void FilterManagerImpl::applyToTarget()
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "app/app.h"
|
||||
#include "app/commands/filters/filter_manager_impl.h"
|
||||
#include "app/console.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/i18n/strings.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "app/modules/editors.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -14,6 +14,7 @@
|
||||
#include "app/app.h"
|
||||
#include "app/context.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "base/memory.h"
|
||||
#include "base/string.h"
|
||||
@ -24,21 +25,39 @@
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
|
||||
#define TRACE_CON(...) // TRACEARGS(__VA_ARGS__)
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
class Console::ConsoleWindow : public Window {
|
||||
Console::ConsoleWindow* Console::m_console = nullptr;
|
||||
|
||||
class Console::ConsoleWindow final : public Window {
|
||||
public:
|
||||
ConsoleWindow() : Window(Window::WithTitleBar, "Console"),
|
||||
m_textbox("", WORDWRAP),
|
||||
m_button("Cancel") {
|
||||
TRACE_CON("CON: ConsoleWindow this=", this);
|
||||
|
||||
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
|
||||
Close.connect(
|
||||
[this]{
|
||||
m_mainWindowClosedConn.disconnect();
|
||||
m_textbox.setText(std::string());
|
||||
|
||||
Console::m_console->deferDelete();
|
||||
Console::m_console = nullptr;
|
||||
TRACE_CON("CON: Close signal");
|
||||
});
|
||||
|
||||
m_view.attachToView(&m_textbox);
|
||||
@ -55,17 +74,33 @@ public:
|
||||
initTheme();
|
||||
}
|
||||
|
||||
~ConsoleWindow() {
|
||||
TRACE_CON("CON: ~ConsoleWindow this=", this);
|
||||
}
|
||||
|
||||
void addMessage(const std::string& msg) {
|
||||
if (!m_hasText) {
|
||||
m_hasText = true;
|
||||
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);
|
||||
|
||||
if (autoScroll) {
|
||||
maxSize = m_view.getScrollableSize();
|
||||
visible = m_view.visibleSize();
|
||||
pt.y = maxSize.h - visible.h;
|
||||
m_view.setViewScroll(pt);
|
||||
}
|
||||
}
|
||||
|
||||
bool isConsoleVisible() const {
|
||||
return (m_hasText && isVisible());
|
||||
bool hasConsoleText() const {
|
||||
return m_hasText;
|
||||
}
|
||||
|
||||
void centerConsole() {
|
||||
@ -83,19 +118,66 @@ public:
|
||||
}
|
||||
|
||||
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 {
|
||||
switch (msg->type()) {
|
||||
|
||||
case ui::kKeyDownMessage:
|
||||
case ui::kKeyDownMessage: {
|
||||
auto scancode = static_cast<KeyMessage*>(msg)->scancode();
|
||||
|
||||
#if defined __APPLE__
|
||||
if (msg->onlyCmdPressed())
|
||||
#else
|
||||
if (msg->onlyCtrlPressed())
|
||||
#endif
|
||||
{
|
||||
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyC)
|
||||
if (scancode == kKeyC)
|
||||
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;
|
||||
}
|
||||
return Window::onProcessMessage(msg);
|
||||
@ -107,18 +189,18 @@ private:
|
||||
m_button.setMinSize(gfx::Size(60*ui::guiscale(), 0));
|
||||
}
|
||||
|
||||
obs::scoped_connection m_mainWindowClosedConn;
|
||||
View m_view;
|
||||
TextBox m_textbox;
|
||||
Button m_button;
|
||||
bool m_hasText = false;
|
||||
};
|
||||
|
||||
int Console::m_consoleCounter = 0;
|
||||
std::unique_ptr<Console::ConsoleWindow> Console::m_console = nullptr;
|
||||
|
||||
Console::Console(Context* ctx)
|
||||
: m_withUI(false)
|
||||
{
|
||||
TRACE_CON("CON: Console this=", this, "ctx=", ctx, "is_ui_thread=", ui::is_ui_thread(), "{");
|
||||
|
||||
if (!ui::is_ui_thread())
|
||||
return;
|
||||
|
||||
@ -136,27 +218,26 @@ Console::Console(Context* ctx)
|
||||
if (!m_withUI)
|
||||
return;
|
||||
|
||||
++m_consoleCounter;
|
||||
if (m_console || m_consoleCounter > 1)
|
||||
return;
|
||||
TRACE_CON("CON: -> withUI=", m_withUI);
|
||||
|
||||
m_console.reset(new ConsoleWindow);
|
||||
if (!m_console)
|
||||
m_console = new ConsoleWindow;
|
||||
}
|
||||
|
||||
Console::~Console()
|
||||
{
|
||||
TRACE_CON("CON: } ~Console this=", this, "withUI=", m_withUI);
|
||||
|
||||
if (!m_withUI)
|
||||
return;
|
||||
|
||||
--m_consoleCounter;
|
||||
|
||||
if (m_console && m_console->isConsoleVisible()) {
|
||||
m_console->manager()->attractFocus(m_console.get());
|
||||
m_console->openWindowInForeground();
|
||||
if (m_console &&
|
||||
m_console->hasConsoleText() &&
|
||||
!m_console->isVisible()) {
|
||||
m_console->manager()->attractFocus(m_console);
|
||||
m_console->openWindow();
|
||||
TRACE_CON("CON: openWindow");
|
||||
}
|
||||
|
||||
if (m_consoleCounter == 0)
|
||||
m_console.reset();
|
||||
}
|
||||
|
||||
void Console::printf(const char* format, ...)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -10,7 +10,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
|
||||
namespace app {
|
||||
class Context;
|
||||
@ -29,8 +28,7 @@ namespace app {
|
||||
class ConsoleWindow;
|
||||
|
||||
bool m_withUI;
|
||||
static int m_consoleCounter;
|
||||
static std::unique_ptr<Console::ConsoleWindow> m_console;
|
||||
static ConsoleWindow* m_console;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -165,6 +165,8 @@ void Context::executeCommand(Command* command, const Params& params)
|
||||
if (!command)
|
||||
return;
|
||||
|
||||
m_result.reset();
|
||||
|
||||
Console console;
|
||||
LOG(VERBOSE, "CTXT: Executing command %s\n", command->id().c_str());
|
||||
try {
|
||||
@ -213,17 +215,23 @@ void Context::executeCommand(Command* command, const Params& params)
|
||||
#endif
|
||||
}
|
||||
catch (base::Exception& e) {
|
||||
m_result = CommandResult(CommandResult::kError);
|
||||
|
||||
LOG(ERROR, "CTXT: Exception caught executing %s command\n%s\n",
|
||||
command->id().c_str(), e.what());
|
||||
Console::showException(e);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
m_result = CommandResult(CommandResult::kError);
|
||||
|
||||
LOG(ERROR, "CTXT: std::exception caught executing %s command\n%s\n",
|
||||
command->id().c_str(), e.what());
|
||||
console.printf("An error ocurred executing the command.\n\nDetails:\n%s", e.what());
|
||||
}
|
||||
#ifdef NDEBUG
|
||||
catch (...) {
|
||||
m_result = CommandResult(CommandResult::kError);
|
||||
|
||||
LOG(ERROR, "CTXT: Unknown exception executing %s command\n",
|
||||
command->id().c_str());
|
||||
|
||||
@ -236,6 +244,11 @@ void Context::executeCommand(Command* command, const Params& params)
|
||||
#endif
|
||||
}
|
||||
|
||||
void Context::setCommandResult(const CommandResult& result)
|
||||
{
|
||||
m_result = result;
|
||||
}
|
||||
|
||||
void Context::onAddDocument(Doc* doc)
|
||||
{
|
||||
m_lastSelectedDoc = doc;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -37,6 +37,24 @@ namespace app {
|
||||
class DocView;
|
||||
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 {
|
||||
public:
|
||||
CommandPreconditionException() throw()
|
||||
@ -100,6 +118,9 @@ namespace app {
|
||||
void executeCommandFromMenuOrShortcut(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 {
|
||||
return nullptr;
|
||||
}
|
||||
@ -134,6 +155,9 @@ namespace app {
|
||||
Doc* m_lastSelectedDoc;
|
||||
mutable std::unique_ptr<Preferences> m_preferences;
|
||||
|
||||
// Result of the execution of a command.
|
||||
CommandResult m_result;
|
||||
|
||||
DISABLE_COPYING(Context);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -333,9 +333,10 @@ private:
|
||||
return nullptr;
|
||||
|
||||
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)
|
||||
spr->setPalette(pal, true);
|
||||
spr->setPalette(pal.get(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -52,6 +52,15 @@ int Command_call(lua_State* L)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,18 @@ void StateWithWheelBehavior::processWheelAction(
|
||||
ToolPreferences::Brush& 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(
|
||||
base::clamp(
|
||||
int(initialBrushSize()+dz),
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -282,6 +282,9 @@ protected:
|
||||
bool back = (msg->altPressed() && scancode == kKeyLeft);
|
||||
bool forward = (msg->altPressed() && scancode == kKeyRight);
|
||||
#endif
|
||||
bool refresh = (scancode == kKeyF5 ||
|
||||
(msg->ctrlPressed() && scancode == kKeyR) ||
|
||||
(msg->cmdPressed() && scancode == kKeyR));
|
||||
|
||||
if (up) {
|
||||
m_filesel->goUp();
|
||||
@ -299,6 +302,9 @@ protected:
|
||||
m_filesel->goForward();
|
||||
return true;
|
||||
}
|
||||
if (refresh) {
|
||||
m_filesel->refreshCurrentFolder();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -322,6 +328,7 @@ FileSelector::FileSelector(FileSelectorType type)
|
||||
goBackButton()->setFocusStop(false);
|
||||
goForwardButton()->setFocusStop(false);
|
||||
goUpButton()->setFocusStop(false);
|
||||
refreshButton()->setFocusStop(false);
|
||||
newFolderButton()->setFocusStop(false);
|
||||
viewType()->setFocusStop(false);
|
||||
for (auto child : viewType()->children())
|
||||
@ -340,6 +347,7 @@ FileSelector::FileSelector(FileSelectorType type)
|
||||
goBackButton()->Click.connect([this]{ onGoBack(); });
|
||||
goForwardButton()->Click.connect([this]{ onGoForward(); });
|
||||
goUpButton()->Click.connect([this]{ onGoUp(); });
|
||||
refreshButton()->Click.connect([this] { onRefreshFolder(); });
|
||||
newFolderButton()->Click.connect([this]{ onNewFolder(); });
|
||||
viewType()->ItemChange.connect([this]{ onChangeViewType(); });
|
||||
location()->CloseListBox.connect([this]{ onLocationCloseListBox(); });
|
||||
@ -382,6 +390,11 @@ void FileSelector::goInsideFolder()
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelector::refreshCurrentFolder()
|
||||
{
|
||||
onRefreshFolder();
|
||||
}
|
||||
|
||||
bool FileSelector::show(
|
||||
const std::string& title,
|
||||
const std::string& initialPath,
|
||||
@ -876,6 +889,14 @@ void FileSelector::onGoUp()
|
||||
m_fileList->goUp();
|
||||
}
|
||||
|
||||
void FileSelector::onRefreshFolder()
|
||||
{
|
||||
auto fs = FileSystemModule::instance();
|
||||
fs->refresh();
|
||||
|
||||
m_fileList->setCurrentFolder(m_fileList->currentFolder());
|
||||
}
|
||||
|
||||
void FileSelector::onNewFolder()
|
||||
{
|
||||
app::gen::NewFolderWindow window;
|
||||
|
@ -37,6 +37,7 @@ namespace app {
|
||||
void goForward();
|
||||
void goUp();
|
||||
void goInsideFolder();
|
||||
void refreshCurrentFolder();
|
||||
|
||||
// Shows the dialog to select a file in the program.
|
||||
bool show(const std::string& title,
|
||||
@ -60,6 +61,7 @@ namespace app {
|
||||
void onFileListFileSelected();
|
||||
void onFileListFileAccepted();
|
||||
void onFileListCurrentFolderChanged();
|
||||
void onRefreshFolder();
|
||||
std::string getSelectedExtension() const;
|
||||
|
||||
class ArrowNavigator;
|
||||
|
@ -83,7 +83,7 @@ protected:
|
||||
return true;
|
||||
|
||||
case kKeyDownMessage:
|
||||
if (window()->isForeground() &&
|
||||
if (window()->shouldProcessEscKeyToCloseWindow() &&
|
||||
static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
|
||||
setSelected(true);
|
||||
return true;
|
||||
@ -91,7 +91,7 @@ protected:
|
||||
break;
|
||||
|
||||
case kKeyUpMessage:
|
||||
if (window()->isForeground() &&
|
||||
if (window()->shouldProcessEscKeyToCloseWindow() &&
|
||||
static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
|
||||
if (isSelected()) {
|
||||
setSelected(false);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -72,11 +72,20 @@ namespace ui {
|
||||
gfx::Rect lastNativeFrame() const { return m_lastFrame; }
|
||||
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
|
||||
obs::signal<void (Event&)> Open;
|
||||
obs::signal<void (CloseEvent&)> Close;
|
||||
|
||||
protected:
|
||||
ButtonBase* closeButton() { return m_closeButton; }
|
||||
|
||||
virtual bool onProcessMessage(Message* msg) override;
|
||||
virtual void onInvalidateRegion(const gfx::Region& region) 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