Merge branch 'eraser-support'

This commit is contained in:
David Capello 2016-04-21 13:22:23 -03:00
commit 56e663bca4
28 changed files with 522 additions and 56 deletions

View File

@ -102,7 +102,6 @@ add_subdirectory(flic)
add_subdirectory(gen)
add_subdirectory(gfx)
add_subdirectory(net)
add_subdirectory(pen)
add_subdirectory(render)
add_subdirectory(script)
add_subdirectory(she)

View File

@ -445,7 +445,6 @@ target_link_libraries(app-lib
flic-lib
gfx-lib
net-lib
pen-lib
render-lib
script-lib
she

View File

@ -67,7 +67,6 @@
#include "doc/palette.h"
#include "doc/site.h"
#include "doc/sprite.h"
#include "pen/pen.h"
#include "render/render.h"
#include "script/engine_delegate.h"
#include "she/display.h"
@ -666,9 +665,6 @@ void App::run()
{
// Run the GUI
if (isGui()) {
// Initialize Wacom tablet API
pen::PenAPI pen(she::instance()->defaultDisplay()->nativeHandle());
// Initialize Steam API
#ifdef ENABLE_STEAM
steam::SteamAPI steam;

View File

@ -113,6 +113,7 @@ protected:
if (lmb->isPressed(msg) || rmb->isPressed(msg)) {
MouseMessage mouseMsg(
(msg->type() == kKeyDownMessage ? kMouseDownMessage: kMouseUpMessage),
PointerType::Unknown,
(lmb->isPressed(msg) ? kButtonLeft: kButtonRight),
msg->modifiers(),
ui::get_mouse_position());

View File

@ -164,6 +164,7 @@ Editor::Editor(Document* document, EditorFlags flags)
, m_antsOffset(0)
, m_customizationDelegate(NULL)
, m_docView(NULL)
, m_lastPointerType(ui::PointerType::Unknown)
, m_flags(flags)
, m_secondaryButton(false)
, m_aniSpeed(1.0)
@ -919,6 +920,12 @@ tools::Tool* Editor::getCurrentEditorTool()
if (m_quicktool)
return m_quicktool;
// Eraser tip
if (m_lastPointerType == ui::PointerType::Eraser) {
tools::ToolBox* toolbox = App::instance()->getToolBox();
return toolbox->getToolById(tools::WellKnownTools::Eraser);
}
tools::Tool* tool = App::instance()->activeTool();
if (m_secondaryButton &&
@ -1283,6 +1290,8 @@ bool Editor::onProcessMessage(Message* msg)
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
m_oldPos = mouseMsg->position();
m_lastPointerType = mouseMsg->pointerType();
if (!m_secondaryButton && mouseMsg->right()) {
m_secondaryButton = mouseMsg->right();
@ -1300,6 +1309,9 @@ bool Editor::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);
m_lastPointerType = static_cast<MouseMessage*>(msg)->pointerType();
return m_state->onMouseMove(this, static_cast<MouseMessage*>(msg));
}
break;
@ -1310,6 +1322,8 @@ bool Editor::onProcessMessage(Message* msg)
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
bool result = m_state->onMouseUp(this, mouseMsg);
m_lastPointerType = mouseMsg->pointerType();
if (!hasCapture()) {
m_secondaryButton = false;
@ -1328,6 +1342,9 @@ bool Editor::onProcessMessage(Message* msg)
if (m_sprite) {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
EditorStatePtr holdState(m_state);
m_lastPointerType = mouseMsg->pointerType();
bool used = m_state->onDoubleClick(this, mouseMsg);
if (used)
return true;

View File

@ -28,6 +28,7 @@
#include "render/zoom.h"
#include "ui/base.h"
#include "ui/cursor_type.h"
#include "ui/pointer_type.h"
#include "ui/timer.h"
#include "ui/widget.h"
@ -325,6 +326,7 @@ namespace app {
DocumentView* m_docView;
gfx::Point m_oldPos;
ui::PointerType m_lastPointerType;
EditorFlags m_flags;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -221,6 +221,7 @@ bool ToolBar::onProcessMessage(Message* msg)
MouseMessage* mouseMsg2 = new MouseMessage(
kMouseDownMessage,
mouseMsg->pointerType(),
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());
@ -635,6 +636,7 @@ bool ToolBar::ToolStrip::onProcessMessage(Message* msg)
MouseMessage* mouseMsg2 = new MouseMessage(
kMouseDownMessage,
mouseMsg->pointerType(),
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());

View File

@ -33,7 +33,7 @@ public:
LOGCONTEXTW logctx;
memset(&logctx, 0, sizeof(LOGCONTEXTW));
logctx.lcOptions |= CXO_SYSTEM;
UINT infoRes = WTInfo(WTI_DEFSYSCTX, 0, &logctx);
UINT infoRes = WTInfoW(WTI_DEFSYSCTX, 0, &logctx);
ASSERT(infoRes == sizeof(LOGCONTEXTW));
ASSERT(logctx.lcOptions & CXO_SYSTEM);

View File

@ -187,6 +187,7 @@ if(USE_SKIA_BACKEND)
if(WIN32)
list(APPEND SHE_SOURCES
skia/skia_window_win.cpp
win/pen.cpp
win/vk.cpp
win/window_dde.cpp)
elseif(APPLE)

View File

@ -24,6 +24,7 @@
#include "she/common/freetype_font.h"
#include "she/common/sprite_sheet_font.h"
#include "she/system.h"
namespace she {

View File

@ -11,6 +11,7 @@
#include "gfx/point.h"
#include "gfx/size.h"
#include "she/keys.h"
#include "she/pointer_type.h"
#include <string>
#include <vector>
@ -57,7 +58,10 @@ namespace she {
m_unicodeChar(0),
m_repeat(0),
m_preciseWheel(false),
m_button(NoneButton) {
m_pointerType(PointerType::Unknown),
m_button(NoneButton),
m_magnification(0.0),
m_pressure(0.0) {
}
Type type() const { return m_type; }
@ -73,10 +77,13 @@ namespace she {
// We suppose that if we are receiving precise scrolling deltas,
// it means that the user is using a touch-like surface (trackpad,
// magic mouse scrolling, touch wacom tablet, etc.)
// TODO change this with the new PointerType::Multitouch
bool preciseWheel() const { return m_preciseWheel; }
PointerType pointerType() const { return m_pointerType; }
MouseButton button() const { return m_button; }
double magnification() const { return m_magnification; }
double pressure() const { return m_pressure; }
void setType(Type type) { m_type = type; }
void setDisplay(Display* display) { m_display = display; }
@ -89,8 +96,10 @@ namespace she {
void setPosition(const gfx::Point& pos) { m_position = pos; }
void setWheelDelta(const gfx::Point& delta) { m_wheelDelta = delta; }
void setPreciseWheel(bool precise) { m_preciseWheel = precise; }
void setPointerType(PointerType pointerType) { m_pointerType = pointerType; }
void setButton(MouseButton button) { m_button = button; }
void setMagnification(double magnification) { m_magnification = magnification; }
void setPressure(double pressure) { m_pressure = pressure; }
private:
Type m_type;
@ -103,8 +112,14 @@ namespace she {
gfx::Point m_position;
gfx::Point m_wheelDelta;
bool m_preciseWheel;
PointerType m_pointerType;
MouseButton m_button;
// For TouchMagnify event
double m_magnification;
// Pressure of stylus used in mouse-like events
double m_pressure;
};
} // namespace she

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2015 David Capello
// Copyright (C) 2015-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,6 +8,8 @@
#define SHE_OSX_VIEW_H_INCLUDED
#pragma once
#include "she/pointer_type.h"
#include <Cocoa/Cocoa.h>
@interface OSXView : NSView {
@ -15,6 +17,7 @@
NSTrackingArea* m_trackingArea;
NSCursor* m_nsCursor;
bool m_visibleMouse;
she::PointerType m_pointerType;
}
- (id)initWithFrame:(NSRect)frameRect;
- (BOOL)acceptsFirstResponder;

View File

@ -92,6 +92,7 @@ bool is_key_pressed(KeyScancode scancode)
{
m_nsCursor = [NSCursor arrowCursor];
m_visibleMouse = true;
m_pointerType = she::PointerType::Unknown;
self = [super initWithFrame:frameRect];
if (self != nil) {
@ -307,6 +308,10 @@ bool is_key_pressed(KeyScancode scancode)
ev.setPosition(get_local_mouse_pos(self, event));
ev.setButton(get_mouse_buttons(event));
ev.setModifiers(get_modifiers_from_nsevent(event));
if (m_pointerType != she::PointerType::Unknown)
ev.setPointerType(m_pointerType);
queue_event(ev);
}
@ -317,6 +322,10 @@ bool is_key_pressed(KeyScancode scancode)
ev.setPosition(get_local_mouse_pos(self, event));
ev.setButton(get_mouse_buttons(event));
ev.setModifiers(get_modifiers_from_nsevent(event));
if (m_pointerType != she::PointerType::Unknown)
ev.setPointerType(m_pointerType);
queue_event(ev);
}
@ -327,6 +336,10 @@ bool is_key_pressed(KeyScancode scancode)
ev.setPosition(get_local_mouse_pos(self, event));
ev.setButton(get_mouse_buttons(event));
ev.setModifiers(get_modifiers_from_nsevent(event));
if (m_pointerType != she::PointerType::Unknown)
ev.setPointerType(m_pointerType);
queue_event(ev);
}
@ -360,11 +373,13 @@ bool is_key_pressed(KeyScancode scancode)
scale = [(OSXWindow*)self.window scale];
if (event.hasPreciseScrollingDeltas) {
ev.setPointerType(she::PointerType::Multitouch);
ev.setWheelDelta(gfx::Point(-event.scrollingDeltaX / scale,
-event.scrollingDeltaY / scale));
ev.setPreciseWheel(true);
}
else {
ev.setPointerType(she::PointerType::Mouse);
ev.setWheelDelta(gfx::Point(-event.scrollingDeltaX,
-event.scrollingDeltaY));
}
@ -379,10 +394,27 @@ bool is_key_pressed(KeyScancode scancode)
ev.setMagnification(event.magnification);
ev.setPosition(get_local_mouse_pos(self, event));
ev.setModifiers(get_modifiers_from_nsevent(event));
ev.setPointerType(she::PointerType::Multitouch);
queue_event(ev);
}
- (void)tabletProximity:(NSEvent*)event
{
if (event.isEnteringProximity == YES) {
switch (event.pointingDeviceType) {
case NSPenPointingDevice: m_pointerType = she::PointerType::Pen; break;
case NSCursorPointingDevice: m_pointerType = she::PointerType::Cursor; break;
case NSEraserPointingDevice: m_pointerType = she::PointerType::Eraser; break;
default:
m_pointerType = she::PointerType::Unknown;
break;
}
}
else {
m_pointerType = she::PointerType::Unknown;
}
}
- (void)cursorUpdate:(NSEvent*)event
{
[self updateCurrentCursor];

25
src/she/pointer_type.h Normal file
View File

@ -0,0 +1,25 @@
// SHE library
// Copyright (C) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_POINTER_TYPE_H_INCLUDED
#define SHE_POINTER_TYPE_H_INCLUDED
#pragma once
namespace she {
// Source of a mouse like event
enum class PointerType {
Unknown,
Mouse, // A regular mouse
Multitouch, // Trackpad/multitouch surface
Pen, // Stylus pen
Cursor, // Puck like device
Eraser // Eraser end of a stylus pen
};
} // namespace she
#endif

View File

@ -13,8 +13,6 @@
#include "gfx/size.h"
#include "she/she.h"
#include "she/common/system.h"
#include "she/skia/skia_system.h"
#if __APPLE__

View File

@ -15,23 +15,28 @@
#include "SkPixelRef.h"
#include "SkStream.h"
#include "she/common/system.h"
#include "she/skia/skia_display.h"
#include "she/skia/skia_surface.h"
#ifdef _WIN32
#include "she/win/event_queue.h"
#include "she/win/system.h"
#define SkiaSystemBase WindowSystem
#elif __APPLE__
#include "she/osx/app.h"
#include "she/osx/event_queue.h"
#define SkiaSystemBase CommonSystem
#else
#include "she/x11/event_queue.h"
#define SkiaSystemBase CommonSystem
#endif
namespace she {
EventQueueImpl g_queue;
class SkiaSystem : public CommonSystem {
class SkiaSystem : public SkiaSystemBase {
public:
SkiaSystem()
: m_defaultDisplay(nullptr)

111
src/she/win/pen.cpp Normal file
View File

@ -0,0 +1,111 @@
// SHE library
// Copyright (C) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "she/win/pen.h"
#include "base/debug.h"
#include "base/fs.h"
#include "base/log.h"
#include "base/path.h"
#include "base/string.h"
typedef UINT (API* WTInfoW_Func)(UINT, UINT, LPVOID);
typedef HCTX (API* WTOpenW_Func)(HWND, LPLOGCONTEXTW, BOOL);
typedef BOOL (API* WTClose_Func)(HCTX);
typedef BOOL (API* WTPacket_Func)(HCTX, UINT, LPVOID);
namespace she {
static WTInfoW_Func WTInfo;
static WTOpenW_Func WTOpen;
static WTClose_Func WTClose;
static WTPacket_Func WTPacket;
PenAPI::PenAPI()
: m_wintabLib(nullptr)
{
}
PenAPI::~PenAPI()
{
if (!m_wintabLib)
return;
base::unload_dll(m_wintabLib);
m_wintabLib = nullptr;
}
HCTX PenAPI::open(HWND hwnd)
{
if (!m_wintabLib && !loadWintab())
return nullptr;
LOGCONTEXTW logctx;
memset(&logctx, 0, sizeof(LOGCONTEXTW));
UINT infoRes = WTInfo(WTI_DEFSYSCTX, 0, &logctx);
ASSERT(infoRes == sizeof(LOGCONTEXTW));
ASSERT(logctx.lcOptions & CXO_SYSTEM);
logctx.lcOptions =
CXO_SYSTEM |
CXO_MESSAGES |
CXO_CSRMESSAGES;
logctx.lcPktData = PACKETDATA;
logctx.lcPktMode = PACKETMODE;
logctx.lcMoveMask = PACKETDATA;
HCTX ctx = WTOpen(hwnd, &logctx, TRUE);
if (!ctx) {
LOG("Error attaching pen to display\n");
return nullptr;
}
LOG("Pen attached to display\n");
return ctx;
}
void PenAPI::close(HCTX ctx)
{
if (ctx) {
ASSERT(m_wintabLib);
LOG("Pen detached from window\n");
WTClose(ctx);
}
}
bool PenAPI::packet(HCTX ctx, UINT serial, LPVOID packet)
{
return (WTPacket(ctx, serial, packet) ? true: false);
}
bool PenAPI::loadWintab()
{
ASSERT(!m_wintabLib);
m_wintabLib = base::load_dll("wintab32.dll");
if (!m_wintabLib) {
LOG("wintab32.dll is not present\n");
return false;
}
WTInfo = base::get_dll_proc<WTInfoW_Func>(m_wintabLib, "WTInfoW");
WTOpen = base::get_dll_proc<WTOpenW_Func>(m_wintabLib, "WTOpenW");
WTClose = base::get_dll_proc<WTClose_Func>(m_wintabLib, "WTClose");
WTPacket = base::get_dll_proc<WTPacket_Func>(m_wintabLib, "WTPacket");
if (!WTInfo || !WTOpen || !WTClose || !WTPacket) {
LOG("wintab32.dll does not contain all required functions\n");
return false;
}
LOG("Pen initialized\n");
return true;
}
} // namespace she

41
src/she/win/pen.h Normal file
View File

@ -0,0 +1,41 @@
// SHE library
// Copyright (C) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_WIN_PEN_H_INCLUDED
#define SHE_WIN_PEN_H_INCLUDED
#pragma once
#include "base/dll.h"
#include <windows.h>
#include "wacom/wintab.h"
#define PACKETDATA (PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE)
#define PACKETMODE (PK_BUTTONS)
#include "wacom/pktdef.h"
namespace she {
// Wintab API wrapper
// Read http://www.wacomeng.com/windows/docs/Wintab_v140.htm for more information.
class PenAPI {
public:
PenAPI();
~PenAPI();
HCTX open(HWND hwnd);
void close(HCTX ctx);
bool packet(HCTX ctx, UINT serial, LPVOID packet);
private:
bool loadWintab();
base::dll m_wintabLib;
};
} // namespace she
#endif

31
src/she/win/system.h Normal file
View File

@ -0,0 +1,31 @@
// SHE library
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_WIN_SYSTEM_H
#define SHE_WIN_SYSTEM_H
#pragma once
#include "she/common/system.h"
#include "she/win/pen.h"
namespace she {
class WindowSystem : public CommonSystem {
public:
WindowSystem() { }
~WindowSystem() { }
PenAPI& penApi() {
return m_penApi;
}
private:
PenAPI m_penApi;
};
} // namespace she
#endif

View File

@ -19,6 +19,7 @@
#include "she/event.h"
#include "she/keys.h"
#include "she/native_cursor.h"
#include "she/win/system.h"
#include "she/win/window_dde.h"
#ifndef WM_MOUSEHWHEEL
@ -40,16 +41,29 @@ namespace she {
, m_restoredSize(0, 0)
, m_isCreated(false)
, m_hasMouse(false)
, m_captureMouse(false) {
, m_captureMouse(false)
, m_hpenctx(nullptr)
, m_pointerType(PointerType::Unknown)
, m_pressure(0.0) {
registerClass();
m_hwnd = createHwnd(this, width, height);
m_hcursor = NULL;
m_hcursor = nullptr;
m_scale = scale;
// This flag is used to avoid calling T::resizeImpl() when we
// add the scrollbars to the window. (As the T type could not be
// fully initialized yet.)
m_isCreated = true;
// Attach Wacom context
m_hpenctx = static_cast<WindowSystem*>(she::instance())
->penApi().open(m_hwnd);
}
~WinWindow() {
if (m_hpenctx)
static_cast<WindowSystem*>(she::instance())
->penApi().close(m_hpenctx);
}
void queueEvent(Event& ev) {
@ -311,6 +325,11 @@ namespace she {
_TrackMouseEvent(&tme);
}
if (m_pointerType != PointerType::Unknown) {
ev.setPointerType(m_pointerType);
ev.setPressure(m_pressure);
}
ev.setType(Event::MouseMove);
queueEvent(ev);
break;
@ -341,6 +360,12 @@ namespace she {
msg == WM_LBUTTONDOWN ? Event::LeftButton:
msg == WM_RBUTTONDOWN ? Event::RightButton:
msg == WM_MBUTTONDOWN ? Event::MiddleButton: Event::NoneButton);
if (m_pointerType != PointerType::Unknown) {
ev.setPointerType(m_pointerType);
ev.setPressure(m_pressure);
}
queueEvent(ev);
break;
}
@ -358,6 +383,12 @@ namespace she {
msg == WM_LBUTTONUP ? Event::LeftButton:
msg == WM_RBUTTONUP ? Event::RightButton:
msg == WM_MBUTTONUP ? Event::MiddleButton: Event::NoneButton);
if (m_pointerType != PointerType::Unknown) {
ev.setPointerType(m_pointerType);
ev.setPressure(m_pressure);
}
queueEvent(ev);
// Avoid popup menu for scrollbars
@ -380,6 +411,12 @@ namespace she {
msg == WM_LBUTTONDBLCLK ? Event::LeftButton:
msg == WM_RBUTTONDBLCLK ? Event::RightButton:
msg == WM_MBUTTONDBLCLK ? Event::MiddleButton: Event::NoneButton);
if (m_pointerType != PointerType::Unknown) {
ev.setPointerType(m_pointerType);
ev.setPressure(m_pressure);
}
queueEvent(ev);
break;
}
@ -573,6 +610,60 @@ namespace she {
return result;
}
case WT_PROXIMITY: {
bool entering_ctx = (LOWORD(lparam) ? true: false);
if (!entering_ctx)
m_pointerType = PointerType::Unknown;
break;
}
case WT_CSRCHANGE: { // From Wintab 1.1
auto& api = static_cast<WindowSystem*>(she::instance())->penApi();
UINT serial = wparam;
HCTX ctx = (HCTX)lparam;
PACKET packet;
if (api.packet(ctx, serial, &packet)) {
switch (packet.pkCursor) {
case 0:
case 3:
m_pointerType = PointerType::Cursor;
break;
case 1:
case 4:
m_pointerType = PointerType::Pen;
break;
case 2
case 5:
m_pointerType = PointerType::Eraser;
break;
default:
m_pointerType = PointerType::Unknown;
break;
}
else
m_pointerType = PointerType::Unknown;
}
case WT_PACKET: {
auto& api = static_cast<WindowSystem*>(she::instance())->penApi();
UINT serial = wparam;
HCTX ctx = (HCTX)lparam;
PACKET packet;
if (api.packet(ctx, serial, &packet)) {
m_pressure = packet.pkNormalPressure / 1000.0; // TODO get the maximum value
if (packet.pkCursor == 2 || packet.pkCursor == 5)
m_pointerType = PointerType::Eraser;
else
m_pointerType = PointerType::Pen;
}
else
m_pointerType = PointerType::Unknown;
break;
}
}
LRESULT result = FALSE;
@ -673,6 +764,11 @@ namespace she {
bool m_isCreated;
bool m_hasMouse;
bool m_captureMouse;
// Wintab API data
HCTX m_hpenctx;
PointerType m_pointerType;
double m_pressure;
};
} // namespace she

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -481,6 +481,7 @@ bool ComboBoxEntry::onProcessMessage(Message* msg)
releaseMouse();
MouseMessage mouseMsg2(kMouseDownMessage,
mouseMsg->pointerType(),
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -90,6 +90,7 @@ bool IntEntry::onProcessMessage(Message* msg)
releaseMouse();
MouseMessage mouseMsg2(kMouseDownMessage,
mouseMsg->pointerType(),
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());

View File

@ -247,7 +247,8 @@ bool Manager::generateMessages()
}
void Manager::generateSetCursorMessage(const gfx::Point& mousePos,
KeyModifiers modifiers)
KeyModifiers modifiers,
PointerType pointerType)
{
if (get_mouse_cursor() == kOutsideDisplay)
return;
@ -257,7 +258,9 @@ void Manager::generateSetCursorMessage(const gfx::Point& mousePos,
enqueueMessage(
newMouseMessage(
kSetCursorMessage, dst,
mousePos, _internal_get_mouse_buttons(),
mousePos,
pointerType,
_internal_get_mouse_buttons(),
modifiers));
else
set_mouse_cursor(kArrowCursor);
@ -346,8 +349,11 @@ void Manager::generateMessagesFromSheEvents()
case she::Event::MouseMove: {
_internal_set_mouse_position(sheEvent.position());
handleMouseMove(sheEvent.position(), m_mouseButtons,
sheEvent.modifiers());
handleMouseMove(
sheEvent.position(),
m_mouseButtons,
sheEvent.modifiers(),
sheEvent.pointerType());
lastMouseMoveEvent = sheEvent;
break;
}
@ -357,8 +363,11 @@ void Manager::generateMessagesFromSheEvents()
m_mouseButtons = (MouseButtons)((int)m_mouseButtons | (int)pressedButton);
_internal_set_mouse_buttons(m_mouseButtons);
handleMouseDown(sheEvent.position(), pressedButton,
sheEvent.modifiers());
handleMouseDown(
sheEvent.position(),
pressedButton,
sheEvent.modifiers(),
sheEvent.pointerType());
break;
}
@ -367,21 +376,28 @@ void Manager::generateMessagesFromSheEvents()
m_mouseButtons = (MouseButtons)((int)m_mouseButtons & ~(int)releasedButton);
_internal_set_mouse_buttons(m_mouseButtons);
handleMouseUp(sheEvent.position(), releasedButton,
sheEvent.modifiers());
handleMouseUp(
sheEvent.position(),
releasedButton,
sheEvent.modifiers(),
sheEvent.pointerType());
break;
}
case she::Event::MouseDoubleClick: {
MouseButtons clickedButton = mouse_buttons_from_she_to_ui(sheEvent);
handleMouseDoubleClick(sheEvent.position(), clickedButton,
sheEvent.modifiers());
handleMouseDoubleClick(
sheEvent.position(),
clickedButton,
sheEvent.modifiers(),
sheEvent.pointerType());
break;
}
case she::Event::MouseWheel: {
handleMouseWheel(sheEvent.position(), m_mouseButtons,
sheEvent.modifiers(),
sheEvent.pointerType(),
sheEvent.wheelDelta(),
sheEvent.preciseWheel());
break;
@ -403,13 +419,15 @@ void Manager::generateMessagesFromSheEvents()
if (lastMouseMoveEvent.type() != she::Event::None) {
sheEvent = lastMouseMoveEvent;
generateSetCursorMessage(sheEvent.position(),
sheEvent.modifiers());
sheEvent.modifiers(),
sheEvent.pointerType());
}
}
void Manager::handleMouseMove(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers)
KeyModifiers modifiers,
PointerType pointerType)
{
// Get the list of widgets to send mouse messages.
mouse_widgets_list.clear();
@ -436,12 +454,16 @@ void Manager::handleMouseMove(const gfx::Point& mousePos,
enqueueMessage(
newMouseMessage(
kMouseMoveMessage, dst,
mousePos, mouseButtons, modifiers));
mousePos,
pointerType,
mouseButtons,
modifiers));
}
void Manager::handleMouseDown(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers)
KeyModifiers modifiers,
PointerType pointerType)
{
handleWindowZOrder();
@ -449,41 +471,53 @@ void Manager::handleMouseDown(const gfx::Point& mousePos,
newMouseMessage(
kMouseDownMessage,
(capture_widget ? capture_widget: mouse_widget),
mousePos, mouseButtons, modifiers));
mousePos,
pointerType,
mouseButtons,
modifiers));
}
void Manager::handleMouseUp(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers)
KeyModifiers modifiers,
PointerType pointerType)
{
enqueueMessage(
newMouseMessage(
kMouseUpMessage,
(capture_widget ? capture_widget: mouse_widget),
mousePos, mouseButtons, modifiers));
mousePos,
pointerType,
mouseButtons,
modifiers));
}
void Manager::handleMouseDoubleClick(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers)
KeyModifiers modifiers,
PointerType pointerType)
{
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
if (dst) {
enqueueMessage(
newMouseMessage(
kDoubleClickMessage,
dst, mousePos, mouseButtons, modifiers));
dst, mousePos, pointerType,
mouseButtons, modifiers));
}
}
void Manager::handleMouseWheel(const gfx::Point& mousePos,
MouseButtons mouseButtons, KeyModifiers modifiers,
const gfx::Point& wheelDelta, bool preciseWheel)
MouseButtons mouseButtons,
KeyModifiers modifiers,
PointerType pointerType,
const gfx::Point& wheelDelta,
bool preciseWheel)
{
enqueueMessage(newMouseMessage(
kMouseWheelMessage,
(capture_widget ? capture_widget: mouse_widget),
mousePos, mouseButtons, modifiers,
mousePos, pointerType, mouseButtons, modifiers,
wheelDelta, preciseWheel));
}
@ -776,7 +810,9 @@ void Manager::setMouse(Widget* widget)
Message* msg = newMouseMessage(
kMouseEnterMessage, NULL,
get_mouse_position(), _internal_get_mouse_buttons(),
get_mouse_position(),
PointerType::Unknown,
_internal_get_mouse_buttons(),
kKeyUninitializedModifier);
for (; it != widget_parents.end(); ++it) {
@ -786,7 +822,8 @@ void Manager::setMouse(Widget* widget)
enqueueMessage(msg);
generateSetCursorMessage(get_mouse_position(),
kKeyUninitializedModifier);
kKeyUninitializedModifier,
PointerType::Unknown);
}
}
}
@ -1419,12 +1456,16 @@ Widget* Manager::findMagneticWidget(Widget* widget)
// static
Message* Manager::newMouseMessage(
MessageType type,
Widget* widget, const gfx::Point& mousePos,
MouseButtons buttons, KeyModifiers modifiers,
const gfx::Point& wheelDelta, bool preciseWheel)
Widget* widget,
const gfx::Point& mousePos,
PointerType pointerType,
MouseButtons buttons,
KeyModifiers modifiers,
const gfx::Point& wheelDelta,
bool preciseWheel)
{
Message* msg = new MouseMessage(
type, buttons, modifiers, mousePos,
type, pointerType, buttons, modifiers, mousePos,
wheelDelta, preciseWheel);
if (widget != NULL)

View File

@ -12,6 +12,7 @@
#include "ui/keys.h"
#include "ui/message_type.h"
#include "ui/mouse_buttons.h"
#include "ui/pointer_type.h"
#include "ui/widget.h"
namespace she {
@ -115,14 +116,32 @@ namespace ui {
virtual void onNewDisplayConfiguration();
private:
void generateSetCursorMessage(const gfx::Point& mousePos, KeyModifiers modifiers);
void generateSetCursorMessage(const gfx::Point& mousePos,
KeyModifiers modifiers,
PointerType pointerType);
void generateMessagesFromSheEvents();
void handleMouseMove(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers);
void handleMouseDown(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers);
void handleMouseUp(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers);
void handleMouseDoubleClick(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers);
void handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers,
const gfx::Point& wheelDelta, bool preciseWheel);
void handleMouseMove(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers,
PointerType pointerType);
void handleMouseDown(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers,
PointerType pointerType);
void handleMouseUp(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers,
PointerType pointerType);
void handleMouseDoubleClick(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers,
PointerType pointerType);
void handleMouseWheel(const gfx::Point& mousePos,
MouseButtons mouseButtons,
KeyModifiers modifiers,
PointerType pointerType,
const gfx::Point& wheelDelta,
bool preciseWheel);
void handleTouchMagnify(const gfx::Point& mousePos,
const KeyModifiers modifiers,
const double magnification);
@ -135,7 +154,9 @@ namespace ui {
static Message* newMouseMessage(
MessageType type,
Widget* widget, const gfx::Point& mousePos,
MouseButtons buttons, KeyModifiers modifiers,
PointerType pointerType,
MouseButtons buttons,
KeyModifiers modifiers,
const gfx::Point& wheelDelta = gfx::Point(0, 0),
bool preciseWheel = false);
void broadcastKeyMsg(Message* msg);

View File

@ -14,6 +14,7 @@
#include "ui/keys.h"
#include "ui/message_type.h"
#include "ui/mouse_buttons.h"
#include "ui/pointer_type.h"
#include "ui/widgets_list.h"
#include <string>
@ -103,18 +104,21 @@ namespace ui {
class MouseMessage : public Message {
public:
MouseMessage(MessageType type,
PointerType pointerType,
MouseButtons buttons,
KeyModifiers modifiers,
const gfx::Point& pos,
const gfx::Point& wheelDelta = gfx::Point(0, 0),
bool preciseWheel = false)
: Message(type, modifiers),
m_pointerType(pointerType),
m_buttons(buttons),
m_pos(pos),
m_wheelDelta(wheelDelta),
m_preciseWheel(preciseWheel) {
}
PointerType pointerType() const { return m_pointerType; }
MouseButtons buttons() const { return m_buttons; }
bool left() const { return (m_buttons & kButtonLeft) == kButtonLeft; }
bool right() const { return (m_buttons & kButtonRight) == kButtonRight; }
@ -125,6 +129,7 @@ namespace ui {
const gfx::Point& position() const { return m_pos; }
private:
PointerType m_pointerType;
MouseButtons m_buttons; // Pressed buttons
gfx::Point m_pos; // Mouse position
gfx::Point m_wheelDelta; // Wheel axis variation

19
src/ui/pointer_type.h Normal file
View File

@ -0,0 +1,19 @@
// Aseprite UI Library
// Copyright (C) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef UI_POINTER_TYPE_H_INCLUDED
#define UI_POINTER_TYPE_H_INCLUDED
#pragma once
#include "she/pointer_type.h"
namespace ui {
typedef she::PointerType PointerType;
} // namespace ui
#endif

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -43,14 +43,15 @@
#include "ui/overlay_manager.h"
#include "ui/paint_event.h"
#include "ui/panel.h"
#include "ui/pointer_type.h"
#include "ui/popup_window.h"
#include "ui/size_hint_event.h"
#include "ui/property.h"
#include "ui/register_message.h"
#include "ui/resize_event.h"
#include "ui/save_layout_event.h"
#include "ui/scroll_bar.h"
#include "ui/separator.h"
#include "ui/size_hint_event.h"
#include "ui/slider.h"
#include "ui/splitter.h"
#include "ui/system.h"

View File

@ -1242,6 +1242,7 @@ bool Widget::offerCapture(ui::MouseMessage* mouseMsg, int widget_type)
MouseMessage* mouseMsg2 = new MouseMessage(
kMouseDownMessage,
mouseMsg->pointerType(),
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());
@ -1328,6 +1329,7 @@ bool Widget::onProcessMessage(Message* msg)
if (kMouseDownMessage) {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
MouseMessage mouseMsg2(kMouseDownMessage,
mouseMsg->pointerType(),
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position(),