diff --git a/data/pref.xml b/data/pref.xml
index 1e4308894..c09c5230c 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -77,6 +77,10 @@
+
+
+
+
@@ -110,6 +114,7 @@
+
diff --git a/data/skins/default/sheet.png b/data/skins/default/sheet.png
index bc0ab7ac1..932b131dd 100644
Binary files a/data/skins/default/sheet.png and b/data/skins/default/sheet.png differ
diff --git a/data/skins/default/skin.xml b/data/skins/default/skin.xml
index 1687d22ea..67a2da808 100644
--- a/data/skins/default/skin.xml
+++ b/data/skins/default/skin.xml
@@ -109,6 +109,7 @@
+
diff --git a/data/widgets/options.xml b/data/widgets/options.xml
index 09311f766..5b566a257 100644
--- a/data/widgets/options.xml
+++ b/data/widgets/options.xml
@@ -96,21 +96,30 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
diff --git a/src/app/commands/cmd_options.cpp b/src/app/commands/cmd_options.cpp
index ce4a6fabe..b2638dd4c 100644
--- a/src/app/commands/cmd_options.cpp
+++ b/src/app/commands/cmd_options.cpp
@@ -78,6 +78,7 @@ public:
sectionListbox()->Change.connect(base::Bind(&OptionsWindow::onChangeSection, this));
// Cursor
+ paintingCursorType()->setSelectedItemIndex(int(m_pref.cursor.paintingCursorType()));
cursorColorPlaceholder()->addChild(m_cursorColor);
if (m_cursorColor->getColor().getType() == app::Color::MaskType) {
@@ -269,6 +270,7 @@ public:
m_pref.editor.zoomWithSlide(slideZoom()->isSelected());
#endif
m_pref.editor.rightClickMode(static_cast(rightClickBehavior()->getSelectedItemIndex()));
+ m_pref.cursor.paintingCursorType(static_cast(paintingCursorType()->getSelectedItemIndex()));
m_pref.cursor.cursorColor(m_cursorColor->getColor());
m_pref.cursor.brushPreview(static_cast(brushPreview()->getSelectedItemIndex()));
m_pref.cursor.useNativeCursor(nativeCursor()->isSelected());
diff --git a/src/app/ui/editor/brush_preview.cpp b/src/app/ui/editor/brush_preview.cpp
index 0b713e048..b6c79aa72 100644
--- a/src/app/ui/editor/brush_preview.cpp
+++ b/src/app/ui/editor/brush_preview.cpp
@@ -32,6 +32,9 @@
#include "doc/layer.h"
#include "doc/primitives.h"
#include "doc/site.h"
+#include "she/display.h"
+#include "ui/manager.h"
+#include "ui/system.h"
namespace app {
@@ -39,8 +42,9 @@ using namespace doc;
BrushPreview::BrushPreview(Editor* editor)
: m_editor(editor)
- , m_type(CROSS)
+ , m_type(CROSSHAIR)
, m_onScreen(false)
+ , m_withModifiedPixels(false)
, m_withRealPreview(false)
, m_screenPosition(0, 0)
, m_editorPosition(0, 0)
@@ -77,6 +81,9 @@ color_t BrushPreview::getBrushColor(Sprite* sprite, Layer* layer)
// Draws the brush cursor in the specified absolute mouse position
// given in 'pos' param. Warning: You should clean the cursor before
// to use this routine with other editor.
+//
+// TODO the logic in this function is really complex, we should think
+// a way to simplify all possibilities
void BrushPreview::show(const gfx::Point& screenPos)
{
if (m_onScreen)
@@ -96,9 +103,8 @@ void BrushPreview::show(const gfx::Point& screenPos)
// Get cursor color
const auto& pref = Preferences::instance();
- app::Color app_cursor_color = pref.cursor.cursorColor();
- gfx::Color ui_cursor_color = color_utils::color_for_ui(app_cursor_color);
- m_blackAndWhiteNegative = (app_cursor_color.getType() == app::Color::MaskType);
+ app::Color appCursorColor = pref.cursor.cursorColor();
+ m_blackAndWhiteNegative = (appCursorColor.getType() == app::Color::MaskType);
// Cursor in the screen (view)
m_screenPosition = screenPos;
@@ -118,7 +124,7 @@ void BrushPreview::show(const gfx::Point& screenPos)
color_t mask_index = sprite->transparentColor();
if (ink->isSelection() || ink->isSlice()) {
- m_type = SELECTION_CROSS;
+ m_type = SELECTION_CROSSHAIR;
}
else if (
(brush->type() == kImageBrushType ||
@@ -134,33 +140,43 @@ void BrushPreview::show(const gfx::Point& screenPos)
m_type = BRUSH_BOUNDARIES;
}
else {
- m_type = CROSS;
+ m_type = CROSSHAIR;
}
- bool usePreview = false;
-
+ bool showPreview = false;
auto brushPreview = pref.cursor.brushPreview();
if (!m_editor->docPref().show.brushPreview())
brushPreview = app::gen::BrushPreview::NONE;
switch (brushPreview) {
case app::gen::BrushPreview::NONE:
- m_type = CROSS;
+ m_type = CROSSHAIR;
break;
case app::gen::BrushPreview::EDGES:
m_type = BRUSH_BOUNDARIES;
break;
case app::gen::BrushPreview::FULL:
- usePreview = m_editor->getState()->requireBrushPreview();
+ showPreview = m_editor->getState()->requireBrushPreview();
break;
}
+ if (m_type & SELECTION_CROSSHAIR)
+ showPreview = false;
+
+ // Use a simple cross
+ if (pref.cursor.paintingCursorType() == gen::PaintingCursorType::SIMPLE_CROSSHAIR) {
+ m_type &= ~(CROSSHAIR | SELECTION_CROSSHAIR);
+ m_type |= NATIVE_CROSSHAIR;
+ }
+
// For cursor type 'bounds' we have to generate cursor boundaries
- if (m_type & BRUSH_BOUNDARIES)
+ if (m_type & BRUSH_BOUNDARIES) {
+ showPreview = false;
generateBoundaries();
+ }
// Draw pixel/brush preview
- if ((m_type & CROSS) && usePreview) {
+ if (showPreview) {
gfx::Rect origBrushBounds = (isFloodfill ? gfx::Rect(0, 0, 1, 1): brush->bounds());
gfx::Rect brushBounds = origBrushBounds;
brushBounds.offset(spritePos);
@@ -222,12 +238,16 @@ void BrushPreview::show(const gfx::Point& screenPos)
}
// Save area and draw the cursor
- {
+ if (!(m_type & NATIVE_CROSSHAIR) ||
+ (m_type & BRUSH_BOUNDARIES)) {
ui::ScreenGraphics g;
ui::SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
+ gfx::Color uiCursorColor = color_utils::color_for_ui(appCursorColor);
- forEachBrushPixel(&g, m_screenPosition, spritePos, ui_cursor_color, &BrushPreview::savePixelDelegate);
- forEachBrushPixel(&g, m_screenPosition, spritePos, ui_cursor_color, &BrushPreview::drawPixelDelegate);
+ forEachBrushPixel(&g, m_screenPosition, spritePos, uiCursorColor, &BrushPreview::savePixelDelegate);
+ forEachBrushPixel(&g, m_screenPosition, spritePos, uiCursorColor, &BrushPreview::drawPixelDelegate);
+
+ m_withModifiedPixels = true;
}
// Cursor in the editor (model)
@@ -236,6 +256,9 @@ void BrushPreview::show(const gfx::Point& screenPos)
// Save the clipping-region to know where to clean the pixels
m_oldClippingRegion = m_clippingRegion;
+
+ if (m_type & NATIVE_CROSSHAIR)
+ ui::set_mouse_cursor(ui::kCrosshairCursor);
}
// Cleans the brush cursor from the specified editor.
@@ -259,7 +282,7 @@ void BrushPreview::hide()
m_clippingRegion.createSubtraction(m_clippingRegion,
m_editor->getUpdateRegion());
- {
+ if (m_withModifiedPixels) {
// Restore pixels
ui::ScreenGraphics g;
ui::SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
@@ -347,10 +370,10 @@ void BrushPreview::forEachBrushPixel(
{
m_savedPixelsIterator = 0;
- if (m_type & CROSS)
+ if (m_type & CROSSHAIR)
traceCrossPixels(g, screenPos, color, pixelDelegate);
- if (m_type & SELECTION_CROSS)
+ if (m_type & SELECTION_CROSSHAIR)
traceSelectionCrossPixels(g, spritePos, color, 1, pixelDelegate);
if (m_type & BRUSH_BOUNDARIES)
@@ -358,8 +381,10 @@ void BrushPreview::forEachBrushPixel(
// Depending on the editor zoom, maybe we need subpixel movement (a
// little dot inside the active pixel)
- if (m_editor->zoom().scale() >= 4.0)
+ if (!(m_type & NATIVE_CROSSHAIR) &&
+ m_editor->zoom().scale() >= 4.0) {
(this->*pixelDelegate)(g, screenPos, color);
+ }
m_savedPixelsLimit = m_savedPixelsIterator;
}
@@ -480,7 +505,7 @@ void BrushPreview::drawPixelDelegate(ui::Graphics* gfx, const gfx::Point& pt, gf
if (m_savedPixelsIterator < (int)m_savedPixels.size() &&
m_clippingRegion.contains(pt)) {
if (m_blackAndWhiteNegative) {
- int c = m_savedPixels[m_savedPixelsIterator++];
+ int c = m_savedPixels[m_savedPixelsIterator];
int r = gfx::getr(c);
int g = gfx::getg(c);
int b = gfx::getb(c);
@@ -490,6 +515,7 @@ void BrushPreview::drawPixelDelegate(ui::Graphics* gfx, const gfx::Point& pt, gf
else {
gfx->putPixel(color, pt.x, pt.y);
}
+ ++m_savedPixelsIterator;
}
}
diff --git a/src/app/ui/editor/brush_preview.h b/src/app/ui/editor/brush_preview.h
index 0abbc295e..ddf5e3653 100644
--- a/src/app/ui/editor/brush_preview.h
+++ b/src/app/ui/editor/brush_preview.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@@ -37,9 +37,10 @@ namespace app {
public:
// Brush type
enum {
- CROSS = 1,
- SELECTION_CROSS = 2,
- BRUSH_BOUNDARIES = 4,
+ CROSSHAIR = 1,
+ SELECTION_CROSSHAIR = 2,
+ BRUSH_BOUNDARIES = 4,
+ NATIVE_CROSSHAIR = 8,
};
BrushPreview(Editor* editor);
@@ -85,6 +86,7 @@ namespace app {
// The brush preview is on the screen.
bool m_onScreen;
+ bool m_withModifiedPixels;
bool m_withRealPreview;
gfx::Point m_screenPosition; // Position in the screen (view)
gfx::Point m_editorPosition; // Position in the editor (model)
diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp
index 8c696fb5a..019fca099 100644
--- a/src/app/ui/skin/skin_theme.cpp
+++ b/src/app/ui/skin/skin_theme.cpp
@@ -103,6 +103,7 @@ static const char* cursor_names[kCursorTypes] = {
"null", // kNoCursor
"normal", // kArrowCursor
"normal_add", // kArrowPlusCursor
+ "crosshair", // kCrosshairCursor
"forbidden", // kForbiddenCursor
"hand", // kHandCursor
"scroll", // kScrollCursor
diff --git a/src/she/alleg4/alleg_display.cpp b/src/she/alleg4/alleg_display.cpp
index 519b63d9f..751f45a72 100644
--- a/src/she/alleg4/alleg_display.cpp
+++ b/src/she/alleg4/alleg_display.cpp
@@ -558,6 +558,7 @@ bool Alleg4Display::setNativeMouseCursor(NativeCursor cursor)
newCursor = MOUSE_CURSOR_QUESTION;
break;
#ifdef ALLEGRO4_WITH_EXTRA_CURSORS
+ case kCrosshairCursor: newCursor = MOUSE_CURSOR_CROSS; break;
case kForbiddenCursor: newCursor = MOUSE_CURSOR_FORBIDDEN; break;
case kMoveCursor: newCursor = MOUSE_CURSOR_MOVE; break;
case kLinkCursor: newCursor = MOUSE_CURSOR_LINK; break;
diff --git a/src/she/native_cursor.h b/src/she/native_cursor.h
index d35c5af13..8f32a7db2 100644
--- a/src/she/native_cursor.h
+++ b/src/she/native_cursor.h
@@ -15,6 +15,7 @@ namespace she {
enum NativeCursor {
kNoCursor,
kArrowCursor,
+ kCrosshairCursor,
kIBeamCursor,
kWaitCursor,
kLinkCursor,
diff --git a/src/she/osx/window.mm b/src/she/osx/window.mm
index 4770d90dd..b5b737275 100644
--- a/src/she/osx/window.mm
+++ b/src/she/osx/window.mm
@@ -120,6 +120,9 @@ using namespace she;
case kSizeSWCursor:
nsCursor = [NSCursor arrowCursor];
break;
+ case kCrosshairCursor:
+ nsCursor = [NSCursor crosshairCursor];
+ break;
case kIBeamCursor:
nsCursor = [NSCursor IBeamCursor];
break;
diff --git a/src/she/win/window.h b/src/she/win/window.h
index f89ca0746..754954643 100644
--- a/src/she/win/window.h
+++ b/src/she/win/window.h
@@ -141,6 +141,9 @@ namespace she {
case kArrowCursor:
hcursor = LoadCursor(NULL, IDC_ARROW);
break;
+ case kCrosshairCursor:
+ hcursor = LoadCursor(NULL, IDC_CROSS);
+ break;
case kIBeamCursor:
hcursor = LoadCursor(NULL, IDC_IBEAM);
break;
diff --git a/src/ui/cursor_type.h b/src/ui/cursor_type.h
index e1625ad9e..a5990211f 100644
--- a/src/ui/cursor_type.h
+++ b/src/ui/cursor_type.h
@@ -17,6 +17,7 @@ namespace ui {
kNoCursor = 0,
kArrowCursor,
kArrowPlusCursor,
+ kCrosshairCursor,
kForbiddenCursor,
kHandCursor,
kScrollCursor,
diff --git a/src/ui/system.cpp b/src/ui/system.cpp
index aae4e06ad..c0a0813d4 100644
--- a/src/ui/system.cpp
+++ b/src/ui/system.cpp
@@ -111,6 +111,9 @@ static void update_mouse_cursor()
case ui::kArrowPlusCursor:
nativeCursor = she::kArrowCursor;
break;
+ case ui::kCrosshairCursor:
+ nativeCursor = she::kCrosshairCursor;
+ break;
case ui::kForbiddenCursor:
nativeCursor = she::kForbiddenCursor;
break;