diff --git a/laf b/laf index 11ffdbd9c..80ec051ec 160000 --- a/laf +++ b/laf @@ -1 +1 @@ -Subproject commit 11ffdbd9cc6232faaff5eecd8cc628bb5a2c706f +Subproject commit 80ec051ecf4b702d769d4b2483e1a34b52368bde diff --git a/src/app/commands/cmd_options.cpp b/src/app/commands/cmd_options.cpp index b0511dbf0..1075b7de5 100644 --- a/src/app/commands/cmd_options.cpp +++ b/src/app/commands/cmd_options.cpp @@ -380,7 +380,7 @@ public: // If the platform supports native cursors... if ((int(os::instance()->capabilities()) & - int(os::Capabilities::CustomNativeMouseCursor)) != 0) { + int(os::Capabilities::CustomMouseCursor)) != 0) { if (m_pref.cursor.useNativeCursor()) nativeCursor()->setSelected(true); nativeCursor()->Click.connect([this]{ onNativeCursorChange(); }); @@ -949,9 +949,9 @@ private: void onNativeCursorChange() { bool state = - // If the platform supports native cursors... + // If the platform supports custom cursors... (((int(os::instance()->capabilities()) & - int(os::Capabilities::CustomNativeMouseCursor)) != 0) && + int(os::Capabilities::CustomMouseCursor)) != 0) && // If the native cursor option is not selec !nativeCursor()->isSelected()); diff --git a/src/app/ui/editor/brush_preview.cpp b/src/app/ui/editor/brush_preview.cpp index af7fa68b1..cd3c994c2 100644 --- a/src/app/ui/editor/brush_preview.cpp +++ b/src/app/ui/editor/brush_preview.cpp @@ -46,10 +46,57 @@ #include "ui/manager.h" #include "ui/system.h" +#include + namespace app { using namespace doc; +static int g_crosshair_pattern[7*7] = { + 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, +}; + +// We're going to keep a cache of native mouse cursor for each +// possibility of the following crosshair: +// +// 2 +// 2 +// 22 3 22 +// 2 +// 2 +// +// Number of crosshair cursors 2^8 * 3 + 2 = 770 +// Here the center can be black, white or hidden. When the center is +// black or white, the crosshair can be empty. +// +// The index/key of this array is calculated in +// BrushPreview::createCrosshairCursor(). +// +// Win32: This is needed to avoid converting from a os::Surface -> +// HCURSOR calling CreateIconIndirect() as many times as possible for +// each mouse movement (because it's a slow function). +// +static std::array g_bwCursors; +static int g_cacheCursorScale = 0; + +// 3 cached cursors when we use a solid cursor (1 dot, crosshair +// without dot at the center, crosshair with dot in the center) +static std::array g_solidCursors; +static gfx::Color g_solidCursorColor = gfx::ColorNone; + +// static +void BrushPreview::destroyInternals() +{ + g_bwCursors.fill(nullptr); + g_solidCursors.fill(nullptr); +} + BrushPreview::BrushPreview(Editor* editor) : m_editor(editor) { @@ -57,7 +104,6 @@ BrushPreview::BrushPreview(Editor* editor) BrushPreview::~BrushPreview() { - m_cursor.reset(); } BrushRef BrushPreview::getCurrentBrush() @@ -351,9 +397,9 @@ void BrushPreview::show(const gfx::Point& screenPos) ui::SetClip clip(&g); gfx::Color uiCursorColor = color_utils::color_for_ui(appCursorColor); - createNativeCursor(); - if (m_cursor) - forEachLittleCrossPixel(&g, m_screenPosition, uiCursorColor, &BrushPreview::putPixelInCursorDelegate); + if (!(m_type & NATIVE_CROSSHAIR)) { + createCrosshairCursor(&g, uiCursorColor); + } forEachBrushPixel(&g, spritePos, uiCursorColor, &BrushPreview::savePixelDelegate); forEachBrushPixel(&g, spritePos, uiCursorColor, &BrushPreview::drawPixelDelegate); @@ -385,7 +431,7 @@ void BrushPreview::hide() // cursor will be changed anyway after the hide() by the caller. // //if (m_cursor) - // m_editor->m_editor->display()->nativeWindow()->setNativeMouseCursor(os::NativeCursor::Hidden); + // m_editor->display()->nativeWindow()->setCursor(os::NativeCursor::Hidden); // Get drawable region m_editor->getDrawableRegion(m_clippingRegion, ui::Widget::kCutTopWindows); @@ -484,79 +530,165 @@ void BrushPreview::generateBoundaries() delete mask; } -void BrushPreview::createNativeCursor() +void BrushPreview::createCrosshairCursor(ui::Graphics* g, + const gfx::Color cursorColor) { + ASSERT(!(m_type & NATIVE_CROSSHAIR)); + gfx::Rect cursorBounds; - - if (m_type & CROSSHAIR) { - cursorBounds |= gfx::Rect(-3, -3, 7, 7); - m_cursorCenter = -cursorBounds.origin(); - } - // Special case of a cursor for one pixel - else if (!(m_type & NATIVE_CROSSHAIR) && - m_editor->zoom().scale() >= 4.0) { - cursorBounds = gfx::Rect(0, 0, 1, 1); - m_cursorCenter = gfx::Point(0, 0); - } - - if (m_cursor) { - if (m_cursor->width() != cursorBounds.w || - m_cursor->height() != cursorBounds.h) { - m_cursor.reset(); - } - } - - if (cursorBounds.isEmpty()) { - ASSERT(!m_cursor); - if (!(m_type & NATIVE_CROSSHAIR)) { - // TODO should we use ui::set_mouse_cursor()? - ui::set_mouse_cursor_reset_info(); - m_editor->display()->nativeWindow()->setNativeMouseCursor(os::NativeCursor::Hidden); - } - return; - } - - if (!m_cursor) { - m_cursor = os::instance()->makeRgbaSurface(cursorBounds.w, cursorBounds.h); - - // Cannot clear the cursor on each iteration because it can - // generate a flicker effect when zooming in the same mouse - // position. That's strange. - m_cursor->clear(); - } -} - -void BrushPreview::forEachLittleCrossPixel( - ui::Graphics* g, - const gfx::Point& screenPos, - gfx::Color color, - PixelDelegate pixelDelegate) -{ - if (m_type & CROSSHAIR) - traceCrossPixels(g, screenPos, color, pixelDelegate); + gfx::Point cursorCenter; // Depending on the editor zoom, maybe we need subpixel movement (a // little dot inside the active pixel) - if (!(m_type & NATIVE_CROSSHAIR) && - m_editor->zoom().scale() >= 4.0) { - (this->*pixelDelegate)(g, screenPos, color); + const bool requireLittleCenterDot = (m_editor->zoom().scale() >= 4.0); + + if (m_type & CROSSHAIR) { + // Regular crosshair of 7x7 + cursorBounds |= gfx::Rect(-3, -3, 7, 7); + cursorCenter = -cursorBounds.origin(); + } + else if (requireLittleCenterDot) { + // Special case of a cursor for one pixel + cursorBounds = gfx::Rect(0, 0, 1, 1); + cursorCenter = gfx::Point(0, 0); } else { - // We'll remove the pixel (as we didn't called Surface::clear() to - // avoid a flickering issue when zooming in the same mouse - // position). - base::ScopedValue restore(m_blackAndWhiteNegative, false, - m_blackAndWhiteNegative); - (this->*pixelDelegate)(g, screenPos, gfx::ColorNone); - } - - if (m_cursor) { // TODO should we use ui::set_mouse_cursor()? ui::set_mouse_cursor_reset_info(); - m_editor->display()->nativeWindow()->setNativeMouseCursor( - m_cursor.get(), - m_cursorCenter, - m_editor->display()->nativeWindow()->scale()); + m_editor->display()->nativeWindow()->setCursor(os::NativeCursor::Hidden); + return; + } + + os::Window* window = m_editor->display()->nativeWindow(); + const int scale = window->scale(); + os::CursorRef cursor = nullptr; + + // Invalidate the entire cache if the scale has changed + if (g_cacheCursorScale != scale) { + g_cacheCursorScale = scale; + g_bwCursors.fill(nullptr); + g_solidCursors.fill(nullptr); + } + + // Cursor with black/white colors (we create a key/index for + // g_cachedCursors depending on the colors on the screen) + if (m_blackAndWhiteNegative) { + int k = 0; + if (m_type & CROSSHAIR) { + int bit = 0; + for (int v=0; v<7; v++) { + for (int u=0; u<7; u++) { + if (g_crosshair_pattern[v*7+u]) { + color_t c = g->getPixel(m_screenPosition.x-3+u, + m_screenPosition.y-3+v); + c = color_utils::blackandwhite_neg(c); + if (rgba_getr(c) == 255) { // White + k |= (1 << bit); + } + ++bit; + } + } + } + } + if (requireLittleCenterDot) { + color_t c = g->getPixel(m_screenPosition.x, + m_screenPosition.y); + c = color_utils::blackandwhite_neg(c); + if (rgba_getr(c) == 255) { // White + k |= (m_type & CROSSHAIR ? 0x200: 0x301); + } + else { // Black + k |= (m_type & CROSSHAIR ? 0x100: 0x300); + } + } + + ASSERT(k < int(g_bwCursors.size())); + if (k >= int(g_bwCursors.size())) // Unexpected key value in release mode + return; + + // Use cached cursor + if (g_bwCursors[k]) { + cursor = g_bwCursors[k]; + } + else { + const gfx::Color black = gfx::rgba(0, 0, 0); + const gfx::Color white = gfx::rgba(255, 255, 255); + os::SurfaceRef cursorSurface = + os::instance()->makeRgbaSurface(cursorBounds.w, + cursorBounds.h); + cursorSurface->clear(); + int bit = 0; + if (m_type & CROSSHAIR) { + for (int v=0; v<7; v++) { + for (int u=0; u<7; u++) { + if (g_crosshair_pattern[v*7+u]) { + cursorSurface->putPixel( + (k & (1 << bit) ? white: black), u, v); + ++bit; + } + } + } + } + if (requireLittleCenterDot) { + cursorSurface->putPixel( + (k == 0x100 || k == 0x300 ? black: white), + cursorBounds.w/2, cursorBounds.h/2); + } + + cursor = g_bwCursors[k] = + os::instance()->makeCursor( + cursorSurface.get(), + cursorCenter, + scale); + } + } + // Cursor with solid color (easiest case, we don't have to check the + // colors in the screen to create the crosshair) + else { + // We have to recreate all cursors if the color has changed. + if (g_solidCursorColor != cursorColor) { + g_solidCursors.fill(nullptr); + g_solidCursorColor = cursorColor; + } + + int k = 0; + if (m_type & CROSSHAIR) { + if (requireLittleCenterDot) + k = 2; + else + k = 1; + } + + // Use cached cursor + if (g_solidCursors[k]) { + cursor = g_solidCursors[k]; + } + else { + os::SurfaceRef cursorSurface = + os::instance()->makeRgbaSurface(cursorBounds.w, + cursorBounds.h); + cursorSurface->clear(); + if (m_type & CROSSHAIR) { + for (int v=0; v<7; v++) + for (int u=0; u<7; u++) + if (g_crosshair_pattern[v*7+u]) + cursorSurface->putPixel(cursorColor, u, v); + } + if (requireLittleCenterDot) + cursorSurface->putPixel(cursorColor, cursorBounds.w/2, cursorBounds.h/2); + + cursor = g_solidCursors[k] = + os::instance()->makeCursor( + cursorSurface.get(), + cursorCenter, + scale); + } + } + + if (cursor) { + // TODO should we use ui::set_mouse_cursor()? + ui::set_mouse_cursor_reset_info(); + window->setCursor(cursor); } } @@ -577,34 +709,6 @@ void BrushPreview::forEachBrushPixel( m_savedPixelsLimit = m_savedPixelsIterator; } -void BrushPreview::traceCrossPixels( - ui::Graphics* g, - const gfx::Point& pt, gfx::Color color, - PixelDelegate pixelDelegate) -{ - static int cross[7*7] = { - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - }; - gfx::Point out; - int u, v; - - for (v=0; v<7; v++) { - for (u=0; u<7; u++) { - if (cross[v*7+u]) { - out.x = pt.x-3+u; - out.y = pt.y-3+v; - (this->*pixelDelegate)(g, out, color); - } - } - } -} - // Old thick cross (used for selection tools) void BrushPreview::traceSelectionCrossPixels( ui::Graphics* g, @@ -673,30 +777,6 @@ void BrushPreview::traceBrushBoundaries(ui::Graphics* g, ////////////////////////////////////////////////////////////////////// // Pixel delegates -void BrushPreview::putPixelInCursorDelegate(ui::Graphics* g, const gfx::Point& pt, gfx::Color color) -{ - ASSERT(m_cursor); - - if (!m_clippingRegion.contains(pt)) - return; - - if (m_blackAndWhiteNegative) { - color_t c = g->getPixel(pt.x, pt.y); - int r = gfx::getr(c); - int g = gfx::getg(c); - int b = gfx::getb(c); - - m_cursor->putPixel(color_utils::blackandwhite_neg(gfx::rgba(r, g, b)), - pt.x - m_screenPosition.x + m_cursorCenter.x, - pt.y - m_screenPosition.y + m_cursorCenter.y); - } - else { - m_cursor->putPixel(color, - pt.x - m_screenPosition.x + m_cursorCenter.x, - pt.y - m_screenPosition.y + m_cursorCenter.y); - } -} - void BrushPreview::savePixelDelegate(ui::Graphics* g, const gfx::Point& pt, gfx::Color color) { if (m_clippingRegion.contains(pt)) { diff --git a/src/app/ui/editor/brush_preview.h b/src/app/ui/editor/brush_preview.h index af3252eb9..f61f40bac 100644 --- a/src/app/ui/editor/brush_preview.h +++ b/src/app/ui/editor/brush_preview.h @@ -19,6 +19,7 @@ #include "gfx/rect.h" #include "gfx/region.h" #include "os/surface.h" +#include "ui/cursor.h" #include @@ -68,6 +69,8 @@ namespace app { NATIVE_CROSSHAIR = 8, }; + static void destroyInternals(); + BrushPreview(Editor* editor); ~BrushPreview(); @@ -90,23 +93,17 @@ namespace app { void generateBoundaries(); // Creates a little native cursor to draw the CROSSHAIR - void createNativeCursor(); - void forEachLittleCrossPixel( - ui::Graphics* g, - const gfx::Point& screenPos, - gfx::Color color, - PixelDelegate pixelDelegate); + void createCrosshairCursor(ui::Graphics* g, const gfx::Color cursorColor); + void forEachBrushPixel( ui::Graphics* g, const gfx::Point& spritePos, gfx::Color color, PixelDelegate pixelDelegate); - void traceCrossPixels(ui::Graphics* g, const gfx::Point& pt, gfx::Color color, PixelDelegate pixel); void traceSelectionCrossPixels(ui::Graphics* g, const gfx::Point& pt, gfx::Color color, int thickness, PixelDelegate pixel); void traceBrushBoundaries(ui::Graphics* g, gfx::Point pos, gfx::Color color, PixelDelegate pixel); - void putPixelInCursorDelegate(ui::Graphics* g, const gfx::Point& pt, gfx::Color color); void savePixelDelegate(ui::Graphics* g, const gfx::Point& pt, gfx::Color color); void drawPixelDelegate(ui::Graphics* g, const gfx::Point& pt, gfx::Color color); void clearPixelDelegate(ui::Graphics* g, const gfx::Point& pt, gfx::Color color); @@ -125,10 +122,6 @@ namespace app { gfx::Point m_screenPosition; // Position in the screen (view) gfx::Point m_editorPosition; // Position in the editor (model) - // Native mouse cursor to draw crosshair - os::SurfaceRef m_cursor; - gfx::Point m_cursorCenter; - // Information about current brush doc::MaskBoundaries m_brushBoundaries; int m_brushGen; diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index 7fab26934..9994f30f4 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -233,6 +233,7 @@ Editor::~Editor() void Editor::destroyEditorSharedInternals() { + BrushPreview::destroyInternals(); if (m_renderEngine) { delete m_renderEngine; m_renderEngine = nullptr; diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp index 2e3bd1611..5eae0d039 100644 --- a/src/app/ui/skin/skin_theme.cpp +++ b/src/app/ui/skin/skin_theme.cpp @@ -222,12 +222,12 @@ SkinTheme* SkinTheme::instance() SkinTheme::SkinTheme() : m_sheet(nullptr) - , m_standardCursors(ui::kCursorTypes, nullptr) , m_defaultFont(nullptr) , m_miniFont(nullptr) , m_preferredScreenScaling(-1) , m_preferredUIScaling(-1) { + m_standardCursors.fill(nullptr); } SkinTheme::~SkinTheme() diff --git a/src/app/ui/skin/skin_theme.h b/src/app/ui/skin/skin_theme.h index ea25e1645..316c2a48d 100644 --- a/src/app/ui/skin/skin_theme.h +++ b/src/app/ui/skin/skin_theme.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of @@ -12,15 +12,17 @@ #include "app/ui/skin/skin_part.h" #include "gfx/color.h" #include "gfx/fwd.h" +#include "ui/cursor.h" +#include "ui/cursor_type.h" #include "ui/manager.h" #include "ui/scale.h" #include "ui/theme.h" #include "theme.xml.h" +#include #include #include -#include namespace ui { class Entry; @@ -155,7 +157,7 @@ namespace app { std::map m_colors_by_id; std::map m_dimensions_by_id; std::map m_cursors; - std::vector m_standardCursors; + std::array m_standardCursors; std::map m_styles; std::map m_fonts; std::map m_themeFonts; diff --git a/src/ui/cursor.cpp b/src/ui/cursor.cpp index 908636434..8ff7cc9a4 100644 --- a/src/ui/cursor.cpp +++ b/src/ui/cursor.cpp @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. @@ -13,14 +13,36 @@ #include "base/debug.h" #include "os/surface.h" +#include "os/system.h" namespace ui { -Cursor::Cursor(const os::SurfaceRef& surface, const gfx::Point& focus) +Cursor::Cursor(const os::SurfaceRef& surface, + const gfx::Point& focus) : m_surface(surface) , m_focus(focus) + , m_scale(0) { - ASSERT(m_surface != nullptr); +} + +void Cursor::reset() +{ + m_surface.reset(); + m_cursor.reset(); + m_focus = gfx::Point(0, 0); + m_scale = 0; +} + +os::CursorRef Cursor::nativeCursor(const int scale) const +{ + if (m_cursor && m_scale == scale) + return m_cursor; + + m_cursor = os::instance()->makeCursor( + m_surface.get(), + m_focus, + m_scale = scale); + return m_cursor; } } // namespace ui diff --git a/src/ui/cursor.h b/src/ui/cursor.h index e22434eb8..7f9cb0b09 100644 --- a/src/ui/cursor.h +++ b/src/ui/cursor.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This file is released under the terms of the MIT license. @@ -10,22 +10,27 @@ #pragma once #include "gfx/point.h" +#include "os/cursor.h" #include "os/surface.h" -namespace os { class Surface; } - namespace ui { class Cursor { public: - Cursor(const os::SurfaceRef& surface, const gfx::Point& focus); + Cursor(const os::SurfaceRef& surface = nullptr, + const gfx::Point& focus = gfx::Point(0, 0)); - const os::SurfaceRef& getSurface() const { return m_surface; } - const gfx::Point& getFocus() const { return m_focus; } + const os::SurfaceRef& surface() const { return m_surface; } + const gfx::Point& focus() const { return m_focus; } + os::CursorRef nativeCursor(const int scale) const; + + void reset(); private: os::SurfaceRef m_surface; gfx::Point m_focus; + mutable os::CursorRef m_cursor; + mutable int m_scale; }; } // namespace ui diff --git a/src/ui/system.cpp b/src/ui/system.cpp index 4cedf4790..ea721fe24 100644 --- a/src/ui/system.cpp +++ b/src/ui/system.cpp @@ -60,14 +60,14 @@ static void update_mouse_overlay(const Cursor* cursor) ASSERT(mouse_display); mouse_cursor_overlay = base::make_ref( mouse_display, - mouse_cursor->getSurface(), + mouse_cursor->surface(), mouse_display->nativeWindow()->pointFromScreen(get_mouse_position()), Overlay::MouseZOrder); OverlayManager::instance()->addOverlay(mouse_cursor_overlay); } else { - mouse_cursor_overlay->setSurface(mouse_cursor->getSurface()); + mouse_cursor_overlay->setSurface(mouse_cursor->surface()); update_cursor_overlay(); } } @@ -84,19 +84,19 @@ static bool set_native_cursor_on_all_displays(Display* display, bool result = false; while (display) { os::Window* nativeWindow = display->nativeWindow(); - if (cursor) { - result |= nativeWindow->setNativeMouseCursor( - // The surface is already scaled by guiscale() - cursor->getSurface().get(), - cursor->getFocus(), - // We scale the cursor by the os::Display scale - nativeWindow->scale() * mouse_cursor_scale); + + if (cursor && cursor->surface()) { + // The cursor surface is already scaled by guiscale(), we scale + // the cursor by the os::Window scale and mouse scale. + const int scale = nativeWindow->scale() * mouse_cursor_scale; + if (auto osCursor = cursor->nativeCursor(scale)) + result |= nativeWindow->setCursor(osCursor); } else if (mouse_cursor_type == kOutsideDisplay) { - result |= nativeWindow->setNativeMouseCursor(os::NativeCursor::Arrow); + result |= nativeWindow->setCursor(os::NativeCursor::Arrow); } else { - result |= nativeWindow->setNativeMouseCursor(os::NativeCursor::Hidden); + result |= nativeWindow->setCursor(os::NativeCursor::Hidden); } display = display->parentDisplay(); } @@ -110,10 +110,10 @@ static bool set_native_cursor_on_all_displays(Display* display, while (display) { os::Window* nativeWindow = display->nativeWindow(); if (mouse_cursor_type == kOutsideDisplay) { - result |= nativeWindow->setNativeMouseCursor(os::NativeCursor::Arrow); + result |= nativeWindow->setCursor(os::NativeCursor::Arrow); } else { - result |= nativeWindow->setNativeMouseCursor(cursor); + result |= nativeWindow->setCursor(cursor); } display = display->parentDisplay(); } @@ -223,7 +223,7 @@ UISystem::UISystem() support_native_custom_cursor = ((os::instance() && (int(os::instance()->capabilities()) & - int(os::Capabilities::CustomNativeMouseCursor))) ? + int(os::Capabilities::CustomMouseCursor))) ? true: false); details::initWidgets(); @@ -231,8 +231,6 @@ UISystem::UISystem() UISystem::~UISystem() { - OverlayManager::destroyInstance(); - // finish theme set_theme(nullptr, guiscale()); @@ -242,6 +240,8 @@ UISystem::~UISystem() if (!update_custom_native_cursor(nullptr)) update_mouse_overlay(nullptr); + OverlayManager::destroyInstance(); + ASSERT(g_instance == this); g_instance = nullptr; } @@ -288,7 +288,7 @@ void update_cursor_overlay() if (mouse_cursor_overlay != nullptr && mouse_scares == 0) { gfx::Point newPos = mouse_display->nativeWindow()->pointFromScreen(get_mouse_position()) - - mouse_cursor->getFocus(); + - mouse_cursor->focus(); if (newPos != mouse_cursor_overlay->position()) { mouse_cursor_overlay->moveOverlay(newPos); diff --git a/src/ui/theme.h b/src/ui/theme.h index 05d0341d2..ea486ded0 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2020-2021 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This file is released under the terms of the MIT license. @@ -59,7 +59,7 @@ namespace ui { virtual os::Font* getDefaultFont() const = 0; virtual os::Font* getWidgetFont(const Widget* widget) const = 0; - virtual Cursor* getStandardCursor(CursorType type) = 0; + virtual ui::Cursor* getStandardCursor(CursorType type) = 0; virtual void initWidget(Widget* widget) = 0; virtual void getWindowMask(Widget* widget, gfx::Region& region) = 0; virtual void setDecorativeWidgetBounds(Widget* widget);