Select a tile by double clicking over it (fix #939)

This commit is contained in:
David Capello 2016-03-19 11:33:05 -03:00
parent 497cfa61a4
commit 30f4e995a3
12 changed files with 159 additions and 13 deletions

View File

@ -398,6 +398,7 @@
<key command="AddColor">
<param name="source" value="bg" />
</key>
<key command="SelectTile" />
</commands>
<!-- Keyboard shortcuts to select tools -->

View File

@ -247,6 +247,7 @@ add_library(app-lib
commands/cmd_save_palette.cpp
commands/cmd_scroll.cpp
commands/cmd_scroll_center.cpp
commands/cmd_select_tile.cpp
commands/cmd_set_color_selector.cpp
commands/cmd_set_ink_type.cpp
commands/cmd_set_loop_section.cpp

View File

@ -0,0 +1,87 @@
// Aseprite
// Copyright (C) 2015, 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
// published by the Free Software Foundation.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/set_mask.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/document.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/pref/preferences.h"
#include "app/snap_to_grid.h"
#include "app/transaction.h"
#include "app/ui/editor/editor.h"
#include "doc/mask.h"
#include "ui/system.h"
namespace app {
using namespace doc;
class SelectTileCommand : public Command {
public:
SelectTileCommand();
Command* clone() const override { return new SelectTileCommand(*this); }
protected:
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
};
SelectTileCommand::SelectTileCommand()
: Command("SelectTile",
"Select Tile",
CmdRecordableFlag)
{
}
bool SelectTileCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
}
void SelectTileCommand::onExecute(Context* ctx)
{
if (!current_editor ||
!current_editor->hasMouse())
return;
// Lock sprite
ContextWriter writer(ctx);
Document* doc(writer.document());
auto& docPref = Preferences::instance().document(doc);
base::UniquePtr<Mask> mask(new Mask());
{
const gfx::Rect gridBounds = docPref.grid.bounds();
gfx::Point pos = current_editor->screenToEditor(ui::get_mouse_position());
pos = snap_to_grid(gridBounds, pos, PreferSnapTo::BoxOrigin);
mask->add(gfx::Rect(pos, gridBounds.size()));
}
// Set the new mask
Transaction transaction(writer.context(),
"Select Tile",
DoesntModifyDocument);
transaction.execute(new cmd::SetMask(doc, mask));
transaction.commit();
doc->generateMaskBoundaries();
update_screen_for_document(doc);
}
Command* CommandFactory::createSelectTileCommand()
{
return new SelectTileCommand;
}
} // namespace app

View File

@ -108,6 +108,7 @@ FOR_EACH_COMMAND(SaveMask)
FOR_EACH_COMMAND(SavePalette)
FOR_EACH_COMMAND(Scroll)
FOR_EACH_COMMAND(ScrollCenter)
FOR_EACH_COMMAND(SelectTile)
FOR_EACH_COMMAND(SelectionAsGrid)
FOR_EACH_COMMAND(SetColorSelector)
FOR_EACH_COMMAND(SetInkType)

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
@ -18,7 +18,9 @@
namespace app {
gfx::Point snap_to_grid(const gfx::Rect& grid, const gfx::Point& point)
gfx::Point snap_to_grid(const gfx::Rect& grid,
const gfx::Point& point,
const PreferSnapTo prefer)
{
gfx::Point newPoint;
div_t d, dx, dy;
@ -26,11 +28,24 @@ gfx::Point snap_to_grid(const gfx::Rect& grid, const gfx::Point& point)
dx = std::div(grid.x, grid.w);
dy = std::div(grid.y, grid.h);
d = std::div(point.x-dx.rem, grid.w);
newPoint.x = dx.rem + d.quot*grid.w + ((d.rem > grid.w/2)? grid.w: 0);
switch (prefer) {
d = std::div(point.y-dy.rem, grid.h);
newPoint.y = dy.rem + d.quot*grid.h + ((d.rem > grid.h/2)? grid.h: 0);
case PreferSnapTo::ClosestGridVertex:
d = std::div(point.x-dx.rem, grid.w);
newPoint.x = dx.rem + d.quot*grid.w + ((d.rem > grid.w/2)? grid.w: 0);
d = std::div(point.y-dy.rem, grid.h);
newPoint.y = dy.rem + d.quot*grid.h + ((d.rem > grid.h/2)? grid.h: 0);
break;
case PreferSnapTo::BoxOrigin:
d = std::div(point.x-dx.rem, grid.w);
newPoint.x = dx.rem + d.quot*grid.w;
d = std::div(point.y-dy.rem, grid.h);
newPoint.y = dy.rem + d.quot*grid.h;
break;
}
return newPoint;
}

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
@ -13,7 +13,14 @@
namespace app {
gfx::Point snap_to_grid(const gfx::Rect& grid, const gfx::Point& point);
enum class PreferSnapTo {
ClosestGridVertex,
BoxOrigin
};
gfx::Point snap_to_grid(const gfx::Rect& grid,
const gfx::Point& point,
const PreferSnapTo prefer);
} // namespace app

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
@ -234,7 +234,8 @@ void ToolLoopManager::snapToGrid(Point& point)
!m_toolLoop->getSnapToGrid())
return;
point = snap_to_grid(m_toolLoop->getGridBounds(), point);
point = snap_to_grid(m_toolLoop->getGridBounds(), point,
PreferSnapTo::ClosestGridVertex);
}
// Strokes are relative to sprite origin.

View File

@ -1294,6 +1294,16 @@ bool Editor::onProcessMessage(Message* msg)
}
break;
case kDoubleClickMessage:
if (m_sprite) {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
EditorStatePtr holdState(m_state);
bool used = m_state->onDoubleClick(this, mouseMsg);
if (used)
return true;
}
break;
case kTouchMagnifyMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);

View File

@ -89,6 +89,9 @@ namespace app {
// Called when the user wants to zoom in/out using a pinch gesture in the trackpad.
virtual bool onTouchMagnify(Editor* editor, ui::TouchMessage* msg) { return false; }
// Called when the user moves the mouse wheel over the editor.
virtual bool onDoubleClick(Editor* editor, ui::MouseMessage* msg) { return false; }
// Called each time the mouse changes its position so we can set an
// appropiated cursor depending on the new coordinates of the mouse
// pointer.

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
@ -268,7 +268,8 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
gfx::Rect gridBounds = App::instance()
->preferences().document(m_document).grid.bounds();
gfx::Point gridOffset(x1, y1);
gridOffset = snap_to_grid(gridBounds, gridOffset);
gridOffset = snap_to_grid(gridBounds, gridOffset,
PreferSnapTo::ClosestGridVertex);
// Now we calculate the difference from x1,y1 point and we can
// use it to adjust all coordinates (x1, y1, x2, y2).

View File

@ -337,6 +337,24 @@ bool StandbyState::onMouseMove(Editor* editor, MouseMessage* msg)
return true;
}
bool StandbyState::onDoubleClick(Editor* editor, MouseMessage* msg)
{
if (editor->hasCapture())
return false;
tools::Ink* ink = editor->getCurrentEditorInk();
// Select a tile with double-click
if (ink->isSelection()) {
Command* selectTileCmd =
CommandsModule::instance()->getCommandByName(CommandId::SelectTile);
UIContext::instance()->executeCommand(selectTileCmd);
}
return false;
}
bool StandbyState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
{
tools::Ink* ink = editor->getCurrentEditorInk();

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
@ -32,6 +32,7 @@ namespace app {
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
virtual bool onDoubleClick(Editor* editor, ui::MouseMessage* msg) override;
virtual bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) override;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) override;