Generate mouse/key events from polling in she module instead of ui module

This commit is contained in:
David Capello 2014-09-03 00:01:30 -03:00
parent bd3fcd3fc6
commit c5a568cd15
32 changed files with 930 additions and 572 deletions

View File

@ -27,11 +27,8 @@
#include "ui/system.h"
#include "ui/theme.h"
#include <allegro.h>
#if defined ALLEGRO_WINDOWS && defined DEBUGMODE
#include <winalleg.h>
#include <windows.h>
#include <psapi.h>
#endif
@ -55,10 +52,6 @@ RefreshCommand::RefreshCommand()
void RefreshCommand::onExecute(Context* context)
{
ui::jmouse_hide();
clear_to_color(screen, makecol(0, 0, 0));
ui::jmouse_show();
// Reload skin
{
skin::SkinTheme* theme = (skin::SkinTheme*)ui::CurrentTheme::get();

View File

@ -2,8 +2,12 @@
# Copyright (C) 2012-2014 David Capello
set(SHE_SOURCES
alleg4/clock.cpp
alleg4/close_button.cpp
alleg4/fontbmp.cpp
alleg4/she_alleg4.cpp)
alleg4/key_poller.cpp
alleg4/mouse_poller.cpp
alleg4/she.cpp)
if(APPLE)
if(NOT USE_SHARED_ALLEGRO4)

43
src/she/alleg4/clock.cpp Normal file
View File

@ -0,0 +1,43 @@
// SHE library
// Copyright (C) 2012-2014 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 <allegro.h>
static volatile int clock_var = 0; // Global timer.
static void clock_inc()
{
++clock_var;
}
END_OF_STATIC_FUNCTION(clock_inc);
namespace she {
void clock_init()
{
// Install timer related stuff
LOCK_VARIABLE(clock_var);
LOCK_FUNCTION(clock_inc);
install_int_ex(clock_inc, BPS_TO_TIMER(1000));
}
void clock_exit()
{
remove_int(clock_inc);
}
int clock_value()
{
return clock_var;
}
} // namespace she

18
src/she/alleg4/clock.h Normal file
View File

@ -0,0 +1,18 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_ALLEG4_CLOCK_H_INCLUDED
#define SHE_ALLEG4_CLOCK_H_INCLUDED
#pragma once
namespace she {
void clock_init();
void clock_exit();
} // namespace she
#endif

View File

@ -0,0 +1,57 @@
// SHE library
// Copyright (C) 2012-2014 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/alleg4/internals.h"
#include "she/event.h"
#include <allegro.h>
namespace {
enum {
STAGE_NORMAL,
STAGE_WANT_CLOSE,
};
// variable to handle the external close button in some Windows enviroments
int want_close_stage;
// hooks the close-button in some platform with window support
void allegro_window_close_hook()
{
if (want_close_stage == STAGE_NORMAL)
want_close_stage = STAGE_WANT_CLOSE;
}
}
namespace she {
void close_button_init()
{
// Hook the window close message
want_close_stage = STAGE_NORMAL;
set_close_button_callback(allegro_window_close_hook);
}
void close_button_generate_events()
{
// Generate Close message when the user press close button on the system window.
if (want_close_stage == STAGE_WANT_CLOSE) {
want_close_stage = STAGE_NORMAL;
Event ev;
ev.setType(Event::CloseDisplay);
ev.setDisplay(unique_display);
queue_event(ev);
}
}
} // namespace she

View File

@ -0,0 +1,18 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_ALLEG4_CLOSE_BUTTON_H_INCLUDED
#define SHE_ALLEG4_CLOSE_BUTTON_H_INCLUDED
#pragma once
namespace she {
void close_button_init();
void close_button_generate_events();
} // namespace she
#endif

View File

@ -13,9 +13,9 @@
#include "config.h"
#endif
#include "she/alleg4/alleg4_font.h"
#include "she/alleg4/font.h"
#include "she/alleg4/alleg4_surface.h"
#include "she/alleg4/surface.h"
#include "she/display.h"
#include "she/system.h"

View File

@ -10,8 +10,11 @@
namespace she {
class Display;
class Event;
extern Display* unique_display;
void queue_event(const Event& ev);
} // namespace she

View File

@ -0,0 +1,93 @@
// SHE library
// Copyright (C) 2012-2014 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/alleg4/internals.h"
#include "she/she.h"
#include <allegro.h>
namespace {
static char old_readed_key[KEY_MAX]; // keyboard status of previous poll
static unsigned key_repeated[KEY_MAX];
}
namespace she {
void key_poller_init()
{
// Reset keyboard
for (int c=0; c<KEY_MAX; c++) {
old_readed_key[c] = 0;
key_repeated[c] = 0;
}
}
void key_poller_generate_events()
{
Event ev;
// Poll keyboard
poll_keyboard();
// Generate kKeyDownMessage messages.
int c;
while (keypressed()) {
int scancode;
int unicode_char = ureadkey(&scancode);
int repeat = 0;
{
c = scancode;
if (c >= 0 && c < KEY_MAX) {
old_readed_key[c] = key[c];
repeat = key_repeated[c]++;
}
}
ev.setType(Event::KeyDown);
ev.setScancode(static_cast<KeyScancode>(scancode));
ev.setUnicodeChar(unicode_char);
ev.setRepeat(repeat);
queue_event(ev);
}
for (int c=0; c<KEY_MAX; c++) {
if (old_readed_key[c] != key[c]) {
KeyScancode scancode = static_cast<KeyScancode>(c);
// Generate kKeyUpMessage messages (old key state is activated,
// the new one is deactivated).
if (old_readed_key[c]) {
ev.setType(Event::KeyUp);
ev.setScancode(scancode);
ev.setUnicodeChar(::scancode_to_ascii(scancode));
ev.setRepeat(0);
queue_event(ev);
old_readed_key[c] = key[c];
key_repeated[c] = 0;
}
// Generate kKeyDownMessage messages for modifiers
else if (c >= kKeyFirstModifierScancode) {
ev.setType(Event::KeyDown);
ev.setScancode(scancode);
ev.setUnicodeChar(::scancode_to_ascii(scancode));
ev.setRepeat(key_repeated[c]++);
queue_event(ev);
old_readed_key[c] = key[c];
}
}
}
}
} // namespace she

View File

@ -0,0 +1,18 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_ALLEG4_KEY_POLLER_H_INCLUDED
#define SHE_ALLEG4_KEY_POLLER_H_INCLUDED
#pragma once
namespace she {
void key_poller_init();
void key_poller_generate_events();
} // namespace she
#endif

View File

@ -0,0 +1,222 @@
// SHE library
// Copyright (C) 2012-2014 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/alleg4/internals.h"
#include "she/clock.h"
#include "she/display.h"
#include "she/event.h"
#include <allegro.h>
#ifdef WIN32
#include <winalleg.h>
#endif
namespace {
using namespace she;
#define DOUBLE_CLICK_TIMEOUT_MSECS 400
enum DlbClk {
DOUBLE_CLICK_NONE,
DOUBLE_CLICK_DOWN,
DOUBLE_CLICK_UP
};
bool moved;
int she_mouse_x;
int she_mouse_y;
int she_mouse_z;
int she_mouse_b;
DlbClk double_click_level;
Event::MouseButton double_click_button = Event::NoneButton;
int double_click_ticks;
inline int display_w() { return (unique_display->width() / unique_display->scale()); }
inline int display_h() { return (unique_display->height() / unique_display->scale()); }
gfx::Point allegro_mouse_point()
{
return gfx::Point(
(int)display_w() * mouse_x / SCREEN_W,
(int)display_h() * mouse_y / SCREEN_H);
}
void update_mouse_position(const gfx::Point& pt)
{
she_mouse_x = pt.x;
she_mouse_y = pt.y;
#ifdef WIN32
if (is_windowed_mode()) {
// This help us (on Windows) to get mouse feedback when we capture
// the mouse but we are outside the window.
POINT pt;
RECT rc;
if (GetCursorPos(&pt) && GetClientRect(win_get_window(), &rc)) {
MapWindowPoints(win_get_window(), NULL, (LPPOINT)&rc, 2);
if (!PtInRect(&rc, pt)) {
// If the mouse is free we can hide the cursor putting the
// mouse outside the screen (right-bottom corder).
if (GetCapture() != win_get_window()) {
she_mouse_x = display_w() + 32 * unique_display->scale();
she_mouse_y = display_h() + 32 * unique_display->scale();
}
// If the mouse is captured we can put it in the edges of the
// screen.
else {
pt.x -= rc.left;
pt.y -= rc.top;
she_mouse_x = display_w() * pt.x / SCREEN_W;
she_mouse_y = display_h() * pt.y / SCREEN_H;
she_mouse_x = MID(0, she_mouse_x, display_w()-1);
she_mouse_y = MID(0, she_mouse_y, display_h()-1);
}
}
}
}
#endif
}
bool poll_mouse_position()
{
poll_mouse();
int old_x = she_mouse_x;
int old_y = she_mouse_y;
she_mouse_x = mouse_x;
she_mouse_y = mouse_y;
she_mouse_b = mouse_b;
she_mouse_z = mouse_z;
update_mouse_position(allegro_mouse_point());
if ((she_mouse_x != old_x) || (she_mouse_y != old_y)) {
poll_mouse();
update_mouse_position(allegro_mouse_point());
// Reset double click status
double_click_level = DOUBLE_CLICK_NONE;
moved = true;
}
if (moved) {
moved = false;
return true;
}
else
return false;
}
void generate_mouse_event_for_button(Event::MouseButton button, int old_b, int new_b)
{
if (old_b == new_b) // No changes in this mouse button
return;
Event ev;
ev.setType(new_b ? Event::MouseDown: Event::MouseUp);
// Double Click
int current_ticks = clock_value();
if (ev.type() == Event::MouseDown) {
if (double_click_level != DOUBLE_CLICK_NONE) {
// Time out, back to NONE
if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) {
double_click_level = DOUBLE_CLICK_NONE;
}
else if (double_click_button == button) {
if (double_click_level == DOUBLE_CLICK_UP) {
ev.setType(Event::MouseDoubleClick);
}
else {
double_click_level = DOUBLE_CLICK_NONE;
}
}
// Press other button, back to NONE
else {
double_click_level = DOUBLE_CLICK_NONE;
}
}
// This could be the beginning of the state
if (double_click_level == DOUBLE_CLICK_NONE) {
double_click_level = DOUBLE_CLICK_DOWN;
double_click_button = button;
double_click_ticks = current_ticks;
}
}
else if (ev.type() == Event::MouseUp) {
if (double_click_level != DOUBLE_CLICK_NONE) {
// Time out, back to NONE
if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) {
double_click_level = DOUBLE_CLICK_NONE;
}
else if (double_click_level == DOUBLE_CLICK_DOWN) {
double_click_level = DOUBLE_CLICK_UP;
double_click_ticks = current_ticks;
}
}
}
queue_event(ev);
}
}
namespace she {
void mouse_poller_init()
{
double_click_level = DOUBLE_CLICK_NONE;
double_click_ticks = 0;
moved = true;
}
void mouse_poller_generate_events()
{
int old_b = she_mouse_b;
int old_z = she_mouse_z;
bool mousemove = poll_mouse_position();
Event ev;
gfx::Point mousePos(gfx::Point(she_mouse_x, she_mouse_y));
ev.setPosition(mousePos);
// Mouse movement
if (mousemove) {
ev.setType(Event::MouseMove);
queue_event(ev);
}
// Mouse wheel
if (old_z != she_mouse_z) {
ev.setType(Event::MouseWheel);
ev.setPosition(mousePos);
ev.setWheelDelta(gfx::Point(0, old_z - she_mouse_z));
queue_event(ev);
}
// Mouse clicks
if (she_mouse_b != old_b) {
generate_mouse_event_for_button(Event::LeftButton, old_b & 1, she_mouse_b & 1);
generate_mouse_event_for_button(Event::RightButton, old_b & 2, she_mouse_b & 2);
generate_mouse_event_for_button(Event::MiddleButton, old_b & 4, she_mouse_b & 4);
}
}
} // namespace she

View File

@ -0,0 +1,18 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_ALLEG4_MOUSE_POLLER_H_INCLUDED
#define SHE_ALLEG4_MOUSE_POLLER_H_INCLUDED
#pragma once
namespace she {
void mouse_poller_init();
void mouse_poller_generate_events();
} // namespace she
#endif

View File

@ -12,13 +12,18 @@
#include "base/concurrent_queue.h"
#include "base/string.h"
#include "she/alleg4/alleg4_font.h"
#include "she/alleg4/alleg4_surface.h"
#include "she/alleg4/font.h"
#include "she/alleg4/surface.h"
#include "she/logger.h"
#include <allegro.h>
#include <allegro/internal/aintern.h>
#define USE_KEY_POLLER
// #ifndef WIN32 // On Windows we generated events from the HWND procedure
#define USE_MOUSE_POLLER
// #endif
#ifdef WIN32
#include <winalleg.h>
@ -53,8 +58,19 @@
#include "loadpng.h"
#include <cassert>
#include <vector>
#include <list>
#include <vector>
#include "she/alleg4/clock.h"
#include "she/alleg4/close_button.h"
#ifdef USE_KEY_POLLER
#include "she/alleg4/key_poller.h"
#endif
#ifdef USE_MOUSE_POLLER
#include "she/alleg4/mouse_poller.h"
#endif
#define DISPLAY_FLAG_FULL_REFRESH 1
#define DISPLAY_FLAG_WINDOW_RESIZE 2
@ -92,13 +108,34 @@ namespace she {
class Alleg4EventQueue : public EventQueue {
public:
Alleg4EventQueue() {
clock_init();
close_button_init();
#ifdef USE_KEY_POLLER
key_poller_init();
#endif
#ifdef USE_MOUSE_POLLER
mouse_poller_init();
#endif
}
void dispose() {
clock_exit();
delete this;
}
void getEvent(Event& event) {
close_button_generate_events();
#ifdef USE_KEY_POLLER
key_poller_generate_events();
#endif
#ifdef USE_MOUSE_POLLER
mouse_poller_generate_events();
#endif
if (!m_events.try_pop(event))
event.setType(Event::None);
}
@ -163,6 +200,8 @@ static LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
break;
}
#ifndef USE_MOUSE_POLLER
case WM_MOUSEMOVE: {
// Adjust capture
if (capture_mouse) {
@ -339,6 +378,8 @@ static LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
break;
}
#endif
case WM_NCCALCSIZE: {
if (wparam) {
// Scrollbars must be enabled and visible to get trackpad
@ -435,6 +476,7 @@ public:
width, height, 0, 0) < 0)
throw DisplayCreationException(allegro_error);
show_mouse(NULL);
setScale(scale);
m_queue = new Alleg4EventQueue();
@ -686,12 +728,7 @@ public:
}
Capabilities capabilities() const override {
return (Capabilities)
(kCanResizeDisplayCapability
#ifdef WIN32
| kMouseEventsCapability
#endif
);
return (Capabilities)(kCanResizeDisplayCapability);
}
Logger* logger() override {

View File

@ -14,7 +14,6 @@ namespace she {
kMultipleDisplaysCapability = 1,
kCanResizeDisplayCapability = 2,
kDisplayScaleCapability = 4,
kMouseEventsCapability = 8,
};
} // namespace she

17
src/she/clock.h Normal file
View File

@ -0,0 +1,17 @@
// SHE library
// Copyright (C) 2012-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_CLOCK_H_INCLUDED
#define SHE_CLOCK_H_INCLUDED
#pragma once
namespace she {
int clock_value();
} // namespace she
#endif

View File

@ -9,16 +9,20 @@
#pragma once
#include "gfx/point.h"
#include "she/keys.h"
#include <string>
#include <vector>
namespace she {
class Display;
class Event {
public:
enum Type {
None,
CloseDisplay,
DropFiles,
MouseEnter,
MouseLeave,
@ -27,6 +31,8 @@ namespace she {
MouseUp,
MouseWheel,
MouseDoubleClick,
KeyDown,
KeyUp,
};
enum MouseButton {
@ -41,20 +47,33 @@ namespace she {
Event() : m_type(None) { }
Type type() const { return m_type; }
Display* display() const { return m_display; }
const Files& files() const { return m_files; }
KeyScancode scancode() const { return m_scancode; }
int unicodeChar() const { return m_unicodeChar; }
int repeat() const { return m_repeat; }
gfx::Point position() const { return m_position; }
gfx::Point wheelDelta() const { return m_wheelDelta; }
MouseButton button() const { return m_button; }
void setType(Type type) { m_type = type; }
void setDisplay(Display* display) { m_display = display; }
void setFiles(const Files& files) { m_files = files; }
void setScancode(KeyScancode scancode) { m_scancode = scancode; }
void setUnicodeChar(int unicodeChar) { m_unicodeChar = unicodeChar; }
void setRepeat(int repeat) { m_repeat = repeat; }
void setPosition(const gfx::Point& pos) { m_position = pos; }
void setWheelDelta(const gfx::Point& delta) { m_wheelDelta = delta; }
void setButton(MouseButton button) { m_button = button; }
private:
Type m_type;
Display* m_display;
Files m_files;
KeyScancode m_scancode;
int m_unicodeChar;
int m_repeat; // repeat=0 means the first time the key is pressed
gfx::Point m_position;
gfx::Point m_wheelDelta;
MouseButton m_button;

159
src/she/keys.h Normal file
View File

@ -0,0 +1,159 @@
// SHE library
// Copyright (C) 2012-2013 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_KEYS_H_INCLUDED
#define SHE_KEYS_H_INCLUDED
#pragma once
namespace she {
enum KeyModifiers {
kKeyNoneModifier = 0,
kKeyShiftModifier = 1,
kKeyCtrlModifier = 2,
kKeyAltModifier = 4,
kKeyCmdModifier = 8,
kKeySpaceModifier = 16
};
enum KeyScancode {
kKeyNil = 0,
kKeyA = 1,
kKeyB = 2,
kKeyC = 3,
kKeyD = 4,
kKeyE = 5,
kKeyF = 6,
kKeyG = 7,
kKeyH = 8,
kKeyI = 9,
kKeyJ = 10,
kKeyK = 11,
kKeyL = 12,
kKeyM = 13,
kKeyN = 14,
kKeyO = 15,
kKeyP = 16,
kKeyQ = 17,
kKeyR = 18,
kKeyS = 19,
kKeyT = 20,
kKeyU = 21,
kKeyV = 22,
kKeyW = 23,
kKeyX = 24,
kKeyY = 25,
kKeyZ = 26,
kKey0 = 27,
kKey1 = 28,
kKey2 = 29,
kKey3 = 30,
kKey4 = 31,
kKey5 = 32,
kKey6 = 33,
kKey7 = 34,
kKey8 = 35,
kKey9 = 36,
kKey0Pad = 37,
kKey1Pad = 38,
kKey2Pad = 39,
kKey3Pad = 40,
kKey4Pad = 41,
kKey5Pad = 42,
kKey6Pad = 43,
kKey7Pad = 44,
kKey8Pad = 45,
kKey9Pad = 46,
kKeyF1 = 47,
kKeyF2 = 48,
kKeyF3 = 49,
kKeyF4 = 50,
kKeyF5 = 51,
kKeyF6 = 52,
kKeyF7 = 53,
kKeyF8 = 54,
kKeyF9 = 55,
kKeyF10 = 56,
kKeyF11 = 57,
kKeyF12 = 58,
kKeyEsc = 59,
kKeyTilde = 60,
kKeyMinus = 61,
kKeyEquals = 62,
kKeyBackspace = 63,
kKeyTab = 64,
kKeyOpenbrace = 65,
kKeyClosebrace = 66,
kKeyEnter = 67,
kKeyColon = 68,
kKeyQuote = 69,
kKeyBackslash = 70,
kKeyBackslash2 = 71,
kKeyComma = 72,
kKeyStop = 73,
kKeySlash = 74,
kKeySpace = 75,
kKeyInsert = 76,
kKeyDel = 77,
kKeyHome = 78,
kKeyEnd = 79,
kKeyPageUp = 80,
kKeyPageDown = 81,
kKeyLeft = 82,
kKeyRight = 83,
kKeyUp = 84,
kKeyDown = 85,
kKeySlashPad = 86,
kKeyAsterisk = 87,
kKeyMinusPad = 88,
kKeyPlusPad = 89,
kKeyDelPad = 90,
kKeyEnterPad = 91,
kKeyPrtscr = 92,
kKeyPause = 93,
kKeyAbntC1 = 94,
kKeyYen = 95,
kKeyKana = 96,
kKeyConvert = 97,
kKeyNoconvert = 98,
kKeyAt = 99,
kKeyCircumflex = 100,
kKeyColon2 = 101,
kKeyKanji = 102,
kKeyEqualsPad = 103, // MacOS X
kKeyBackquote = 104, // MacOS X
kKeySemicolon = 105, // MacOS X
kKeyCommand = 106, // MacOS X
kKeyUnknown1 = 107,
kKeyUnknown2 = 108,
kKeyUnknown3 = 109,
kKeyUnknown4 = 110,
kKeyUnknown5 = 111,
kKeyUnknown6 = 112,
kKeyUnknown7 = 113,
kKeyUnknown8 = 114,
kKeyFirstModifierScancode = 115,
kKeyLShift = 115,
kKeyRShift = 116,
kKeyLControl = 117,
kKeyRControl = 118,
kKeyAlt = 119,
kKeyAltGr = 120,
kKeyLWin = 121,
kKeyRWin = 122,
kKeyMenu = 123,
kKeyScrLock = 124,
kKeyNumLock = 125,
kKeyCapsLock = 126,
kKeyScancodes = 127
};
} // namespace she
#endif

View File

@ -19,7 +19,6 @@ add_library(ui-lib
image_view.cpp
int_entry.cpp
intern.cpp
keys.cpp
label.cpp
link_label.cpp
listbox.cpp

View File

@ -32,12 +32,18 @@
#include "config.h"
#endif
#include <allegro/unicode.h>
#include <stdarg.h>
#include <stdio.h>
#include "ui/alert.h"
#include "base/bind.h"
#include "ui/ui.h"
#include "ui/box.h"
#include "ui/button.h"
#include "ui/grid.h"
#include "ui/label.h"
#include "ui/separator.h"
#include "ui/theme.h"
#include <cstdarg>
#include <cstdio>
namespace ui {
@ -147,7 +153,7 @@ void Alert::processString(char* buf, std::vector<Widget*>& labels, std::vector<W
button_widget->setMinSize(gfx::Size(60*jguiscale(), 0));
buttons.push_back(button_widget);
usprintf(buttonId, "button-%lu", buttons.size());
sprintf(buttonId, "button-%lu", buttons.size());
button_widget->setId(buttonId);
button_widget->Click.connect(Bind<void>(&Window::closeWindow, this, button_widget));
}

View File

@ -16,11 +16,8 @@
#include "ui/widget.h"
#include "ui/window.h"
#include <allegro/gfx.h>
#include <allegro/keyboard.h>
#include <allegro/timer.h>
#include <queue>
#include <string.h>
#include <cstring>
namespace ui {

View File

@ -1,18 +0,0 @@
// 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/keys.h"
#include <allegro.h>
int ui::scancode_to_unicode(KeyScancode scancode)
{
return ::scancode_to_ascii(scancode);
}

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013 David Capello
// Copyright (C) 2001-2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,153 +8,152 @@
#define UI_KEYS_H_INCLUDED
#pragma once
#include "she/keys.h"
namespace ui {
enum KeyModifiers {
kKeyNoneModifier = 0,
kKeyShiftModifier = 1,
kKeyCtrlModifier = 2,
kKeyAltModifier = 4,
kKeyCmdModifier = 8,
kKeySpaceModifier = 16
};
typedef she::KeyModifiers KeyModifiers;
typedef she::KeyScancode KeyScancode;
enum KeyScancode {
kKeyNil = 0,
kKeyA = 1,
kKeyB = 2,
kKeyC = 3,
kKeyD = 4,
kKeyE = 5,
kKeyF = 6,
kKeyG = 7,
kKeyH = 8,
kKeyI = 9,
kKeyJ = 10,
kKeyK = 11,
kKeyL = 12,
kKeyM = 13,
kKeyN = 14,
kKeyO = 15,
kKeyP = 16,
kKeyQ = 17,
kKeyR = 18,
kKeyS = 19,
kKeyT = 20,
kKeyU = 21,
kKeyV = 22,
kKeyW = 23,
kKeyX = 24,
kKeyY = 25,
kKeyZ = 26,
kKey0 = 27,
kKey1 = 28,
kKey2 = 29,
kKey3 = 30,
kKey4 = 31,
kKey5 = 32,
kKey6 = 33,
kKey7 = 34,
kKey8 = 35,
kKey9 = 36,
kKey0Pad = 37,
kKey1Pad = 38,
kKey2Pad = 39,
kKey3Pad = 40,
kKey4Pad = 41,
kKey5Pad = 42,
kKey6Pad = 43,
kKey7Pad = 44,
kKey8Pad = 45,
kKey9Pad = 46,
kKeyF1 = 47,
kKeyF2 = 48,
kKeyF3 = 49,
kKeyF4 = 50,
kKeyF5 = 51,
kKeyF6 = 52,
kKeyF7 = 53,
kKeyF8 = 54,
kKeyF9 = 55,
kKeyF10 = 56,
kKeyF11 = 57,
kKeyF12 = 58,
kKeyEsc = 59,
kKeyTilde = 60,
kKeyMinus = 61,
kKeyEquals = 62,
kKeyBackspace = 63,
kKeyTab = 64,
kKeyOpenbrace = 65,
kKeyClosebrace = 66,
kKeyEnter = 67,
kKeyColon = 68,
kKeyQuote = 69,
kKeyBackslash = 70,
kKeyBackslash2 = 71,
kKeyComma = 72,
kKeyStop = 73,
kKeySlash = 74,
kKeySpace = 75,
kKeyInsert = 76,
kKeyDel = 77,
kKeyHome = 78,
kKeyEnd = 79,
kKeyPageUp = 80,
kKeyPageDown = 81,
kKeyLeft = 82,
kKeyRight = 83,
kKeyUp = 84,
kKeyDown = 85,
kKeySlashPad = 86,
kKeyAsterisk = 87,
kKeyMinusPad = 88,
kKeyPlusPad = 89,
kKeyDelPad = 90,
kKeyEnterPad = 91,
kKeyPrtscr = 92,
kKeyPause = 93,
kKeyAbntC1 = 94,
kKeyYen = 95,
kKeyKana = 96,
kKeyConvert = 97,
kKeyNoconvert = 98,
kKeyAt = 99,
kKeyCircumflex = 100,
kKeyColon2 = 101,
kKeyKanji = 102,
kKeyEqualsPad = 103, // MacOS X
kKeyBackquote = 104, // MacOS X
kKeySemicolon = 105, // MacOS X
kKeyCommand = 106, // MacOS X
kKeyUnknown1 = 107,
kKeyUnknown2 = 108,
kKeyUnknown3 = 109,
kKeyUnknown4 = 110,
kKeyUnknown5 = 111,
kKeyUnknown6 = 112,
kKeyUnknown7 = 113,
kKeyUnknown8 = 114,
using she::kKeyNoneModifier;
using she::kKeyShiftModifier;
using she::kKeyCtrlModifier;
using she::kKeyAltModifier;
using she::kKeyCmdModifier;
using she::kKeySpaceModifier;
kKeyFirstModifierScancode = 115,
using she::kKeyNil;
using she::kKeyA;
using she::kKeyB;
using she::kKeyC;
using she::kKeyD;
using she::kKeyE;
using she::kKeyF;
using she::kKeyG;
using she::kKeyH;
using she::kKeyI;
using she::kKeyJ;
using she::kKeyK;
using she::kKeyL;
using she::kKeyM;
using she::kKeyN;
using she::kKeyO;
using she::kKeyP;
using she::kKeyQ;
using she::kKeyR;
using she::kKeyS;
using she::kKeyT;
using she::kKeyU;
using she::kKeyV;
using she::kKeyW;
using she::kKeyX;
using she::kKeyY;
using she::kKeyZ;
using she::kKey0;
using she::kKey1;
using she::kKey2;
using she::kKey3;
using she::kKey4;
using she::kKey5;
using she::kKey6;
using she::kKey7;
using she::kKey8;
using she::kKey9;
using she::kKey0Pad;
using she::kKey1Pad;
using she::kKey2Pad;
using she::kKey3Pad;
using she::kKey4Pad;
using she::kKey5Pad;
using she::kKey6Pad;
using she::kKey7Pad;
using she::kKey8Pad;
using she::kKey9Pad;
using she::kKeyF1;
using she::kKeyF2;
using she::kKeyF3;
using she::kKeyF4;
using she::kKeyF5;
using she::kKeyF6;
using she::kKeyF7;
using she::kKeyF8;
using she::kKeyF9;
using she::kKeyF10;
using she::kKeyF11;
using she::kKeyF12;
using she::kKeyEsc;
using she::kKeyTilde;
using she::kKeyMinus;
using she::kKeyEquals;
using she::kKeyBackspace;
using she::kKeyTab;
using she::kKeyOpenbrace;
using she::kKeyClosebrace;
using she::kKeyEnter;
using she::kKeyColon;
using she::kKeyQuote;
using she::kKeyBackslash;
using she::kKeyBackslash2;
using she::kKeyComma;
using she::kKeyStop;
using she::kKeySlash;
using she::kKeySpace;
using she::kKeyInsert;
using she::kKeyDel;
using she::kKeyHome;
using she::kKeyEnd;
using she::kKeyPageUp;
using she::kKeyPageDown;
using she::kKeyLeft;
using she::kKeyRight;
using she::kKeyUp;
using she::kKeyDown;
using she::kKeySlashPad;
using she::kKeyAsterisk;
using she::kKeyMinusPad;
using she::kKeyPlusPad;
using she::kKeyDelPad;
using she::kKeyEnterPad;
using she::kKeyPrtscr;
using she::kKeyPause;
using she::kKeyAbntC1;
using she::kKeyYen;
using she::kKeyKana;
using she::kKeyConvert;
using she::kKeyNoconvert;
using she::kKeyAt;
using she::kKeyCircumflex;
using she::kKeyColon2;
using she::kKeyKanji;
using she::kKeyEqualsPad;
using she::kKeyBackquote;
using she::kKeySemicolon;
using she::kKeyCommand;
using she::kKeyUnknown1;
using she::kKeyUnknown2;
using she::kKeyUnknown3;
using she::kKeyUnknown4;
using she::kKeyUnknown5;
using she::kKeyUnknown6;
using she::kKeyUnknown7;
using she::kKeyUnknown8;
kKeyLShift = 115,
kKeyRShift = 116,
kKeyLControl = 117,
kKeyRControl = 118,
kKeyAlt = 119,
kKeyAltGr = 120,
kKeyLWin = 121,
kKeyRWin = 122,
kKeyMenu = 123,
kKeyScrLock = 124,
kKeyNumLock = 125,
kKeyCapsLock = 126,
using she::kKeyFirstModifierScancode;
kKeyScancodes = 127
};
using she::kKeyLShift;
using she::kKeyRShift;
using she::kKeyLControl;
using she::kKeyRControl;
using she::kKeyAlt;
using she::kKeyAltGr;
using she::kKeyLWin;
using she::kKeyRWin;
using she::kKeyMenu;
using she::kKeyScrLock;
using she::kKeyNumLock;
using she::kKeyCapsLock;
int scancode_to_unicode(KeyScancode scancode);
using she::kKeyScancodes;
} // namespace ui

View File

@ -31,7 +31,7 @@
#ifdef REPORT_EVENTS
#include <iostream>
#endif
#include <allegro.h>
#include <list>
#include <vector>
@ -44,21 +44,6 @@ namespace ui {
JI_DECORATIVE)) == JI_FOCUSSTOP) && \
((widget)->isVisible()))
#define DOUBLE_CLICK_TIMEOUT_MSECS 400
enum {
DOUBLE_CLICK_NONE,
DOUBLE_CLICK_DOWN,
DOUBLE_CLICK_UP
};
enum {
STAGE_NORMAL,
STAGE_WANT_CLOSE,
STAGE_WAITING_REPLY,
STAGE_CLOSE_ALL,
};
static const int NFILTERS = (int)(kFirstRegisteredMessage+1);
struct Filter
@ -74,16 +59,6 @@ struct Filter
typedef std::list<Message*> Messages;
typedef std::list<Filter*> Filters;
static bool mouse_events_from_she;
static int double_click_level;
static MouseButtons double_click_buttons;
static int double_click_ticks;
static int want_close_stage; /* variable to handle the external
close button in some Windows
enviroments */
Manager* Manager::m_defaultManager = NULL;
static WidgetsList new_windows; // Windows that we should show
@ -95,12 +70,7 @@ static Widget* focus_widget; // The widget with the focus
static Widget* mouse_widget; // The widget with the mouse
static Widget* capture_widget; // The widget that captures the mouse
static bool first_time_poll; /* true when we don't enter in poll yet */
static char old_readed_key[KEY_MAX]; /* keyboard status of previous
poll */
static unsigned key_repeated[KEY_MAX];
static bool first_time = true; // true when we don't enter in poll yet
/* keyboard focus movement stuff */
static bool move_focus(Manager* manager, Message* msg);
@ -112,13 +82,6 @@ static int cmp_right(Widget* widget, int x, int y);
static int cmp_up(Widget* widget, int x, int y);
static int cmp_down(Widget* widget, int x, int y);
/* hooks the close-button in some platform with window support */
static void allegro_window_close_hook()
{
if (want_close_stage == STAGE_NORMAL)
want_close_stage = STAGE_WANT_CLOSE;
}
Manager::Manager()
: Widget(kManagerWidget)
, m_display(NULL)
@ -128,10 +91,6 @@ Manager::Manager()
, m_mouseButtons(kButtonNone)
{
if (!m_defaultManager) {
// Hook the window close message
want_close_stage = STAGE_NORMAL;
set_close_button_callback(allegro_window_close_hook);
// Empty lists
ASSERT(msg_queue.empty());
ASSERT(new_windows.empty());
@ -141,29 +100,14 @@ Manager::Manager()
focus_widget = NULL;
mouse_widget = NULL;
capture_widget = NULL;
first_time_poll = true;
double_click_level = DOUBLE_CLICK_NONE;
double_click_ticks = 0;
// Reset keyboard
for (int c=0; c<KEY_MAX; c++) {
old_readed_key[c] = 0;
key_repeated[c] = 0;
}
}
setBounds(gfx::Rect(0, 0, ui::display_w(), ui::display_h()));
setVisible(true);
// Default manager is the first one (and is always visible).
if (!m_defaultManager) {
if (!m_defaultManager)
m_defaultManager = this;
mouse_events_from_she =
((she::instance()->capabilities() & she::kMouseEventsCapability)
== she::kMouseEventsCapability);
}
}
Manager::~Manager()
@ -213,22 +157,19 @@ void Manager::run()
{
MessageLoop loop(this);
if (first_time) {
first_time = false;
Manager::getDefault()->invalidate();
jmouse_set_cursor(kArrowCursor);
}
while (!getChildren().empty())
loop.pumpMessages();
}
bool Manager::generateMessages()
{
// Poll keyboard
poll_keyboard();
if (first_time_poll) {
first_time_poll = false;
Manager::getDefault()->invalidate();
jmouse_set_cursor(kArrowCursor);
}
// First check: there are windows to manage?
if (getChildren().empty())
return false;
@ -259,19 +200,6 @@ bool Manager::generateMessages()
new_windows.clear();
}
if (!mouse_events_from_she)
generateMouseMessages();
// Generate Close message when the user press close button on the system window.
if (want_close_stage == STAGE_WANT_CLOSE) {
want_close_stage = STAGE_NORMAL;
Message* msg = new Message(kCloseAppMessage);
msg->broadcastToChildren(this);
enqueueMessage(msg);
}
generateKeyMessages();
generateMessagesFromSheEvents();
// Generate messages for timers
@ -286,92 +214,6 @@ bool Manager::generateMessages()
return false;
}
void Manager::generateMouseMessages()
{
// Update mouse status
bool mousemove = _internal_poll_mouse();
gfx::Point mousePos(gfx::Point(jmouse_x(0), jmouse_y(0)));
if (mousemove || !mouse_widget)
handleMouseMove(mousePos, currentMouseButtons(0));
// Mouse wheel
if (jmouse_z(0) != jmouse_z(1))
handleMouseWheel(mousePos, currentMouseButtons(0),
gfx::Point(0, jmouse_z(1) - jmouse_z(0)));
// Mouse clicks
if (jmouse_b(0) != jmouse_b(1)) {
int current_ticks = ui::clock();
bool pressed =
((jmouse_b(1) & 1) == 0 && (jmouse_b(0) & 1) == 1) ||
((jmouse_b(1) & 2) == 0 && (jmouse_b(0) & 2) == 2) ||
((jmouse_b(1) & 4) == 0 && (jmouse_b(0) & 4) == 4);
MessageType msgType = (pressed ? kMouseDownMessage: kMouseUpMessage);
MouseButtons mouseButtons = (pressed ? currentMouseButtons(0): currentMouseButtons(1));
// The message will include which button was pressed or released.
// (This doesn't represent all buttons that are currently pushed.)
MouseButtons mouseButtonsDelta = (MouseButtons)
(currentMouseButtons(0) ^ currentMouseButtons(1));
//////////////////////////////////////////////////////////////////////
// Double Click
if (msgType == kMouseDownMessage) {
if (double_click_level != DOUBLE_CLICK_NONE) {
// Time out, back to NONE
if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) {
double_click_level = DOUBLE_CLICK_NONE;
}
else if (double_click_buttons == mouseButtons) {
if (double_click_level == DOUBLE_CLICK_UP) {
msgType = kDoubleClickMessage;
}
else {
double_click_level = DOUBLE_CLICK_NONE;
}
}
// Press other button, back to NONE
else {
double_click_level = DOUBLE_CLICK_NONE;
}
}
// This could be the beginning of the state
if (double_click_level == DOUBLE_CLICK_NONE) {
double_click_level = DOUBLE_CLICK_DOWN;
double_click_buttons = mouseButtons;
double_click_ticks = current_ticks;
}
}
else if (msgType == kMouseUpMessage) {
if (double_click_level != DOUBLE_CLICK_NONE) {
// Time out, back to NONE
if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) {
double_click_level = DOUBLE_CLICK_NONE;
}
else if (double_click_level == DOUBLE_CLICK_DOWN) {
double_click_level = DOUBLE_CLICK_UP;
double_click_ticks = current_ticks;
}
}
}
switch (msgType) {
case kMouseDownMessage:
handleMouseDown(mousePos, mouseButtonsDelta);
break;
case kMouseUpMessage:
handleMouseUp(mousePos, mouseButtonsDelta);
break;
case kDoubleClickMessage:
handleMouseDoubleClick(mousePos, mouseButtonsDelta);
break;
}
}
}
void Manager::generateSetCursorMessage(const gfx::Point& mousePos)
{
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
@ -382,62 +224,6 @@ void Manager::generateSetCursorMessage(const gfx::Point& mousePos)
jmouse_set_cursor(kArrowCursor);
}
void Manager::generateKeyMessages()
{
// Generate kKeyDownMessage messages.
int c;
while (keypressed()) {
int scancode;
int unicode_char = ureadkey(&scancode);
int repeat = 0;
{
c = scancode;
if (c >= 0 && c < KEY_MAX) {
old_readed_key[c] = key[c];
repeat = key_repeated[c]++;
}
}
Message* msg = new KeyMessage(kKeyDownMessage,
static_cast<KeyScancode>(scancode),
unicode_char, repeat);
broadcastKeyMsg(msg);
enqueueMessage(msg);
}
for (int c=0; c<KEY_MAX; c++) {
if (old_readed_key[c] != key[c]) {
KeyScancode scancode = static_cast<ui::KeyScancode>(c);
// Generate kKeyUpMessage messages (old key state is activated,
// the new one is deactivated).
if (old_readed_key[c]) {
// Press/release key interface
Message* msg = new KeyMessage(kKeyUpMessage,
scancode,
scancode_to_unicode(scancode), 0);
old_readed_key[c] = key[c];
key_repeated[c] = 0;
broadcastKeyMsg(msg);
enqueueMessage(msg);
}
// Generate kKeyDownMessage messages for modifiers
else if (c >= kKeyFirstModifierScancode) {
// Press/release key interface
Message* msg = new KeyMessage(kKeyDownMessage,
scancode,
scancode_to_unicode(scancode),
key_repeated[c]++);
old_readed_key[c] = key[c];
broadcastKeyMsg(msg);
enqueueMessage(msg);
}
}
}
}
static MouseButtons mouse_buttons_from_she_to_ui(const she::Event& sheEvent)
{
switch (sheEvent.button()) {
@ -461,6 +247,13 @@ void Manager::generateMessagesFromSheEvents()
switch (sheEvent.type()) {
case she::Event::CloseDisplay: {
Message* msg = new Message(kCloseAppMessage);
msg->broadcastToChildren(this);
enqueueMessage(msg);
break;
}
case she::Event::DropFiles: {
Message* msg = new DropFilesMessage(sheEvent.files());
msg->addRecipient(this);
@ -468,18 +261,26 @@ void Manager::generateMessagesFromSheEvents()
break;
}
case she::Event::MouseEnter: {
if (!mouse_events_from_she)
continue;
case she::Event::KeyDown:
case she::Event::KeyUp: {
Message* msg = new KeyMessage(
sheEvent.type() == she::Event::KeyDown ?
kKeyDownMessage:
kKeyUpMessage,
sheEvent.scancode(),
sheEvent.unicodeChar(),
sheEvent.repeat());
broadcastKeyMsg(msg);
enqueueMessage(msg);
break;
}
case she::Event::MouseEnter: {
jmouse_set_cursor(kArrowCursor);
break;
}
case she::Event::MouseLeave: {
if (!mouse_events_from_she)
continue;
jmouse_set_cursor(kNoCursor);
setMouse(NULL);
@ -488,9 +289,6 @@ void Manager::generateMessagesFromSheEvents()
}
case she::Event::MouseMove: {
if (!mouse_events_from_she)
continue;
// TODO Currently we cannot handleMouseMove() for each
// she::Event::MouseMove as the UI library is not prepared yet
// to process more than one kMouseMoveMessage message for
@ -501,9 +299,6 @@ void Manager::generateMessagesFromSheEvents()
}
case she::Event::MouseDown: {
if (!mouse_events_from_she)
continue;
MouseButtons pressedButton = mouse_buttons_from_she_to_ui(sheEvent);
m_mouseButtons = (MouseButtons)((int)m_mouseButtons | (int)pressedButton);
_internal_set_mouse_buttons(m_mouseButtons);
@ -513,9 +308,6 @@ void Manager::generateMessagesFromSheEvents()
}
case she::Event::MouseUp: {
if (!mouse_events_from_she)
continue;
MouseButtons releasedButton = mouse_buttons_from_she_to_ui(sheEvent);
m_mouseButtons = (MouseButtons)((int)m_mouseButtons & ~(int)releasedButton);
_internal_set_mouse_buttons(m_mouseButtons);
@ -525,18 +317,12 @@ void Manager::generateMessagesFromSheEvents()
}
case she::Event::MouseDoubleClick: {
if (!mouse_events_from_she)
continue;
MouseButtons clickedButton = mouse_buttons_from_she_to_ui(sheEvent);
handleMouseDoubleClick(sheEvent.position(), clickedButton);
break;
}
case she::Event::MouseWheel: {
if (!mouse_events_from_she)
continue;
handleMouseWheel(sheEvent.position(), m_mouseButtons, sheEvent.wheelDelta());
break;
}
@ -572,9 +358,6 @@ void Manager::handleMouseMove(const gfx::Point& mousePos, MouseButtons mouseButt
setMouse(widget);
}
// Reset double click status
double_click_level = DOUBLE_CLICK_NONE;
// Send the mouse movement message
Widget* dst = (capture_widget ? capture_widget: mouse_widget);
enqueueMessage(newMouseMessage(kMouseMoveMessage, dst, mousePos, mouseButtons));

View File

@ -92,9 +92,7 @@ namespace ui {
virtual LayoutIO* onGetLayoutIO();
private:
void generateMouseMessages();
void generateSetCursorMessage(const gfx::Point& mousePos);
void generateKeyMessages();
void generateMessagesFromSheEvents();
void handleMouseMove(const gfx::Point& mousePos, MouseButtons mouseButtons);
void handleMouseDown(const gfx::Point& mousePos, MouseButtons mouseButtons);

View File

@ -481,7 +481,9 @@ bool MenuBox::onProcessMessage(Message* msg)
if (((this->type == kMenuBoxWidget) && (msg->keyModifiers() == kKeyNoneModifier || // <-- Inside menu-boxes we can use letters without Alt modifier pressed
msg->keyModifiers() == kKeyAltModifier)) ||
((this->type == kMenuBarWidget) && (msg->keyModifiers() == kKeyAltModifier))) {
selected = check_for_letter(menu, scancode_to_unicode(static_cast<KeyMessage*>(msg)->scancode()));
selected = check_for_letter(menu,
static_cast<KeyMessage*>(msg)->unicodeChar());
if (selected) {
menu->highlightItem(selected, true, true, true);
return true;

View File

@ -22,7 +22,8 @@ namespace ui {
Message::Message(MessageType type)
: m_type(type)
, m_used(false)
, m_modifiers((KeyModifiers)((key[KEY_LSHIFT] || key[KEY_RSHIFT] ? kKeyShiftModifier: 0) |
, m_modifiers((KeyModifiers)
((key[KEY_LSHIFT] || key[KEY_RSHIFT] ? kKeyShiftModifier: 0) |
(key[KEY_LCONTROL] || key[KEY_RCONTROL] ? kKeyCtrlModifier: 0) |
(key[KEY_ALT] ? kKeyAltModifier: 0) |
(key[KEY_COMMAND] ? kKeyCmdModifier: 0) |

View File

@ -24,8 +24,7 @@ namespace ui {
class Timer;
class Widget;
class Message
{
class Message {
public:
typedef WidgetsList::iterator& recipients_iterator;

View File

@ -11,6 +11,7 @@
#include "ui/system.h"
#include "gfx/point.h"
#include "she/clock.h"
#include "she/display.h"
#include "she/surface.h"
#include "ui/cursor.h"
@ -21,19 +22,10 @@
#include "ui/theme.h"
#include "ui/widget.h"
#include <allegro.h>
#if defined(WIN32)
#include <winalleg.h>
#endif
namespace ui {
bool dirty_display_flag = true;
// Global timer.
static volatile int clock_var = 0;
// Current mouse cursor type.
static CursorType mouse_cursor_type = kNoCursor;
@ -50,21 +42,8 @@ static int m_x[2];
static int m_y[2];
static int m_z[2];
static bool moved;
static int mouse_scares = 0;
/* Local routines. */
static void clock_inc();
static void update_mouse_position(const gfx::Point& pt);
static void clock_inc()
{
++clock_var;
}
END_OF_STATIC_FUNCTION(clock_inc);
static void update_mouse_overlay(Cursor* cursor)
{
mouse_cursor = cursor;
@ -93,8 +72,6 @@ static void update_mouse_overlay(Cursor* cursor)
static void update_mouse_cursor()
{
show_mouse(NULL);
// Use native cursor when it's possible/available/configured to do so.
bool native_cursor_available = false;
@ -166,20 +143,7 @@ static void update_mouse_cursor()
int _ji_system_init()
{
/* Install timer related stuff. */
LOCK_VARIABLE(clock_var);
LOCK_VARIABLE(m_b);
LOCK_FUNCTION(clock_inc);
if (install_int_ex(clock_inc, BPS_TO_TIMER(1000)) < 0)
return -1;
if (screen)
_internal_poll_mouse();
moved = true;
mouse_cursor_type = kNoCursor;
return 0;
}
@ -187,13 +151,11 @@ void _ji_system_exit()
{
set_display(NULL);
update_mouse_overlay(NULL);
remove_int(clock_inc);
}
int clock()
{
return clock_var;
return she::clock_value();
}
void set_display(she::Display* display)
@ -294,55 +256,13 @@ bool jmouse_is_shown()
return mouse_scares == 0;
}
static gfx::Point allegro_mouse_point()
{
return gfx::Point(
(int)ui::display_w() * mouse_x / SCREEN_W,
(int)ui::display_w() * mouse_y / SCREEN_W);
}
/**
* Updates the mouse information (position, wheel and buttons).
*
* @return Returns true if the mouse moved.
*/
bool _internal_poll_mouse()
{
m_b[1] = m_b[0];
m_x[1] = m_x[0];
m_y[1] = m_y[0];
m_z[1] = m_z[0];
poll_mouse();
m_b[0] = mouse_b;
m_z[0] = mouse_z;
update_mouse_position(allegro_mouse_point());
if ((m_x[0] != m_x[1]) || (m_y[0] != m_y[1])) {
poll_mouse();
update_mouse_position(allegro_mouse_point());
moved = true;
}
if (moved) {
moved = false;
return true;
}
else
return false;
}
void _internal_no_mouse_position()
{
moved = true;
update_mouse_overlay(NULL);
}
void _internal_set_mouse_position(const gfx::Point& newPos)
{
moved = true;
if (m_x[0] >= 0) {
m_x[1] = m_x[0];
m_y[1] = m_y[0];
@ -388,46 +308,4 @@ 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]; }
static void update_mouse_position(const gfx::Point& pt)
{
m_x[0] = pt.x;
m_y[0] = pt.y;
if (is_windowed_mode()) { // TODO move this to "she" module
#ifdef WIN32
// This help us (on Windows) to get mouse feedback when we capture
// the mouse but we are outside the window.
POINT pt;
RECT rc;
if (GetCursorPos(&pt) && GetClientRect(win_get_window(), &rc)) {
MapWindowPoints(win_get_window(), NULL, (LPPOINT)&rc, 2);
if (!PtInRect(&rc, pt)) {
// If the mouse is free we can hide the cursor putting the
// mouse outside the screen (right-bottom corder).
if (!Manager::getDefault()->getCapture()) {
if (mouse_cursor) {
m_x[0] = ui::display_w() + mouse_cursor->getFocus().x;
m_y[0] = ui::display_h() + mouse_cursor->getFocus().y;
}
}
// If the mouse is captured we can put it in the edges of the
// screen.
else {
pt.x -= rc.left;
pt.y -= rc.top;
m_x[0] = ui::display_w() * pt.x / SCREEN_W;
m_y[0] = ui::display_h() * pt.y / SCREEN_H;
m_x[0] = MID(0, m_x[0], ui::display_w()-1);
m_y[0] = MID(0, m_y[0], ui::display_h()-1);
}
}
}
#endif
}
}
} // namespace ui

View File

@ -47,8 +47,6 @@ namespace ui {
bool jmouse_is_hidden();
bool jmouse_is_shown();
bool _internal_poll_mouse();
void _internal_no_mouse_position();
void _internal_set_mouse_position(const gfx::Point& newPos);
void _internal_set_mouse_buttons(MouseButtons buttons);

View File

@ -18,8 +18,6 @@
#include "ui/theme.h"
#include "ui/view.h"
#include <allegro/keyboard.h>
namespace ui {
TextBox::TextBox(const std::string& text, int align)