mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-04 01:13:38 +00:00
Merge branch '1.0'
* In this branch the Alt+mnemonic issues are solved in "she" layer when the she::Event is generated (see src/she/alleg4/key_poller.cpp) * Mouse cursor issues on OS X are solved in src/she/alleg4/mouse_poller.cpp Conflicts: src/app/test_context.h src/ui/manager.cpp
This commit is contained in:
commit
d176839bf4
@ -181,12 +181,14 @@ AL_VAR(int, osx_mouse_warped);
|
||||
AL_VAR(int, osx_skip_mouse_move);
|
||||
AL_VAR(int, osx_emulate_mouse_buttons);
|
||||
AL_VAR(NSTrackingRectTag, osx_mouse_tracking_rect);
|
||||
extern AL_METHOD(void, osx_window_close_hook, (void));
|
||||
extern AL_METHOD(void, osx_resize_callback, (RESIZE_DISPLAY_EVENT *ev));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
extern AL_METHOD(void, osx_window_close_hook, (void));
|
||||
extern AL_METHOD(void, osx_resize_callback, (RESIZE_DISPLAY_EVENT *ev));
|
||||
extern AL_METHOD(void, osx_mouse_enter_callback, (void));
|
||||
extern AL_METHOD(void, osx_mouse_leave_callback, (void));
|
||||
|
||||
#endif
|
||||
|
||||
/* Local variables: */
|
||||
|
@ -255,7 +255,12 @@ static void osx_mouse_set_range(int x1, int y1, int x2, int y2)
|
||||
mouse_maxx = x2;
|
||||
mouse_maxy = y2;
|
||||
|
||||
osx_mouse_position(CLAMP(mouse_minx, _mouse_x, mouse_maxx), CLAMP(mouse_miny, _mouse_y, mouse_maxy));
|
||||
// Do not change the position of the mouse inside the
|
||||
// range to avoid changing the position to 0,0 when
|
||||
// the program starts.
|
||||
//osx_mouse_position(
|
||||
// CLAMP(mouse_minx, _mouse_x, mouse_maxx),
|
||||
// CLAMP(mouse_miny, _mouse_y, mouse_maxy));
|
||||
}
|
||||
|
||||
|
||||
@ -418,13 +423,13 @@ static int osx_select_system_cursor(AL_CONST int cursor)
|
||||
requested_cursor = [NSCursor operationNotAllowedCursor];
|
||||
break;
|
||||
case MOUSE_CURSOR_SIZE_N:
|
||||
requested_cursor = [NSCursor resizeUpCursor]; break;
|
||||
requested_cursor = [NSCursor resizeUpCursor];
|
||||
break;
|
||||
case MOUSE_CURSOR_SIZE_S:
|
||||
requested_cursor = [NSCursor resizeDownCursor]; break;
|
||||
requested_cursor = [NSCursor resizeDownCursor];
|
||||
break;
|
||||
case MOUSE_CURSOR_SIZE_NS:
|
||||
requested_cursor = [NSCursor resizeUpDownCursor]; break;
|
||||
requested_cursor = [NSCursor resizeUpDownCursor];
|
||||
break;
|
||||
case MOUSE_CURSOR_SIZE_W:
|
||||
requested_cursor = [NSCursor resizeLeftCursor];
|
||||
|
@ -69,6 +69,8 @@ AllegroWindow *osx_window = NULL;
|
||||
char osx_window_title[ALLEGRO_MESSAGE_SIZE];
|
||||
void (*osx_window_close_hook)(void) = NULL;
|
||||
void (*osx_resize_callback)(RESIZE_DISPLAY_EVENT *ev) = NULL;
|
||||
void (*osx_mouse_enter_callback)() = NULL;
|
||||
void (*osx_mouse_leave_callback)() = NULL;
|
||||
int osx_gfx_mode = OSX_GFX_NONE;
|
||||
int osx_emulate_mouse_buttons = FALSE;
|
||||
int osx_window_first_expose = FALSE;
|
||||
@ -295,6 +297,9 @@ void osx_event_handler()
|
||||
_mouse_on = TRUE;
|
||||
osx_hide_native_mouse();
|
||||
}
|
||||
|
||||
if (osx_mouse_enter_callback)
|
||||
osx_mouse_enter_callback();
|
||||
}
|
||||
}
|
||||
[NSApp sendEvent: event];
|
||||
@ -308,6 +313,9 @@ void osx_event_handler()
|
||||
_mouse_on = FALSE;
|
||||
osx_show_native_mouse();
|
||||
}
|
||||
|
||||
if (osx_mouse_leave_callback)
|
||||
osx_mouse_leave_callback();
|
||||
}
|
||||
}
|
||||
[NSApp sendEvent: event];
|
||||
|
@ -740,13 +740,10 @@ void DocumentApi::moveCel(
|
||||
// Move the cel between different layers.
|
||||
else {
|
||||
if (!dstCel) {
|
||||
dstImage = Image::createCopy(srcImage);
|
||||
|
||||
dstCel = new Cel(*srcCel);
|
||||
dstCel->setFrame(dstFrame);
|
||||
dstImage = crop_image(srcImage,
|
||||
-srcCel->x(),
|
||||
-srcCel->y(),
|
||||
dstSprite->width(), // TODO dstSprite or srcSprite
|
||||
dstSprite->height(), 0);
|
||||
dstCel->setImage(addImageInStock(dstSprite, dstImage));
|
||||
}
|
||||
|
||||
|
72
src/app/document_api_tests.cpp
Normal file
72
src/app/document_api_tests.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2014 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "tests/test.h"
|
||||
|
||||
#include "app/document_api.h"
|
||||
#include "app/test_context.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "raster/cel.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/primitives.h"
|
||||
|
||||
using namespace app;
|
||||
using namespace raster;
|
||||
|
||||
typedef base::UniquePtr<Document> DocumentPtr;
|
||||
|
||||
TEST(DocumentApi, MoveCel) {
|
||||
TestContext ctx;
|
||||
DocumentPtr doc(static_cast<Document*>(ctx.documents().add(32, 16)));
|
||||
Sprite* sprite = doc->sprite();
|
||||
LayerImage* layer1 = dynamic_cast<LayerImage*>(sprite->folder()->getFirstLayer());
|
||||
LayerImage* layer2 = new LayerImage(sprite);
|
||||
|
||||
Cel* cel1 = layer1->getCel(FrameNumber(0));
|
||||
cel1->setPosition(2, -2);
|
||||
cel1->setOpacity(128);
|
||||
|
||||
Image* image1 = cel1->image();
|
||||
EXPECT_EQ(32, image1->width());
|
||||
EXPECT_EQ(16, image1->height());
|
||||
for (int v=0; v<image1->height(); ++v)
|
||||
for (int u=0; u<image1->width(); ++u)
|
||||
image1->putPixel(u, v, u+v*image1->width());
|
||||
|
||||
// Create a copy for later comparison.
|
||||
base::UniquePtr<Image> expectedImage(Image::createCopy(image1));
|
||||
|
||||
doc->getApi().moveCel(
|
||||
layer1, FrameNumber(0),
|
||||
layer2, FrameNumber(1));
|
||||
|
||||
EXPECT_EQ(NULL, layer1->getCel(FrameNumber(0)));
|
||||
|
||||
Cel* cel2 = layer2->getCel(FrameNumber(1));
|
||||
ASSERT_TRUE(cel2 != NULL);
|
||||
|
||||
Image* image2 = cel2->image();
|
||||
EXPECT_EQ(32, image2->width());
|
||||
EXPECT_EQ(16, image2->height());
|
||||
EXPECT_EQ(0, count_diff_between_images(expectedImage, image2));
|
||||
EXPECT_EQ(2, cel2->x());
|
||||
EXPECT_EQ(-2, cel2->y());
|
||||
EXPECT_EQ(128, cel2->opacity());
|
||||
|
||||
doc->close();
|
||||
}
|
@ -78,6 +78,12 @@ typedef base::UniquePtr<app::Document> DocumentPtr;
|
||||
EXPECT_TRUE(expect_frame(f, 5)); \
|
||||
EXPECT_TRUE(expect_frame(g, 6));
|
||||
|
||||
#define EXPECT_CEL(y, x, v, u) \
|
||||
EXPECT_TRUE(expect_cel(y, x, v, u));
|
||||
|
||||
#define EXPECT_EMPTY_CEL(y, x) \
|
||||
EXPECT_TRUE(expect_empty_cel(y, x));
|
||||
|
||||
class DocRangeOps : public ::testing::Test {
|
||||
public:
|
||||
DocRangeOps() {
|
||||
@ -147,19 +153,11 @@ protected:
|
||||
|
||||
bool expect_layer_frame(int expected_layer, int expected_frame, int layer, int frame) {
|
||||
if (frame >= 0) {
|
||||
color_t expected_color = white;
|
||||
if (!expect_cel(expected_layer, expected_frame, layer, frame))
|
||||
return false;
|
||||
|
||||
color_t color = get_pixel(
|
||||
static_cast<LayerImage*>(sprite->indexToLayer(LayerIndex(layer)))
|
||||
->getCel(FrameNumber(frame))->image(),
|
||||
expected_layer, expected_frame);
|
||||
|
||||
EXPECT_EQ(expected_color, color);
|
||||
EXPECT_EQ((expected_frame+1), sprite->getFrameDuration(FrameNumber(frame)));
|
||||
|
||||
return
|
||||
(expected_color == color
|
||||
&& (expected_frame+1) == sprite->getFrameDuration(FrameNumber(frame)));
|
||||
return ((expected_frame+1) == sprite->getFrameDuration(FrameNumber(frame)));
|
||||
}
|
||||
|
||||
if (layer >= 0) {
|
||||
@ -173,6 +171,27 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool expect_cel(int expected_layer, int expected_frame, int layer, int frame) {
|
||||
color_t expected_color = white;
|
||||
|
||||
color_t color = get_pixel(
|
||||
static_cast<LayerImage*>(sprite->indexToLayer(LayerIndex(layer)))
|
||||
->getCel(FrameNumber(frame))->image(),
|
||||
expected_layer, expected_frame);
|
||||
|
||||
EXPECT_EQ(expected_color, color);
|
||||
|
||||
return (expected_color == color);
|
||||
}
|
||||
|
||||
bool expect_empty_cel(int layer, int frame) {
|
||||
Cel* cel = static_cast<LayerImage*>(sprite->indexToLayer(LayerIndex(layer)))
|
||||
->getCel(FrameNumber(frame));
|
||||
|
||||
EXPECT_EQ(NULL, cel);
|
||||
return (cel == NULL);
|
||||
}
|
||||
|
||||
TestContext ctx;
|
||||
DocumentPtr doc;
|
||||
Sprite* sprite;
|
||||
@ -222,6 +241,10 @@ inline DocumentRange frames_range(int frame) {
|
||||
return range(0, frame, 0, frame, DocumentRange::kFrames);
|
||||
}
|
||||
|
||||
inline DocumentRange cels_range(int fromLayer, int fromFrNum, int toLayer, int toFrNum) {
|
||||
return range(fromLayer, fromFrNum, toLayer, toFrNum, DocumentRange::kCels);
|
||||
}
|
||||
|
||||
TEST_F(DocRangeOps, MoveLayersNoOp) {
|
||||
// Move one layer to the same place
|
||||
|
||||
@ -679,7 +702,37 @@ TEST_F(DocRangeOps, MoveFrames) {
|
||||
}
|
||||
|
||||
TEST_F(DocRangeOps, MoveCels) {
|
||||
// TODO
|
||||
DocumentRangePlace ignore = kDocumentRangeBefore;
|
||||
|
||||
move_range(doc,
|
||||
cels_range(0, 0, 0, 0),
|
||||
cels_range(0, 1, 0, 1), ignore);
|
||||
EXPECT_CEL(0, 0, 0, 1);
|
||||
EXPECT_EMPTY_CEL(0, 0);
|
||||
doc->getUndo()->doUndo();
|
||||
EXPECT_CEL(0, 0, 0, 0);
|
||||
|
||||
move_range(doc,
|
||||
cels_range(0, 0, 0, 1),
|
||||
cels_range(0, 2, 0, 3), ignore);
|
||||
EXPECT_CEL(0, 0, 0, 2);
|
||||
EXPECT_CEL(0, 1, 0, 3);
|
||||
EXPECT_EMPTY_CEL(0, 0);
|
||||
EXPECT_EMPTY_CEL(0, 1);
|
||||
doc->getUndo()->doUndo();
|
||||
|
||||
move_range(doc,
|
||||
cels_range(0, 0, 0, 3),
|
||||
cels_range(1, 0, 1, 3), ignore);
|
||||
EXPECT_CEL(0, 0, 1, 0);
|
||||
EXPECT_CEL(0, 1, 1, 1);
|
||||
EXPECT_CEL(0, 2, 1, 2);
|
||||
EXPECT_CEL(0, 3, 1, 3);
|
||||
EXPECT_EMPTY_CEL(0, 0);
|
||||
EXPECT_EMPTY_CEL(0, 1);
|
||||
EXPECT_EMPTY_CEL(0, 2);
|
||||
EXPECT_EMPTY_CEL(0, 3);
|
||||
doc->getUndo()->doUndo();
|
||||
}
|
||||
|
||||
TEST_F(DocRangeOps, CopyLayers) {
|
||||
|
@ -707,20 +707,6 @@ bool GifFormat::onSave(FileOp* fop)
|
||||
throw Exception("Error writing GIF graphics extension record (trailer section).");
|
||||
}
|
||||
|
||||
// Add Aseprite block (at this moment, it's empty).
|
||||
if (frame_num == 0) {
|
||||
if (EGifPutExtensionLeader(gif_file, APPLICATION_EXT_FUNC_CODE) == GIF_ERROR)
|
||||
throw Exception("Error writing GIF comment (header section).");
|
||||
|
||||
unsigned char extension_bytes[11];
|
||||
memcpy(extension_bytes, "ASEPRITE1.0", 11);
|
||||
if (EGifPutExtensionBlock(gif_file, sizeof(extension_bytes), extension_bytes) == GIF_ERROR)
|
||||
throw Exception("Error writing GIF comment (first block).");
|
||||
|
||||
if (EGifPutExtensionTrailer(gif_file) == GIF_ERROR)
|
||||
throw Exception("Error writing GIF comment (trailer section).");
|
||||
}
|
||||
|
||||
// Write graphics extension record (to save the duration of the
|
||||
// frame and maybe the transparency index).
|
||||
{
|
||||
|
@ -21,9 +21,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "app/context.h"
|
||||
#include "app/document.h"
|
||||
#include "app/document_location.h"
|
||||
#include "doc/settings.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/settings.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -54,7 +54,10 @@ void key_poller_generate_events()
|
||||
|
||||
ev.setType(Event::KeyDown);
|
||||
ev.setScancode(static_cast<KeyScancode>(scancode));
|
||||
ev.setUnicodeChar(unicode_char);
|
||||
if (unicode_char != 0)
|
||||
ev.setUnicodeChar(unicode_char);
|
||||
else
|
||||
ev.setUnicodeChar(::scancode_to_ascii(scancode));
|
||||
ev.setRepeat(repeat);
|
||||
queue_event(ev);
|
||||
}
|
||||
|
@ -14,10 +14,15 @@
|
||||
#include "she/event.h"
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winalleg.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <allegro/platform/aintosx.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace she;
|
||||
@ -36,6 +41,9 @@ int she_mouse_y;
|
||||
int she_mouse_z;
|
||||
int she_mouse_b;
|
||||
|
||||
// Flag to block all the generation of mouse messages from polling.
|
||||
bool mouse_left = false;
|
||||
|
||||
DlbClk double_click_level;
|
||||
Event::MouseButton double_click_button = Event::NoneButton;
|
||||
int double_click_ticks;
|
||||
@ -131,6 +139,29 @@ void generate_mouse_event_for_button(Event::MouseButton button, int old_b, int n
|
||||
queue_event(ev);
|
||||
}
|
||||
|
||||
#if __APPLE__
|
||||
|
||||
void osx_mouser_enter_she_callback()
|
||||
{
|
||||
Event ev;
|
||||
ev.setPosition(gfx::Point(0, 0));
|
||||
ev.setType(Event::MouseEnter);
|
||||
queue_event(ev);
|
||||
|
||||
mouse_left = false;
|
||||
}
|
||||
|
||||
void osx_mouser_leave_she_callback()
|
||||
{
|
||||
Event ev;
|
||||
ev.setType(Event::MouseLeave);
|
||||
queue_event(ev);
|
||||
|
||||
mouse_left = true;
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
}
|
||||
|
||||
namespace she {
|
||||
@ -140,10 +171,18 @@ void mouse_poller_init()
|
||||
double_click_level = DOUBLE_CLICK_NONE;
|
||||
double_click_ticks = 0;
|
||||
moved = true;
|
||||
|
||||
#ifdef __APPLE__
|
||||
osx_mouse_enter_callback = osx_mouser_enter_she_callback;
|
||||
osx_mouse_leave_callback = osx_mouser_leave_she_callback;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mouse_poller_generate_events()
|
||||
{
|
||||
if (mouse_left)
|
||||
return;
|
||||
|
||||
int old_b = she_mouse_b;
|
||||
int old_z = she_mouse_z;
|
||||
|
||||
|
@ -40,7 +40,9 @@
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
|
||||
#elif defined(ALLEGRO_UNIX)
|
||||
|
||||
#include <xalleg.h>
|
||||
#ifdef None
|
||||
#undef None
|
||||
@ -448,7 +450,8 @@ void unsubclass_hwnd(HWND hwnd)
|
||||
base_wndproc = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // WIN32
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class Alleg4Display : public Display {
|
||||
|
@ -321,8 +321,11 @@ std::string Accelerator::toString() const
|
||||
if (m_modifiers & kKeySpaceModifier) buf += "Space+";
|
||||
|
||||
// Key
|
||||
if (m_unicodeChar)
|
||||
buf += (wchar_t)toupper(m_unicodeChar);
|
||||
if (m_unicodeChar) {
|
||||
std::wstring wideUnicodeChar;
|
||||
wideUnicodeChar.push_back((wchar_t)toupper(m_unicodeChar));
|
||||
buf += base::to_utf8(wideUnicodeChar);
|
||||
}
|
||||
else if (m_scancode && m_scancode > 0 && m_scancode < (int)table_size)
|
||||
buf += table[m_scancode];
|
||||
else if (!buf.empty() && buf[buf.size()-1] == '+')
|
||||
|
@ -11,6 +11,8 @@
|
||||
namespace ui {
|
||||
|
||||
enum CursorType {
|
||||
kOutsideDisplay = -1,
|
||||
|
||||
kFirstCursorType = 0,
|
||||
kNoCursor = 0,
|
||||
kArrowCursor,
|
||||
|
@ -281,7 +281,7 @@ void Manager::generateMessagesFromSheEvents()
|
||||
}
|
||||
|
||||
case she::Event::MouseLeave: {
|
||||
jmouse_set_cursor(kNoCursor);
|
||||
jmouse_set_cursor(kOutsideDisplay);
|
||||
setMouse(NULL);
|
||||
|
||||
_internal_no_mouse_position();
|
||||
|
@ -75,11 +75,14 @@ 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) {
|
||||
if (use_native_mouse_cursor || mouse_cursor_type == kOutsideDisplay) {
|
||||
she::NativeCursor nativeCursor = she::kNoCursor;
|
||||
|
||||
native_cursor_available = true;
|
||||
switch (mouse_cursor_type) {
|
||||
case ui::kOutsideDisplay:
|
||||
nativeCursor = she::kArrowCursor;
|
||||
break;
|
||||
case ui::kNoCursor: break;
|
||||
case ui::kArrowCursor:
|
||||
case ui::kArrowPlusCursor:
|
||||
@ -128,10 +131,12 @@ static void update_mouse_cursor()
|
||||
// Use a software cursor with the overlay.
|
||||
|
||||
if (!native_cursor_set) {
|
||||
if (mouse_cursor_type == ui::kNoCursor)
|
||||
if (mouse_cursor_type == ui::kNoCursor) {
|
||||
update_mouse_overlay(NULL);
|
||||
else
|
||||
}
|
||||
else {
|
||||
update_mouse_overlay(CurrentTheme::get()->getCursor(mouse_cursor_type));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Hide the overlay if we are using a native cursor.
|
||||
|
Loading…
x
Reference in New Issue
Block a user