aseprite/src/ui/system.cpp

307 lines
6.9 KiB
C++

// Aseprite UI Library
// Copyright (C) 2001-2013 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 "ui/system.h"
#include "gfx/point.h"
#include "she/clock.h"
#include "she/display.h"
#include "she/surface.h"
#include "ui/cursor.h"
#include "ui/intern.h"
#include "ui/manager.h"
#include "ui/overlay.h"
#include "ui/overlay_manager.h"
#include "ui/theme.h"
#include "ui/widget.h"
namespace ui {
bool dirty_display_flag = true;
// Current mouse cursor type.
static CursorType mouse_cursor_type = kNoCursor;
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 bool native_cursor_set = false; // If we displayed a native cursor
/* Mouse information (button and position). */
static volatile int m_b[2];
static int m_x[2];
static int m_y[2];
static int m_z[2];
static int mouse_scares = 0;
static void update_mouse_overlay(Cursor* cursor)
{
mouse_cursor = cursor;
if (mouse_cursor && mouse_scares == 0) {
if (!mouse_cursor_overlay) {
mouse_cursor_overlay = new Overlay(
mouse_cursor->getSurface(),
gfx::Point(m_x[0], m_y[0]),
Overlay::MouseZOrder);
OverlayManager::instance()->addOverlay(mouse_cursor_overlay);
}
else {
mouse_cursor_overlay->setSurface(mouse_cursor->getSurface());
update_cursor_overlay();
}
}
else if (mouse_cursor_overlay) {
OverlayManager::instance()->removeOverlay(mouse_cursor_overlay);
mouse_cursor_overlay->setSurface(NULL);
delete mouse_cursor_overlay;
mouse_cursor_overlay = NULL;
}
}
static void update_mouse_cursor()
{
// Use native cursor when it's possible/available/configured to do so.
bool native_cursor_available = false;
if (use_native_mouse_cursor) {
she::NativeCursor nativeCursor = she::kNoCursor;
native_cursor_available = true;
switch (mouse_cursor_type) {
case ui::kNoCursor: break;
case ui::kArrowCursor:
case ui::kArrowPlusCursor:
nativeCursor = she::kArrowCursor;
break;
case ui::kForbiddenCursor:
nativeCursor = she::kForbiddenCursor;
break;
case ui::kHandCursor:
nativeCursor = she::kLinkCursor;
break;
case ui::kScrollCursor:
case ui::kMoveCursor:
nativeCursor = she::kMoveCursor;
break;
case ui::kSizeNSCursor: nativeCursor = she::kSizeNSCursor; break;
case ui::kSizeWECursor: nativeCursor = she::kSizeWECursor; break;
case ui::kSizeNCursor: nativeCursor = she::kSizeNCursor; break;
case ui::kSizeNECursor: nativeCursor = she::kSizeNECursor; break;
case ui::kSizeECursor: nativeCursor = she::kSizeECursor; break;
case ui::kSizeSECursor: nativeCursor = she::kSizeSECursor; break;
case ui::kSizeSCursor: nativeCursor = she::kSizeSCursor; break;
case ui::kSizeSWCursor: nativeCursor = she::kSizeSWCursor; break;
case ui::kSizeWCursor: nativeCursor = she::kSizeWCursor; break;
case ui::kSizeNWCursor: nativeCursor = she::kSizeNWCursor; break;
default:
native_cursor_available = false;
break;
}
if (native_cursor_available) {
native_cursor_available =
mouse_display->setNativeMouseCursor(nativeCursor);
native_cursor_set = (nativeCursor != she::kNoCursor);
}
}
// Hide native cursor if it is visible but the current cursor type
// is not supported natively.
if (!native_cursor_available && native_cursor_set) {
mouse_display->setNativeMouseCursor(she::kNoCursor);
native_cursor_set = false;
}
// Use a software cursor with the overlay.
if (!native_cursor_set) {
if (mouse_cursor_type == ui::kNoCursor)
update_mouse_overlay(NULL);
else
update_mouse_overlay(CurrentTheme::get()->getCursor(mouse_cursor_type));
}
else {
// Hide the overlay if we are using a native cursor.
update_mouse_overlay(NULL);
}
dirty_display_flag = true;
}
int _ji_system_init()
{
mouse_cursor_type = kNoCursor;
return 0;
}
void _ji_system_exit()
{
set_display(NULL);
update_mouse_overlay(NULL);
}
int clock()
{
return she::clock_value();
}
void set_display(she::Display* display)
{
CursorType cursor = jmouse_get_cursor();
jmouse_set_cursor(kNoCursor);
mouse_display = display;
if (display) {
Manager* manager = Manager::getDefault();
if (manager) {
manager->setDisplay(display);
// Update default-manager size
if ((manager->getBounds().w != ui::display_w() ||
manager->getBounds().h != ui::display_h())) {
manager->setBounds(gfx::Rect(0, 0, ui::display_w(), ui::display_h()));
}
}
jmouse_set_cursor(cursor); // Restore mouse cursor
}
}
int display_w()
{
if (mouse_display)
return mouse_display->width() / mouse_display->scale();
else
return 1;
}
int display_h()
{
if (mouse_display)
return mouse_display->height() / mouse_display->scale();
else
return 1;
}
void update_cursor_overlay()
{
if (mouse_cursor_overlay != NULL && mouse_scares == 0) {
gfx::Point newPos(m_x[0]-mouse_cursor->getFocus().x,
m_y[0]-mouse_cursor->getFocus().y);
if (newPos != mouse_cursor_overlay->getPosition()) {
mouse_cursor_overlay->moveOverlay(newPos);
dirty_display_flag = true;
}
}
}
void set_use_native_cursors(bool state)
{
use_native_mouse_cursor = state;
}
CursorType jmouse_get_cursor()
{
return mouse_cursor_type;
}
void jmouse_set_cursor(CursorType type)
{
if (mouse_cursor_type == type)
return;
mouse_cursor_type = type;
update_mouse_cursor();
}
void jmouse_hide()
{
ASSERT(mouse_scares >= 0);
mouse_scares++;
}
void jmouse_show()
{
ASSERT(mouse_scares > 0);
mouse_scares--;
if (mouse_scares == 0)
update_mouse_cursor();
}
bool jmouse_is_hidden()
{
ASSERT(mouse_scares >= 0);
return mouse_scares > 0;
}
bool jmouse_is_shown()
{
ASSERT(mouse_scares >= 0);
return mouse_scares == 0;
}
void _internal_no_mouse_position()
{
update_mouse_overlay(NULL);
}
void _internal_set_mouse_position(const gfx::Point& newPos)
{
if (m_x[0] >= 0) {
m_x[1] = m_x[0];
m_y[1] = m_y[0];
}
else {
m_x[1] = newPos.x;
m_y[1] = newPos.y;
}
m_x[0] = newPos.x;
m_y[0] = newPos.y;
}
void _internal_set_mouse_buttons(MouseButtons buttons)
{
m_b[1] = m_b[0];
m_b[0] = buttons;
}
gfx::Point get_mouse_position()
{
return gfx::Point(jmouse_x(0), jmouse_y(0));
}
void set_mouse_position(const gfx::Point& newPos)
{
if (mouse_display)
mouse_display->setMousePosition(newPos);
_internal_set_mouse_position(newPos);
}
MouseButtons jmouse_b(int antique)
{
return (MouseButtons)m_b[antique & 1];
}
int jmouse_x(int antique) { return m_x[antique & 1]; }
int jmouse_y(int antique) { return m_y[antique & 1]; }
int jmouse_z(int antique) { return m_z[antique & 1]; }
} // namespace ui