Add a new mouse cursor to move selection edges

With this change the app-specific cursors were removed from the ui library. Maybe it needs some clean-up for following versions.
master
David Capello 2017-04-06 18:41:18 -03:00
parent 90c364fe30
commit e5c15161e8
23 changed files with 182 additions and 158 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -111,6 +111,7 @@
<part id="cursor_hand" x="80" y="48" w="16" h="16" focusx="5" focusy="3" />
<part id="cursor_scroll" x="80" y="64" w="16" h="16" focusx="8" focusy="8" />
<part id="cursor_move" x="80" y="80" w="16" h="16" focusx="0" focusy="0" />
<part id="cursor_move_selection" x="96" y="80" w="16" h="16" focusx="0" focusy="0" />
<part id="cursor_size_ns" x="80" y="112" w="16" h="16" focusx="8" focusy="8" />
<part id="cursor_size_we" x="80" y="144" w="16" h="16" focusx="8" focusy="8" />
<part id="cursor_size_n" x="80" y="112" w="16" h="16" focusx="8" focusy="8" />
@ -239,11 +240,8 @@
<part id="target_layers" x="208" y="224" w="32" h="16" />
<part id="target_frames_layers" x="240" y="224" w="32" h="16" />
<part id="selection_replace" x="176" y="160" w="7" h="7" />
<part id="selection_replace_selected" x="176" y="168" w="7" h="7" />
<part id="selection_add" x="192" y="160" w="7" h="7" />
<part id="selection_add_selected" x="192" y="168" w="7" h="7" />
<part id="selection_subtract" x="208" y="160" w="7" h="7" />
<part id="selection_subtract_selected" x="208" y="168" w="7" h="7" />
<part id="selection_add" x="184" y="160" w="7" h="7" />
<part id="selection_subtract" x="192" y="160" w="7" h="7" />
<part id="unpinned" x="192" y="144" w="8" h="8" />
<part id="pinned" x="200" y="144" w="8" h="8" />
<part id="drop_down_button_left_normal" x="48" y="32" w1="3" w2="2" w3="3" h1="4" h2="6" h3="6" />

View File

@ -154,7 +154,7 @@ bool ColorButton::onProcessMessage(Message* msg)
case kSetCursorMessage:
if (hasCapture()) {
ui::set_mouse_cursor(kEyedropperCursor);
ui::set_mouse_cursor(kCustomCursor, SkinTheme::instance()->cursors.eyedropper());
return true;
}
break;

View File

@ -154,7 +154,7 @@ bool ColorSpectrum::onProcessMessage(ui::Message* msg)
case kSetCursorMessage: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
if (childrenBounds().contains(mouseMsg->position())) {
ui::set_mouse_cursor(kEyedropperCursor);
ui::set_mouse_cursor(kCustomCursor, SkinTheme::instance()->cursors.eyedropper());
return true;
}
break;

View File

@ -176,7 +176,7 @@ bool ColorTintShadeTone::onProcessMessage(ui::Message* msg)
case kSetCursorMessage: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
if (childrenBounds().contains(mouseMsg->position())) {
ui::set_mouse_cursor(kEyedropperCursor);
ui::set_mouse_cursor(kCustomCursor, SkinTheme::instance()->cursors.eyedropper());
return true;
}
break;

View File

@ -295,7 +295,7 @@ bool ColorWheel::onProcessMessage(ui::Message* msg)
- bounds().origin());
if (color.getType() != app::Color::MaskType) {
ui::set_mouse_cursor(kEyedropperCursor);
ui::set_mouse_cursor(kCustomCursor, SkinTheme::instance()->cursors.eyedropper());
return true;
}
break;

View File

@ -22,6 +22,7 @@
#include "app/ui/editor/editor_customization_delegate.h"
#include "app/ui/editor/glue.h"
#include "app/ui/keyboard_shortcuts.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui_context.h"
#include "doc/layer.h"
#include "ui/message.h"
@ -173,7 +174,8 @@ bool DrawingState::onMouseMove(Editor* editor, MouseMessage* msg)
bool DrawingState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
{
if (m_toolLoop->getInk()->isEyedropper()) {
editor->showMouseCursor(kEyedropperCursor);
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.eyedropper());
}
else {
editor->showBrushPreview(mouseScreenPos);

View File

@ -2205,10 +2205,11 @@ void Editor::setAnimationSpeedMultiplier(double speed)
m_aniSpeed = speed;
}
void Editor::showMouseCursor(CursorType cursorType)
void Editor::showMouseCursor(CursorType cursorType,
const Cursor* cursor)
{
m_brushPreview.hide();
ui::set_mouse_cursor(cursorType);
ui::set_mouse_cursor(cursorType, cursor);
}
void Editor::showBrushPreview(const gfx::Point& screenPos)

View File

@ -42,6 +42,7 @@ namespace gfx {
class Region;
}
namespace ui {
class Cursor;
class Graphics;
class View;
}
@ -237,7 +238,8 @@ namespace app {
void setAnimationSpeedMultiplier(double speed);
// Functions to be used in EditorState::onSetCursor()
void showMouseCursor(ui::CursorType cursorType);
void showMouseCursor(ui::CursorType cursorType,
const ui::Cursor* cursor = nullptr);
void showBrushPreview(const gfx::Point& pos);
// Gets the brush preview controller.

View File

@ -14,6 +14,7 @@
#include "app/context_access.h"
#include "app/transaction.h"
#include "app/ui/editor/editor.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
#include "app/ui_context.h"
#include "doc/mask.h"
@ -103,22 +104,11 @@ bool MovingSelectionState::onMouseMove(Editor* editor, MouseMessage* msg)
bool MovingSelectionState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
{
editor->showMouseCursor(kMoveCursor);
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.moveSelection());
return true;
}
bool MovingSelectionState::onKeyDown(Editor* editor, KeyMessage* msg)
{
// Use StandbyState implementation
return StandbyState::onKeyDown(editor, msg);
}
bool MovingSelectionState::onKeyUp(Editor* editor, KeyMessage* msg)
{
// Use StandbyState implementation
return StandbyState::onKeyUp(editor, msg);
}
bool MovingSelectionState::onUpdateStatusBar(Editor* editor)
{
const gfx::Rect bounds = editor->document()->mask()->bounds();

View File

@ -23,8 +23,6 @@ namespace app {
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
virtual bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) override;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) override;
virtual bool onUpdateStatusBar(Editor* editor) override;
virtual bool requireBrushPreview() override { return false; }

View File

@ -18,6 +18,7 @@
#include "app/ui/editor/editor.h"
#include "app/ui/editor/editor_customization_delegate.h"
#include "app/ui/editor/scrolling_state.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui_context.h"
#include "doc/frame_tag.h"
#include "doc/handle_anidir.h"
@ -157,7 +158,8 @@ bool PlayState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
tools::Ink* ink = editor->getCurrentEditorInk();
if (ink) {
if (ink->isZoom()) {
editor->showMouseCursor(kMagnifierCursor);
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.magnifier());
return true;
}
}

View File

@ -67,7 +67,7 @@ namespace app {
using namespace ui;
static CursorType rotated_size_cursors[] = {
static CursorType rotated_size_cursors[8] = {
kSizeECursor,
kSizeNECursor,
kSizeNCursor,
@ -78,17 +78,6 @@ static CursorType rotated_size_cursors[] = {
kSizeSECursor
};
static CursorType rotated_rotate_cursors[] = {
kRotateECursor,
kRotateNECursor,
kRotateNCursor,
kRotateNWCursor,
kRotateWCursor,
kRotateSWCursor,
kRotateSCursor,
kRotateSECursor
};
#ifdef _MSC_VER
#pragma warning(disable:4355) // warning C4355: 'this' : used in base member initializer list
#endif
@ -413,7 +402,8 @@ bool StandbyState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
// If the current tool change selection (e.g. rectangular marquee, etc.)
if (ink->isSelection()) {
if (overSelectionEdges(editor, mouseScreenPos)) {
editor->showMouseCursor(kHandCursor); // TODO create a new mouse cursor
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.moveSelection());
return true;
}
@ -431,11 +421,13 @@ bool StandbyState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
return true;
}
else if (ink->isEyedropper()) {
editor->showMouseCursor(kEyedropperCursor);
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.eyedropper());
return true;
}
else if (ink->isZoom()) {
editor->showMouseCursor(kMagnifierCursor);
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.magnifier());
return true;
}
else if (ink->isScrollMovement()) {
@ -722,10 +714,12 @@ bool StandbyState::overSelectionEdges(Editor* editor,
const gfx::Point& mouseScreenPos) const
{
// Move selection edges
if (editor->isActive() &&
if (Preferences::instance().selection.moveEdges() &&
editor->isActive() &&
editor->document()->isMaskVisible() &&
editor->document()->getMaskBoundaries() &&
Preferences::instance().selection.moveEdges()) {
// TODO improve this check, how we can know that we aren't in the MovingPixelsState
!dynamic_cast<MovingPixelsState*>(editor->getState().get())) {
// For each selection edge
for (const auto& seg : *editor->document()->getMaskBoundaries()) {
gfx::Rect segBounds = editor->editorToScreen(seg.bounds());
@ -771,31 +765,33 @@ bool StandbyState::Decorator::onSetCursor(tools::Ink* ink, Editor* editor, const
return false;
if (ink && ink->isSelection() && editor->document()->isMaskVisible()) {
auto theme = skin::SkinTheme::instance();
const Transformation transformation(m_standbyState->getTransformation(editor));
TransformHandles* tr = getTransformHandles(editor);
HandleType handle = tr->getHandleAtPoint(
editor, mouseScreenPos, transformation);
CursorType newCursor = kArrowCursor;
CursorType newCursorType = kArrowCursor;
const Cursor* newCursor = nullptr;
switch (handle) {
case ScaleNWHandle: newCursor = kSizeNWCursor; break;
case ScaleNHandle: newCursor = kSizeNCursor; break;
case ScaleNEHandle: newCursor = kSizeNECursor; break;
case ScaleWHandle: newCursor = kSizeWCursor; break;
case ScaleEHandle: newCursor = kSizeECursor; break;
case ScaleSWHandle: newCursor = kSizeSWCursor; break;
case ScaleSHandle: newCursor = kSizeSCursor; break;
case ScaleSEHandle: newCursor = kSizeSECursor; break;
case RotateNWHandle: newCursor = kRotateNWCursor; break;
case RotateNHandle: newCursor = kRotateNCursor; break;
case RotateNEHandle: newCursor = kRotateNECursor; break;
case RotateWHandle: newCursor = kRotateWCursor; break;
case RotateEHandle: newCursor = kRotateECursor; break;
case RotateSWHandle: newCursor = kRotateSWCursor; break;
case RotateSHandle: newCursor = kRotateSCursor; break;
case RotateSEHandle: newCursor = kRotateSECursor; break;
case PivotHandle: newCursor = kHandCursor; break;
case ScaleNWHandle: newCursorType = kSizeNWCursor; break;
case ScaleNHandle: newCursorType = kSizeNCursor; break;
case ScaleNEHandle: newCursorType = kSizeNECursor; break;
case ScaleWHandle: newCursorType = kSizeWCursor; break;
case ScaleEHandle: newCursorType = kSizeECursor; break;
case ScaleSWHandle: newCursorType = kSizeSWCursor; break;
case ScaleSHandle: newCursorType = kSizeSCursor; break;
case ScaleSEHandle: newCursorType = kSizeSECursor; break;
case RotateNWHandle: newCursor = theme->cursors.rotateNw(); break;
case RotateNHandle: newCursor = theme->cursors.rotateN(); break;
case RotateNEHandle: newCursor = theme->cursors.rotateNe(); break;
case RotateWHandle: newCursor = theme->cursors.rotateW(); break;
case RotateEHandle: newCursor = theme->cursors.rotateE(); break;
case RotateSWHandle: newCursor = theme->cursors.rotateSw(); break;
case RotateSHandle: newCursor = theme->cursors.rotateS(); break;
case RotateSEHandle: newCursor = theme->cursors.rotateSe(); break;
case PivotHandle: newCursorType = kHandCursor; break;
default:
return false;
}
@ -807,16 +803,28 @@ bool StandbyState::Decorator::onSetCursor(tools::Ink* ink, Editor* editor, const
angle >>= 16;
angle /= 32;
if (newCursor >= kSizeNCursor && newCursor <= kSizeNWCursor) {
if (newCursorType >= kSizeNCursor &&
newCursorType <= kSizeNWCursor) {
size_t num = sizeof(rotated_size_cursors) / sizeof(rotated_size_cursors[0]);
size_t c;
for (c=num-1; c>0; --c)
if (rotated_size_cursors[c] == newCursor)
if (rotated_size_cursors[c] == newCursorType)
break;
newCursor = rotated_size_cursors[(c+angle) % num];
newCursorType = rotated_size_cursors[(c+angle) % num];
}
else if (newCursor >= kRotateNCursor && newCursor <= kRotateNWCursor) {
else if (newCursor) {
auto theme = skin::SkinTheme::instance();
const Cursor* rotated_rotate_cursors[8] = {
theme->cursors.rotateE(),
theme->cursors.rotateNe(),
theme->cursors.rotateN(),
theme->cursors.rotateNw(),
theme->cursors.rotateW(),
theme->cursors.rotateSw(),
theme->cursors.rotateS(),
theme->cursors.rotateSe()
};
size_t num = sizeof(rotated_rotate_cursors) / sizeof(rotated_rotate_cursors[0]);
size_t c;
for (c=num-1; c>0; --c)
@ -824,9 +832,10 @@ bool StandbyState::Decorator::onSetCursor(tools::Ink* ink, Editor* editor, const
break;
newCursor = rotated_rotate_cursors[(c+angle) % num];
newCursorType = kCustomCursor;
}
editor->showMouseCursor(newCursor);
editor->showMouseCursor(newCursorType, newCursor);
return true;
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -12,6 +12,7 @@
#include "app/app.h"
#include "app/ui/editor/editor.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
#include "doc/sprite.h"
#include "gfx/rect.h"
@ -81,7 +82,8 @@ bool ZoomingState::onMouseMove(Editor* editor, MouseMessage* msg)
bool ZoomingState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
{
editor->showMouseCursor(kMagnifierCursor);
editor->showMouseCursor(
kCustomCursor, skin::SkinTheme::instance()->cursors.magnifier());
return true;
}

View File

@ -69,16 +69,6 @@ static const char* g_cursor_names[kCursorTypes] = {
"size_sw", // kSizeSWCursor
"size_w", // kSizeWCursor
"size_nw", // kSizeNWCursor
"rotate_n", // kRotateNCursor
"rotate_ne", // kRotateNECursor
"rotate_e", // kRotateECursor
"rotate_se", // kRotateSECursor
"rotate_s", // kRotateSCursor
"rotate_sw", // kRotateSWCursor
"rotate_w", // kRotateWCursor
"rotate_nw", // kRotateNWCursor
"eyedropper", // kEyedropperCursor
"magnifier" // kMagnifierCursor
};
static FontData* load_font(std::map<std::string, FontData*>& fonts,
@ -187,7 +177,7 @@ SkinTheme* SkinTheme::instance()
SkinTheme::SkinTheme()
: m_sheet(nullptr)
, m_cursors(ui::kCursorTypes, nullptr)
, m_standardCursors(ui::kCursorTypes, nullptr)
, m_defaultFont(nullptr)
, m_miniFont(nullptr)
{
@ -196,8 +186,8 @@ SkinTheme::SkinTheme()
SkinTheme::~SkinTheme()
{
// Delete all cursors.
for (size_t c=0; c<m_cursors.size(); ++c)
delete m_cursors[c];
for (auto it : m_cursors)
delete it.second; // Delete cursor
if (m_sheet)
m_sheet->dispose();
@ -429,21 +419,27 @@ void SkinTheme::loadXml(const std::string& skinId)
int focusx = std::strtol(xmlPart->Attribute("focusx"), NULL, 10);
int focusy = std::strtol(xmlPart->Attribute("focusy"), NULL, 10);
LOG(VERBOSE) << "THEME: Loading cursor '" << cursorName << "'\n";
auto it = m_cursors.find(cursorName);
if (it != m_cursors.end() && it->second != nullptr) {
delete it->second;
it->second = nullptr;
}
// TODO share the Surface with the SkinPart
she::Surface* slice = sliceSheet(nullptr, gfx::Rect(x, y, w, h));
Cursor* cursor =
new Cursor(slice,
gfx::Point(focusx*guiscale(),
focusy*guiscale()));
m_cursors[cursorName] = cursor;
for (int c=0; c<kCursorTypes; ++c) {
if (cursorName != g_cursor_names[c])
continue;
LOG(VERBOSE) << "THEME: Loading cursor '" << cursorName << "'\n";
delete m_cursors[c];
m_cursors[c] = nullptr;
// TODO share the Surface with the SkinPart
she::Surface* slice = sliceSheet(nullptr, gfx::Rect(x, y, w, h));
m_cursors[c] = new Cursor(slice,
gfx::Point(focusx*guiscale(),
focusy*guiscale()));
break;
if (cursorName == g_cursor_names[c]) {
m_standardCursors[c] = cursor;
break;
}
}
}
@ -686,15 +682,12 @@ she::Font* SkinTheme::getWidgetFont(const Widget* widget) const
return getDefaultFont();
}
Cursor* SkinTheme::getCursor(CursorType type)
Cursor* SkinTheme::getStandardCursor(CursorType type)
{
if (type == kNoCursor) {
return NULL;
}
else {
ASSERT(type >= kFirstCursorType && type <= kLastCursorType);
return m_cursors[type];
}
if (type >= kFirstCursorType && type <= kLastCursorType)
return m_standardCursors[type];
else
return nullptr;
}
void SkinTheme::initWidget(Widget* widget)

View File

@ -18,6 +18,7 @@
#include <map>
#include <string>
#include <vector>
namespace ui {
class Entry;
@ -49,7 +50,7 @@ namespace app {
she::Font* getWidgetFont(const ui::Widget* widget) const override;
she::Font* getMiniFont() const { return m_miniFont; }
ui::Cursor* getCursor(ui::CursorType type) override;
ui::Cursor* getStandardCursor(ui::CursorType type) override;
void initWidget(ui::Widget* widget) override;
void getWindowMask(ui::Widget* widget, gfx::Region& region) override;
int getScrollbarSize() override;
@ -96,6 +97,14 @@ namespace app {
return SkinPartPtr(nullptr);
}
ui::Cursor* getCursorById(const std::string& id) const {
auto it = m_cursors.find(id);
if (it != m_cursors.end())
return it->second;
else
return nullptr;
}
int getDimensionById(const std::string& id) const {
// Warning! Don't use ui::guiscale(), as CurrentTheme::get()
// is still nullptr when we use this getDimensionById()
@ -139,7 +148,8 @@ namespace app {
std::map<std::string, SkinPartPtr> m_parts_by_id;
std::map<std::string, gfx::Color> m_colors_by_id;
std::map<std::string, int> m_dimensions_by_id;
std::vector<ui::Cursor*> m_cursors;
std::map<std::string, ui::Cursor*> m_cursors;
std::vector<ui::Cursor*> m_standardCursors;
std::map<std::string, ui::Style*> m_styles;
std::map<std::string, FontData*> m_fonts;
std::map<std::string, she::Font*> m_themeFonts;
@ -147,14 +157,6 @@ namespace app {
she::Font* m_miniFont;
};
inline SkinPartPtr get_part_by_id(const std::string& id) {
return static_cast<SkinTheme*>(ui::Manager::getDefault()->theme())->getPartById(id);
}
inline gfx::Color get_color_by_id(const std::string& id) {
return static_cast<SkinTheme*>(ui::Manager::getDefault()->theme())->getColorById(id);
}
} // namespace skin
} // namespace app

View File

@ -17,6 +17,7 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
std::vector<std::string> dimensions;
std::vector<std::string> colors;
std::vector<std::string> parts;
std::vector<std::string> cursors;
std::vector<std::string> styles;
TiXmlHandle handle(doc);
@ -46,7 +47,10 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
.FirstChild("part").ToElement();
while (elem) {
const char* id = elem->Attribute("id");
if (!strchr(id, ':'))
if (std::strncmp(id, "cursor_", 7) == 0) {
cursors.push_back(std::string(id).substr(7));
}
else if (!std::strchr(id, ':'))
parts.push_back(id);
elem = elem->NextSiblingElement();
}
@ -136,7 +140,27 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
std::cout
<< " };\n";
// New styles sub class
// Cursors sub class
std::cout
<< " class Cursors {\n"
<< " template<typename> friend class ThemeFile;\n"
<< " public:\n";
for (auto cursor : cursors) {
std::string id = convert_xmlid_to_cppid(cursor, false);
std::cout
<< " const ui::Cursor* " << id << "() const { return m_" << id << "; }\n";
}
std::cout
<< " private:\n";
for (auto cursor : cursors) {
std::string id = convert_xmlid_to_cppid(cursor, false);
std::cout
<< " ui::Cursor* m_" << id << ";\n";
}
std::cout
<< " };\n";
// Styles sub class
std::cout
<< "\n"
<< " class Styles {\n"
@ -162,6 +186,7 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
<< " Dimensions dimensions;\n"
<< " Colors colors;\n"
<< " Parts parts;\n"
<< " Cursors cursors;\n"
<< " Styles styles;\n"
<< "\n"
<< " protected:\n"
@ -181,6 +206,11 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
std::cout << " byId(parts.m_" << id
<< ", \"" << part << "\");\n";
}
for (auto cursor : cursors) {
std::string id = convert_xmlid_to_cppid(cursor, false);
std::cout << " byId(cursors.m_" << id
<< ", \"" << cursor << "\");\n";
}
for (auto style : styles) {
std::string id = convert_xmlid_to_cppid(style, false);
std::cout << " byId(styles.m_" << id
@ -199,6 +229,9 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
<< " void byId(skin::SkinPartPtr& part, const std::string& id) {\n"
<< " part = static_cast<T*>(this)->getPartById(id);\n"
<< " }\n"
<< " void byId(ui::Cursor*& cursor, const std::string& id) {\n"
<< " cursor = static_cast<T*>(this)->getCursorById(id);\n"
<< " }\n"
<< " void byId(ui::Style*& style, const std::string& id) {\n"
<< " style = static_cast<T*>(this)->getStyleById(id);\n"
<< " }\n";

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -20,7 +20,7 @@ namespace ui {
Cursor(she::Surface* surface, const gfx::Point& focus);
~Cursor();
she::Surface* getSurface() { return m_surface; }
she::Surface* getSurface() const { return m_surface; }
const gfx::Point& getFocus() const { return m_focus; }
private:

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -16,12 +16,12 @@ namespace ui {
kFirstCursorType = 0,
kNoCursor = 0,
kArrowCursor,
kArrowPlusCursor,
kArrowPlusCursor, // Copy element
kCrosshairCursor,
kForbiddenCursor,
kHandCursor,
kScrollCursor,
kMoveCursor,
kHandCursor, // Hand to press a link
kScrollCursor, // Hand to scroll
kMoveCursor, // Drag and drop cursor
kSizeNSCursor,
kSizeWECursor,
@ -35,20 +35,10 @@ namespace ui {
kSizeWCursor,
kSizeNWCursor,
kRotateNCursor,
kRotateNECursor,
kRotateECursor,
kRotateSECursor,
kRotateSCursor,
kRotateSWCursor,
kRotateWCursor,
kRotateNWCursor,
kEyedropperCursor,
kMagnifierCursor,
kLastCursorType = kMagnifierCursor,
kLastCursorType = kSizeNWCursor,
kCursorTypes,
kCustomCursor,
};
} // namespace ui

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -28,10 +28,11 @@ namespace ui {
// Current mouse cursor type.
static CursorType mouse_cursor_type = kOutsideDisplay;
static Cursor* mouse_cursor = NULL;
static she::Display* mouse_display = NULL;
static Overlay* mouse_cursor_overlay = NULL;
static bool use_native_mouse_cursor = false;
static const Cursor* mouse_cursor_custom = nullptr;
static const Cursor* mouse_cursor = nullptr;
static she::Display* mouse_display = nullptr;
static Overlay* mouse_cursor_overlay = nullptr;
static bool use_native_mouse_cursor = true;
static bool support_native_custom_cursor = false;
// Mouse information (button and position).
@ -42,7 +43,7 @@ static int mouse_cursor_scale = 1;
static int mouse_scares = 0;
static void update_mouse_overlay(Cursor* cursor)
static void update_mouse_overlay(const Cursor* cursor)
{
mouse_cursor = cursor;
@ -68,7 +69,7 @@ static void update_mouse_overlay(Cursor* cursor)
}
}
static bool update_custom_native_cursor(Cursor* cursor)
static bool update_custom_native_cursor(const Cursor* cursor)
{
bool result = false;
@ -98,7 +99,7 @@ static bool update_custom_native_cursor(Cursor* cursor)
static void update_mouse_cursor()
{
she::NativeCursor nativeCursor = she::kNoCursor;
Cursor* cursor = nullptr;
const Cursor* cursor = nullptr;
if (use_native_mouse_cursor ||
mouse_cursor_type == kOutsideDisplay) {
@ -150,9 +151,11 @@ static void update_mouse_cursor()
// Use a custom cursor
if (nativeCursor == she::kNoCursor &&
mouse_cursor_type != ui::kOutsideDisplay &&
get_theme()) {
cursor = get_theme()->getCursor(mouse_cursor_type);
mouse_cursor_type != ui::kOutsideDisplay) {
if (get_theme() && mouse_cursor_type != ui::kCustomCursor)
cursor = get_theme()->getStandardCursor(mouse_cursor_type);
else
cursor = mouse_cursor_custom;
}
// Try to use a custom native cursor if it's possible
@ -236,12 +239,14 @@ CursorType get_mouse_cursor()
return mouse_cursor_type;
}
void set_mouse_cursor(CursorType type)
void set_mouse_cursor(CursorType type, const Cursor* cursor)
{
if (mouse_cursor_type == type)
if (mouse_cursor_type == type &&
mouse_cursor_custom == cursor)
return;
mouse_cursor_type = type;
mouse_cursor_custom = cursor;
update_mouse_cursor();
}

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -17,6 +17,7 @@ namespace she { class Display; }
namespace ui {
class Cursor;
class Widget;
class UISystem {
@ -36,7 +37,7 @@ namespace ui {
void set_use_native_cursors(bool state);
CursorType get_mouse_cursor();
void set_mouse_cursor(CursorType type);
void set_mouse_cursor(CursorType type, const Cursor* cursor = nullptr);
void set_mouse_cursor_scale(const int newScale);
void hide_mouse_cursor();

View File

@ -131,9 +131,7 @@ Theme::~Theme()
void Theme::regenerate()
{
CursorType type = get_mouse_cursor();
set_mouse_cursor(kNoCursor);
onRegenerate();
// TODO We cannot reinitialize all widgets because this mess all
@ -141,8 +139,6 @@ void Theme::regenerate()
// uiscale() and get the new look without the need to restart the
// whole app.
//details::reinitThemeForAllWidgets();
set_mouse_cursor(type);
}
void Theme::setDecorativeWidgetBounds(Widget* widget)

View File

@ -58,7 +58,7 @@ namespace ui {
virtual she::Font* getDefaultFont() const = 0;
virtual she::Font* getWidgetFont(const Widget* widget) const = 0;
virtual Cursor* getCursor(CursorType type) = 0;
virtual 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);