diff --git a/data/gui.xml b/data/gui.xml
index 4fdf1a658..530692b97 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -636,6 +636,7 @@
diff --git a/data/pref.xml b/data/pref.xml
index a18597331..b2534bd03 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -28,6 +28,8 @@
+
+
diff --git a/data/strings/en.ini b/data/strings/en.ini
index 49f2431c4..b32213bea 100644
--- a/data/strings/en.ini
+++ b/data/strings/en.ini
@@ -806,6 +806,7 @@ file_export_sprite_sheet = &Export Sprite Sheet
file_repeat_last_export = Repeat &Last Export
file_scripts = Scri&pts
file_open_script_folder = &Open Scripts Folder
+file_rescan_script_folder = &Rescan Scripts Folder
file_exit = E&xit
edit = &Edit
edit_undo = &Undo
@@ -1185,8 +1186,10 @@ simple_crosshair = Simple Crosshair
crosshair_on_sprite = Crosshair on Sprite
brush_preview = Brush Preview:
brush_preview_none = None
-brush_preview_edges = Brush Edges
-brush_preview_full = Full Real-time Brush Preview
+brush_preview_edges = Edges Only
+brush_preview_full = Full Preview
+brush_preview_fullall = Full Preview with All Tools
+brush_preview_fullnedges = Full Preview and Edges
cursor_color_type = Crosshair && Brush Edges Color:
cursor_neg_bw = Negative Black and White
cursor_specific_color = Specific Color
diff --git a/data/widgets/options.xml b/data/widgets/options.xml
index c606d86d8..cb51d04a0 100644
--- a/data/widgets/options.xml
+++ b/data/widgets/options.xml
@@ -292,6 +292,8 @@
+
+
diff --git a/laf b/laf
index ab08b047d..c6a00f92f 160000
--- a/laf
+++ b/laf
@@ -1 +1 @@
-Subproject commit ab08b047defdd3390e3aaa55a02c6a10225496ac
+Subproject commit c6a00f92ff4f073864db99e48c415997381cd88a
diff --git a/src/app/cmd/add_cel.cpp b/src/app/cmd/add_cel.cpp
index e6a3c0813..d34d800ef 100644
--- a/src/app/cmd/add_cel.cpp
+++ b/src/app/cmd/add_cel.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -108,10 +109,13 @@ void AddCel::removeCel(Layer* layer, Cel* cel)
ev.sprite(layer->sprite());
ev.layer(layer);
ev.cel(cel);
- doc->notify_observers(&DocObserver::onRemoveCel, ev);
+ doc->notify_observers(&DocObserver::onBeforeRemoveCel, ev);
static_cast(layer)->removeCel(cel);
layer->incrementVersion();
+
+ doc->notify_observers(&DocObserver::onAfterRemoveCel, ev);
+
delete cel;
}
diff --git a/src/app/commands/cmd_cel_properties.cpp b/src/app/commands/cmd_cel_properties.cpp
index 43a7e60b7..1c976e593 100644
--- a/src/app/commands/cmd_cel_properties.cpp
+++ b/src/app/commands/cmd_cel_properties.cpp
@@ -230,6 +230,11 @@ private:
}
// DocObserver impl
+ void onBeforeRemoveCel(DocEvent& ev) override {
+ if (m_cel == ev.cel())
+ setCel(m_document, nullptr);
+ }
+
void onCelOpacityChange(DocEvent& ev) override {
if (m_cel == ev.cel())
updateFromCel();
diff --git a/src/app/commands/cmd_refresh.cpp b/src/app/commands/cmd_refresh.cpp
index a58b31732..31596469b 100644
--- a/src/app/commands/cmd_refresh.cpp
+++ b/src/app/commands/cmd_refresh.cpp
@@ -10,7 +10,10 @@
#endif
#include "app/app.h"
+#include "app/app_menus.h"
#include "app/commands/command.h"
+#include "app/ui/main_menu_bar.h"
+#include "app/ui/main_window.h"
#include "app/ui/status_bar.h"
#include "fmt/format.h"
#include "ui/scale.h"
@@ -40,8 +43,15 @@ RefreshCommand::RefreshCommand()
void RefreshCommand::onExecute(Context* context)
{
+ // Reload menus (mainly to reload the File > Scripts menu)
+ //AppMenus::instance()->reload();
+ App::instance()->mainWindow()->getMenuBar()->reload();
+
+ // Reload theme
ui::set_theme(ui::get_theme(),
ui::guiscale());
+
+ // Redraw screen
app_refresh_screen();
// Print memory information
diff --git a/src/app/commands/command.cpp b/src/app/commands/command.cpp
index 0764b383f..4ac363209 100644
--- a/src/app/commands/command.cpp
+++ b/src/app/commands/command.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@@ -21,7 +22,10 @@ Command::Command(const char* id, CommandFlags flags)
{
std::string strId = "commands.";
strId += this->id();
- m_friendlyName = Strings::instance()->translate(strId.c_str());
+ if (auto s = Strings::instance())
+ m_friendlyName = s->translate(strId.c_str());
+ else
+ m_friendlyName = strId;
}
Command::~Command()
diff --git a/src/app/commands/new_params.cpp b/src/app/commands/new_params.cpp
index b7567f935..a7f8be407 100644
--- a/src/app/commands/new_params.cpp
+++ b/src/app/commands/new_params.cpp
@@ -357,7 +357,7 @@ void Param::fromLua(lua_State* L, int index)
template<>
void Param::fromLua(lua_State* L, int index)
{
- script::get_value_from_lua(L, index);
+ setValue(script::get_value_from_lua(L, index));
}
template<>
diff --git a/src/app/context.cpp b/src/app/context.cpp
index 3a62da3e7..078dd9126 100644
--- a/src/app/context.cpp
+++ b/src/app/context.cpp
@@ -148,7 +148,11 @@ void Context::executeCommand(Command* command, const Params& params)
try {
m_flags.update(this);
+#if 0
+ // params.empty() can be empty when we call the command from Lua
+ // with a table.
ASSERT(!command->needsParams() || !params.empty());
+#endif
command->loadParams(params);
diff --git a/src/app/doc_observer.h b/src/app/doc_observer.h
index 904c40812..7c958c120 100644
--- a/src/app/doc_observer.h
+++ b/src/app/doc_observer.h
@@ -40,7 +40,8 @@ namespace app {
// removed, and the sprite's total number of frames is modified.
virtual void onRemoveFrame(DocEvent& ev) { }
virtual void onRemoveTag(DocEvent& ev) { }
- virtual void onRemoveCel(DocEvent& ev) { }
+ virtual void onBeforeRemoveCel(DocEvent& ev) { }
+ virtual void onAfterRemoveCel(DocEvent& ev) { }
virtual void onRemoveSlice(DocEvent& ev) { }
virtual void onSpriteSizeChanged(DocEvent& ev) { }
diff --git a/src/app/tools/controllers.h b/src/app/tools/controllers.h
index 777ab73a3..4b5bb1dda 100644
--- a/src/app/tools/controllers.h
+++ b/src/app/tools/controllers.h
@@ -153,6 +153,8 @@ public:
stroke[0] = m_first;
stroke[1] = pt;
+ bool isoAngle = false;
+
if ((int(loop->getModifiers()) & int(ToolLoopModifiers::kSquareAspect))) {
int dx = stroke[1].x - m_first.x;
int dy = stroke[1].y - m_first.y;
@@ -173,6 +175,7 @@ public:
else if (angle < 36.0) {
stroke[1].x = m_first.x + SGN(dx)*maxsize;
stroke[1].y = m_first.y + SGN(dy)*maxsize/2;
+ isoAngle = true;
}
// Snap at 45
else if (angle < 54.0) {
@@ -183,6 +186,7 @@ public:
else if (angle < 72.0) {
stroke[1].x = m_first.x + SGN(dx)*maxsize/2;
stroke[1].y = m_first.y + SGN(dy)*maxsize;
+ isoAngle = true;
}
// Snap vertically
else {
@@ -207,8 +211,8 @@ public:
else if ((int(loop->getModifiers()) & int(ToolLoopModifiers::kFromCenter))) {
int rx = stroke[1].x - m_first.x;
int ry = stroke[1].y - m_first.y;
- stroke[0].x = m_first.x - rx;
- stroke[0].y = m_first.y - ry;
+ stroke[0].x = m_first.x - rx + (isoAngle && ABS(rx) > ABS(ry) ? SGN(rx)*(rx & 1): 0);
+ stroke[0].y = m_first.y - ry + (isoAngle && ABS(rx) < ABS(ry) ? SGN(ry)*(ry & 1): 0);
stroke[1].x = m_first.x + rx;
stroke[1].y = m_first.y + ry;
}
diff --git a/src/app/tools/intertwine.cpp b/src/app/tools/intertwine.cpp
index 0e963e6b2..e4d9f6042 100644
--- a/src/app/tools/intertwine.cpp
+++ b/src/app/tools/intertwine.cpp
@@ -127,7 +127,8 @@ doc::AlgoLineWithAlgoPixel Intertwine::getLineAlgo(ToolLoop* loop,
const Stroke::Pt& b)
{
bool needsFixForLineBrush = false;
- if (loop->getBrush()->type() == kLineBrushType) {
+ if ((loop->getBrush()->type() == kLineBrushType) &&
+ (a.size > 1.0 || b.size > 1.0)) {
if ((a.angle != 0.0f || b.angle != 0.0f) &&
(a.angle != b.angle)) {
needsFixForLineBrush = true;
diff --git a/src/app/ui/doc_view.cpp b/src/app/ui/doc_view.cpp
index bdfe24b57..27418219f 100644
--- a/src/app/ui/doc_view.cpp
+++ b/src/app/ui/doc_view.cpp
@@ -428,7 +428,7 @@ void DocView::onAddCel(DocEvent& ev)
UIContext::instance()->notifyActiveSiteChanged();
}
-void DocView::onRemoveCel(DocEvent& ev)
+void DocView::onAfterRemoveCel(DocEvent& ev)
{
// This can happen when we apply a filter that clear the whole cel
// and then the cel is removed in a background/job
diff --git a/src/app/ui/doc_view.h b/src/app/ui/doc_view.h
index 14b8507ab..ad4d7b370 100644
--- a/src/app/ui/doc_view.h
+++ b/src/app/ui/doc_view.h
@@ -78,7 +78,7 @@ namespace app {
void onRemoveFrame(DocEvent& ev) override;
void onTagChange(DocEvent& ev) override;
void onAddCel(DocEvent& ev) override;
- void onRemoveCel(DocEvent& ev) override;
+ void onAfterRemoveCel(DocEvent& ev) override;
void onTotalFramesChanged(DocEvent& ev) override;
void onLayerRestacked(DocEvent& ev) override;
diff --git a/src/app/ui/editor/brush_preview.cpp b/src/app/ui/editor/brush_preview.cpp
index 51f493694..267a58467 100644
--- a/src/app/ui/editor/brush_preview.cpp
+++ b/src/app/ui/editor/brush_preview.cpp
@@ -149,7 +149,7 @@ void BrushPreview::show(const gfx::Point& screenPos)
(ink->isEffect()) ||
// or when the brush color is transparent and we are not in the background layer
(!ink->isShading() &&
- (layer && !layer->isBackground()) &&
+ (layer && layer->isTransparent()) &&
((sprite->pixelFormat() == IMAGE_INDEXED && brush_color == mask_index) ||
(sprite->pixelFormat() == IMAGE_RGB && rgba_geta(brush_color) == 0) ||
(sprite->pixelFormat() == IMAGE_GRAYSCALE && graya_geta(brush_color) == 0))))) {
@@ -160,6 +160,8 @@ void BrushPreview::show(const gfx::Point& screenPos)
}
bool showPreview = false;
+ bool showPreviewWithEdges = false;
+ bool cancelEdges = false;
auto brushPreview = pref.cursor.brushPreview();
if (!m_editor->docPref().show.brushPreview())
brushPreview = app::gen::BrushPreview::NONE;
@@ -172,7 +174,20 @@ void BrushPreview::show(const gfx::Point& screenPos)
m_type = BRUSH_BOUNDARIES;
break;
case app::gen::BrushPreview::FULL:
+ case app::gen::BrushPreview::FULLALL:
+ case app::gen::BrushPreview::FULLNEDGES:
showPreview = m_editor->getState()->requireBrushPreview();
+ switch (brushPreview) {
+ case app::gen::BrushPreview::FULLALL:
+ if (showPreview)
+ m_type = CROSSHAIR;
+ cancelEdges = true;
+ break;
+ case app::gen::BrushPreview::FULLNEDGES:
+ if (showPreview)
+ showPreviewWithEdges = true;
+ break;
+ }
break;
}
@@ -183,6 +198,8 @@ void BrushPreview::show(const gfx::Point& screenPos)
// layer) we don't show the brush preview temporally.
if (showPreview && m_editor->isExtraCelLocked()) {
showPreview = false;
+ showPreviewWithEdges = false;
+ cancelEdges = false;
m_type |= BRUSH_BOUNDARIES;
}
@@ -195,9 +212,12 @@ void BrushPreview::show(const gfx::Point& screenPos)
// For cursor type 'bounds' we have to generate cursor boundaries
if (m_type & BRUSH_BOUNDARIES) {
if (brush->type() != kImageBrushType)
- showPreview = false;
- generateBoundaries();
+ showPreview = showPreviewWithEdges;
+ if (cancelEdges)
+ m_type &= ~BRUSH_BOUNDARIES;
}
+ if (m_type & BRUSH_BOUNDARIES)
+ generateBoundaries();
// Draw pixel/brush preview
if (showPreview) {
diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp
index e9ac060ce..e30240d9c 100644
--- a/src/app/ui/editor/editor.cpp
+++ b/src/app/ui/editor/editor.cpp
@@ -159,6 +159,7 @@ Editor::Editor(Doc* document, EditorFlags flags)
, m_aniSpeed(1.0)
, m_isPlaying(false)
, m_showGuidesThisCel(nullptr)
+ , m_showAutoCelGuides(false)
, m_tagFocusBand(-1)
{
if (!m_renderEngine)
@@ -875,8 +876,7 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
}
// Draw active layer/cel edges
- bool showGuidesThisCel = this->showAutoCelGuides();
- if ((m_docPref.show.layerEdges() || showGuidesThisCel) &&
+ if ((m_docPref.show.layerEdges() || m_showAutoCelGuides) &&
// Show layer edges only on "standby" like states where brush
// preview is shown (e.g. with this we avoid to showing the
// edges in states like DrawingState, etc.).
@@ -887,9 +887,10 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
g, cel,
color_utils::color_for_ui(Preferences::instance().guides.layerEdgesColor()));
- if (showGuidesThisCel &&
- m_showGuidesThisCel != cel)
+ if (m_showAutoCelGuides &&
+ m_showGuidesThisCel != cel) {
drawCelGuides(g, cel, m_showGuidesThisCel);
+ }
}
}
@@ -1764,6 +1765,9 @@ bool Editor::onProcessMessage(Message* msg)
case kMouseLeaveMessage:
m_brushPreview.hide();
StatusBar::instance()->showDefaultText();
+
+ // Hide autoguides
+ updateAutoCelGuides(nullptr);
break;
case kMouseDownMessage:
@@ -2149,7 +2153,7 @@ void Editor::onBeforeRemoveLayer(DocEvent& ev)
setLayer(layerToSelect);
}
-void Editor::onRemoveCel(DocEvent& ev)
+void Editor::onBeforeRemoveCel(DocEvent& ev)
{
m_showGuidesThisCel = nullptr;
}
@@ -2774,22 +2778,21 @@ void Editor::invalidateIfActive()
invalidate();
}
-bool Editor::showAutoCelGuides()
-{
- return
- (getCurrentEditorInk()->isCelMovement() &&
- m_docPref.show.autoGuides() &&
- m_customizationDelegate &&
- int(m_customizationDelegate->getPressedKeyAction(KeyContext::MoveTool) & KeyAction::AutoSelectLayer));
-}
-
void Editor::updateAutoCelGuides(ui::Message* msg)
{
Cel* oldShowGuidesThisCel = m_showGuidesThisCel;
+ bool oldShowAutoCelGuides = m_showAutoCelGuides;
+
+ m_showAutoCelGuides = (
+ msg &&
+ getCurrentEditorInk()->isCelMovement() &&
+ m_docPref.show.autoGuides() &&
+ m_customizationDelegate &&
+ int(m_customizationDelegate->getPressedKeyAction(KeyContext::MoveTool) & KeyAction::AutoSelectLayer));
// Check if the user is pressing the Ctrl or Cmd key on move
// tool to show automatic guides.
- if (showAutoCelGuides() &&
+ if (m_showAutoCelGuides &&
m_state->requireBrushPreview()) {
ui::MouseMessage* mouseMsg = dynamic_cast(msg);
@@ -2805,8 +2808,10 @@ void Editor::updateAutoCelGuides(ui::Message* msg)
m_showGuidesThisCel = nullptr;
}
- if (m_showGuidesThisCel != oldShowGuidesThisCel)
+ if (m_showGuidesThisCel != oldShowGuidesThisCel ||
+ m_showAutoCelGuides != oldShowAutoCelGuides) {
invalidate();
+ }
}
// static
diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h
index e999319b6..33fc7acfb 100644
--- a/src/app/ui/editor/editor.h
+++ b/src/app/ui/editor/editor.h
@@ -320,7 +320,7 @@ namespace app {
void onExposeSpritePixels(DocEvent& ev) override;
void onSpritePixelRatioChanged(DocEvent& ev) override;
void onBeforeRemoveLayer(DocEvent& ev) override;
- void onRemoveCel(DocEvent& ev) override;
+ void onBeforeRemoveCel(DocEvent& ev) override;
void onAddTag(DocEvent& ev) override;
void onRemoveTag(DocEvent& ev) override;
void onRemoveSlice(DocEvent& ev) override;
@@ -436,6 +436,7 @@ namespace app {
// The Cel that is above the mouse if the Ctrl (or Cmd) key is
// pressed (move key).
Cel* m_showGuidesThisCel;
+ bool m_showAutoCelGuides;
// Focused tag band. Used by the Timeline to save/restore the
// focused tag band for each sprite/editor.
diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp
index 59ecb6a83..d6b7f6da6 100644
--- a/src/app/ui/editor/moving_pixels_state.cpp
+++ b/src/app/ui/editor/moving_pixels_state.cpp
@@ -5,6 +5,8 @@
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
+#define MOVPIXS_TRACE(...) // TRACE(__VA_ARGS__)
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -174,7 +176,7 @@ void MovingPixelsState::onEditorGotFocus(Editor* editor)
EditorState::LeaveAction MovingPixelsState::onLeaveState(Editor* editor, EditorState* newState)
{
- TRACE("MOVPIXS: onLeaveState\n");
+ MOVPIXS_TRACE("MOVPIXS: onLeaveState\n");
ASSERT(m_pixelsMovement);
ASSERT(editor == m_editor);
@@ -489,9 +491,23 @@ bool MovingPixelsState::onKeyUp(Editor* editor, KeyMessage* msg)
bool MovingPixelsState::onUpdateStatusBar(Editor* editor)
{
+ MOVPIXS_TRACE("MOVPIXS: onUpdateStatusBar (%p)\n", m_pixelsMovement.get());
+
ASSERT(m_pixelsMovement);
ASSERT(editor == m_editor);
+ // We've received a crash report where this is nullptr when
+ // MovingPixelsState::onLeaveState() generates a general update
+ // notification (notifyGeneralUpdate()) just after the
+ // m_pixelsMovement is deleted with removePixelsMovement(). The
+ // general update signals a scroll update in the view which will ask
+ // for the status bar content again (Editor::notifyScrollChanged).
+ //
+ // We weren't able to reproduce this scenario anyway (which should
+ // be visible with the ASSERT() above).
+ if (!m_pixelsMovement)
+ return false;
+
const Transformation& transform(getTransformation(editor));
gfx::Size imageSize = m_pixelsMovement->getInitialImageSize();
@@ -532,7 +548,7 @@ void MovingPixelsState::onBeforeCommandExecution(CommandExecutionEvent& ev)
{
Command* command = ev.command();
- TRACE("MOVPIXS: onBeforeCommandExecution %s\n", command->id().c_str());
+ MOVPIXS_TRACE("MOVPIXS: onBeforeCommandExecution %s\n", command->id().c_str());
// If the command is for other editor, we don't drop pixels.
if (!isActiveEditor())
@@ -743,7 +759,7 @@ void MovingPixelsState::setTransparentColor(bool opaque, const app::Color& color
void MovingPixelsState::dropPixels()
{
- TRACE("MOVPIXS: dropPixels\n");
+ MOVPIXS_TRACE("MOVPIXS: dropPixels\n");
// Just change to default state (StandbyState generally). We'll
// receive an onLeaveState() event after this call.
diff --git a/src/app/ui/file_selector.cpp b/src/app/ui/file_selector.cpp
index 1e8e2f6ca..3249bbce8 100644
--- a/src/app/ui/file_selector.cpp
+++ b/src/app/ui/file_selector.cpp
@@ -641,9 +641,10 @@ again:
}
#endif
- // does it not have extension? ...we should add the extension
+ // Does it not have extension? ...we should add the extension
// selected in the filetype combo-box
- if (!buf.empty() && base::get_file_extension(buf).empty()) {
+ if (m_type == FileSelectorType::Save &&
+ !buf.empty() && base::get_file_extension(buf).empty()) {
buf += '.';
buf += getSelectedExtension();
}
diff --git a/src/app/ui/preview_editor.cpp b/src/app/ui/preview_editor.cpp
index c86be5d86..b8111d126 100644
--- a/src/app/ui/preview_editor.cpp
+++ b/src/app/ui/preview_editor.cpp
@@ -483,10 +483,10 @@ void PreviewEditorWindow::destroyDocView()
void PreviewEditorWindow::adjustPlayingTag()
{
Editor* editor = m_relatedEditor;
- Editor* miniEditor = m_docView->editor();
+ if (!editor || !m_docView)
+ return;
- ASSERT(editor);
- ASSERT(miniEditor);
+ Editor* miniEditor = m_docView->editor();
if (miniEditor->isPlaying()) {
doc::Tag* tag = editor
diff --git a/src/app/util/open_batch.h b/src/app/util/open_batch.h
index 4b53e4581..39b43bc25 100644
--- a/src/app/util/open_batch.h
+++ b/src/app/util/open_batch.h
@@ -42,7 +42,10 @@ namespace app {
}
}
- ctx->executeCommandFromMenuOrShortcut(&m_cmd, params);
+ if (ctx->isUIAvailable())
+ ctx->executeCommandFromMenuOrShortcut(&m_cmd, params);
+ else
+ ctx->executeCommand(&m_cmd, params);
// Future decision for other files in the CLI
auto d = m_cmd.seqDecision();
diff --git a/src/dio/aseprite_decoder.cpp b/src/dio/aseprite_decoder.cpp
index d8b3b8c34..be2ab6bfb 100644
--- a/src/dio/aseprite_decoder.cpp
+++ b/src/dio/aseprite_decoder.cpp
@@ -39,6 +39,22 @@ bool AsepriteDecoder::decode()
return false;
}
+ if (header.depth != 32 &&
+ header.depth != 16 &&
+ header.depth != 8) {
+ delegate()->error(
+ fmt::format("Invalid color depth {0}",
+ header.depth));
+ return false;
+ }
+
+ if (header.width < 1 || header.height < 1) {
+ delegate()->error(
+ fmt::format("Invalid sprite size {0}x{1}",
+ header.width, header.height));
+ return false;
+ }
+
// Create the new sprite
std::unique_ptr sprite(
new doc::Sprite(doc::ImageSpec(header.depth == 32 ? doc::ColorMode::RGB:
diff --git a/src/doc/algorithm/polygon.cpp b/src/doc/algorithm/polygon.cpp
index 4c23ec408..33f90041b 100644
--- a/src/doc/algorithm/polygon.cpp
+++ b/src/doc/algorithm/polygon.cpp
@@ -1,5 +1,5 @@
// Aseprite Document Library
-// Copyright (c) 2019 Igara Studio S.A.
+// Copyright (c) 2019-2020 Igara Studio S.A.
// Copyright (c) 2001-2014 David Capello
//
// This file is released under the terms of the MIT license.
@@ -9,6 +9,7 @@
#include "config.h"
#endif
+#include "base/debug.h"
#include "doc/algo.h"
#include "doc/algorithm/polygon.h"
diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp
index 8caa9d0f6..b26c54c12 100644
--- a/src/ui/manager.cpp
+++ b/src/ui/manager.cpp
@@ -518,30 +518,7 @@ void Manager::handleMouseMove(const gfx::Point& mousePos,
const PointerType pointerType,
const float pressure)
{
- // Get the list of widgets to send mouse messages.
- mouse_widgets_list.clear();
- broadcastMouseMessage(mouse_widgets_list);
-
- // Get the widget under the mouse
- Widget* widget = nullptr;
- for (auto mouseWidget : mouse_widgets_list) {
- widget = mouseWidget->pick(mousePos);
- if (widget) {
- // Get the first ancestor of the picked widget that doesn't
- // ignore mouse events.
- while (widget && widget->hasFlags(IGNORE_MOUSE))
- widget = widget->parent();
- break;
- }
- }
-
- // Fixup "mouse" flag
- if (widget != mouse_widget) {
- if (!widget)
- freeMouse();
- else
- setMouse(widget);
- }
+ updateMouseWidgets(mousePos);
// Send the mouse movement message
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
@@ -683,6 +660,34 @@ void Manager::handleWindowZOrder()
setFocus(mouse_widget);
}
+void Manager::updateMouseWidgets(const gfx::Point& mousePos)
+{
+ // Get the list of widgets to send mouse messages.
+ mouse_widgets_list.clear();
+ broadcastMouseMessage(mouse_widgets_list);
+
+ // Get the widget under the mouse
+ Widget* widget = nullptr;
+ for (auto mouseWidget : mouse_widgets_list) {
+ widget = mouseWidget->pick(mousePos);
+ if (widget) {
+ // Get the first ancestor of the picked widget that doesn't
+ // ignore mouse events.
+ while (widget && widget->hasFlags(IGNORE_MOUSE))
+ widget = widget->parent();
+ break;
+ }
+ }
+
+ // Fixup "mouse" flag
+ if (widget != mouse_widget) {
+ if (!widget)
+ freeMouse();
+ else
+ setMouse(widget);
+ }
+}
+
void Manager::dispatchMessages()
{
// Send messages in the queue (mouse/key/timer/etc. events) This
@@ -1103,9 +1108,7 @@ void Manager::_openWindow(Window* window)
// Update mouse widget (as it can be a widget below the
// recently opened window).
- Widget* widget = pick(ui::get_mouse_position());
- if (widget)
- setMouse(widget);
+ updateMouseWidgets(ui::get_mouse_position());
}
void Manager::_closeWindow(Window* window, bool redraw_background)
@@ -1160,9 +1163,7 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
// Update mouse widget (as it can be a widget below the
// recently closed window).
- Widget* widget = pick(ui::get_mouse_position());
- if (widget)
- setMouse(widget);
+ updateMouseWidgets(ui::get_mouse_position());
redrawState = RedrawState::AWindowHasJustBeenClosed;
}
diff --git a/src/ui/manager.h b/src/ui/manager.h
index 1da5b6d86..4554548ad 100644
--- a/src/ui/manager.h
+++ b/src/ui/manager.h
@@ -145,6 +145,7 @@ namespace ui {
const KeyModifiers modifiers,
const double magnification);
void handleWindowZOrder();
+ void updateMouseWidgets(const gfx::Point& mousePos);
int pumpQueue();
bool sendMessageToWidget(Message* msg, Widget* widget);