mirror of
https://github.com/aseprite/aseprite.git
synced 2024-12-27 03:16:58 +00:00
Improve "Canvas Size" command to show rulers to change the canvas size.
+ Added EditorDecorator and EditorState::getDecorator(). + Added EditorPreRender and EditorPostRender classes. + Added Image::rectblend and image_rectblend functions to draw transparent rectangles. + Added SelectTileState and Ruler classes.
This commit is contained in:
parent
6293161028
commit
210e33f76a
@ -1,8 +1,7 @@
|
||||
<!-- ASE - Allegro Sprite Editor -->
|
||||
<!-- Copyright (C) 2001-2011 by David Capello -->
|
||||
<jinete>
|
||||
<window text="Canvas Size [work-in-progress]" name="canvas_size">
|
||||
<box vertical="true">
|
||||
<box vertical="true" name="main_box">
|
||||
<box horizontal="true">
|
||||
<box vertical="true" homogeneous="true">
|
||||
<label text="Left:" />
|
||||
@ -30,5 +29,4 @@
|
||||
</box>
|
||||
</box>
|
||||
</box>
|
||||
</window>
|
||||
</jinete>
|
||||
|
@ -289,6 +289,7 @@ add_library(aseprite-library
|
||||
widgets/editor/moving_pixels_state.cpp
|
||||
widgets/editor/pixels_movement.cpp
|
||||
widgets/editor/scrolling_state.cpp
|
||||
widgets/editor/select_tile_state.cpp
|
||||
widgets/editor/standby_state.cpp
|
||||
widgets/editor/tool_loop_impl.cpp
|
||||
widgets/fileview.cpp
|
||||
|
@ -19,18 +19,97 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "app/color_utils.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "commands/command.h"
|
||||
#include "document_wrappers.h"
|
||||
#include "gui/gui.h"
|
||||
#include "modules/editors.h"
|
||||
#include "modules/gui.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/mask.h"
|
||||
#include "raster/sprite.h"
|
||||
#include "undo_transaction.h"
|
||||
#include "widgets/color_bar.h"
|
||||
#include "widgets/editor/editor.h"
|
||||
#include "widgets/editor/select_tile_state.h"
|
||||
|
||||
#include <allegro/unicode.h>
|
||||
|
||||
// Frame used to show canvas parameters.
|
||||
class CanvasSizeFrame : public Frame
|
||||
, public SelectTileDelegate
|
||||
{
|
||||
public:
|
||||
CanvasSizeFrame(int left, int top, int right, int bottom)
|
||||
: Frame(false, "Canvas Size")
|
||||
, m_editor(current_editor)
|
||||
, m_rect(-left, -top,
|
||||
current_editor->getSprite()->getWidth() + right,
|
||||
current_editor->getSprite()->getHeight() + bottom)
|
||||
{
|
||||
m_mainBox = load_widget("canvas_size.xml", "main_box");
|
||||
get_widgets(m_mainBox,
|
||||
"left", &m_left,
|
||||
"top", &m_top,
|
||||
"right", &m_right,
|
||||
"bottom", &m_bottom,
|
||||
"ok", &m_ok, NULL);
|
||||
|
||||
addChild(m_mainBox);
|
||||
|
||||
m_left->setTextf("%d", left);
|
||||
m_right->setTextf("%d", right);
|
||||
m_top->setTextf("%d", top);
|
||||
m_bottom->setTextf("%d", bottom);
|
||||
|
||||
m_editor->setDefaultState(EditorStatePtr(new SelectTileState(this, m_rect)));
|
||||
}
|
||||
|
||||
~CanvasSizeFrame()
|
||||
{
|
||||
m_editor->setDefaultState(EditorStatePtr(new StandbyState));
|
||||
}
|
||||
|
||||
bool pressedOk() { return get_killer() == m_ok; }
|
||||
|
||||
int getLeft() const { return m_left->getTextInt(); }
|
||||
int getRight() const { return m_right->getTextInt(); }
|
||||
int getTop() const { return m_top->getTextInt(); }
|
||||
int getBottom() const { return m_bottom->getTextInt(); }
|
||||
|
||||
// SelectTileDelegate impleentation
|
||||
virtual void onChangeRectangle(const gfx::Rect& rect) OVERRIDE
|
||||
{
|
||||
m_rect = rect;
|
||||
|
||||
m_left->setTextf("%d", -m_rect.x);
|
||||
m_top->setTextf("%d", -m_rect.y);
|
||||
m_right->setTextf("%d", (m_rect.x + m_rect.w) - current_editor->getSprite()->getWidth());
|
||||
m_bottom->setTextf("%d", (m_rect.y + m_rect.h) - current_editor->getSprite()->getHeight());
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onBroadcastMouseMessage(WidgetsList& targets) OVERRIDE
|
||||
{
|
||||
Frame::onBroadcastMouseMessage(targets);
|
||||
|
||||
// Add the editor as receptor of mouse events too.
|
||||
targets.push_back(View::getView(m_editor));
|
||||
}
|
||||
|
||||
private:
|
||||
Editor* m_editor;
|
||||
Widget* m_mainBox;
|
||||
Widget* m_left;
|
||||
Widget* m_right;
|
||||
Widget* m_top;
|
||||
Widget* m_bottom;
|
||||
Widget* m_ok;
|
||||
gfx::Rect m_rect;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CanvasSizeCommand : public Command
|
||||
{
|
||||
int m_left, m_right, m_top, m_bottom;
|
||||
@ -64,40 +143,27 @@ void CanvasSizeCommand::onExecute(Context* context)
|
||||
const Sprite* sprite(document->getSprite());
|
||||
|
||||
if (context->isUiAvailable()) {
|
||||
JWidget left, top, right, bottom, ok;
|
||||
|
||||
// load the window widget
|
||||
FramePtr window(load_widget("canvas_size.xml", "canvas_size"));
|
||||
get_widgets(window,
|
||||
"left", &left,
|
||||
"top", &top,
|
||||
"right", &right,
|
||||
"bottom", &bottom,
|
||||
"ok", &ok, NULL);
|
||||
UniquePtr<CanvasSizeFrame> window(new CanvasSizeFrame(0, 0, 0, 0));
|
||||
|
||||
window->remap_window();
|
||||
window->center_window();
|
||||
|
||||
left->setTextf("%d", m_left);
|
||||
right->setTextf("%d", m_right);
|
||||
top->setTextf("%d", m_top);
|
||||
bottom->setTextf("%d", m_bottom);
|
||||
|
||||
load_window_pos(window, "CanvasSize");
|
||||
window->setVisible(true);
|
||||
window->open_window_fg();
|
||||
save_window_pos(window, "CanvasSize");
|
||||
|
||||
if (window->get_killer() != ok)
|
||||
if (!window->pressedOk())
|
||||
return;
|
||||
|
||||
m_left = left->getTextInt();
|
||||
m_right = right->getTextInt();
|
||||
m_top = top->getTextInt();
|
||||
m_bottom = bottom->getTextInt();
|
||||
m_left = window->getLeft();
|
||||
m_right = window->getRight();
|
||||
m_top = window->getTop();
|
||||
m_bottom = window->getBottom();
|
||||
}
|
||||
|
||||
// resize canvas
|
||||
// Resize canvas
|
||||
|
||||
int x1 = -m_left;
|
||||
int y1 = -m_top;
|
||||
|
@ -296,6 +296,33 @@ void image_rectfill(Image* image, int x1, int y1, int x2, int y2, int color)
|
||||
image->rectfill(x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
void image_rectblend(Image* image, int x1, int y1, int x2, int y2, int color, int opacity)
|
||||
{
|
||||
int t;
|
||||
|
||||
if (x1 > x2) {
|
||||
t = x1;
|
||||
x1 = x2;
|
||||
x2 = t;
|
||||
}
|
||||
|
||||
if (y1 > y2) {
|
||||
t = y1;
|
||||
y1 = y2;
|
||||
y2 = t;
|
||||
}
|
||||
|
||||
if ((x2 < 0) || (x1 >= image->w) || (y2 < 0) || (y1 >= image->h))
|
||||
return;
|
||||
|
||||
if (x1 < 0) x1 = 0;
|
||||
if (y1 < 0) y1 = 0;
|
||||
if (x2 >= image->w) x2 = image->w-1;
|
||||
if (y2 >= image->h) y2 = image->h-1;
|
||||
|
||||
image->rectblend(x1, y1, x2, y2, color, opacity);
|
||||
}
|
||||
|
||||
typedef struct Data
|
||||
{
|
||||
Image* image;
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
virtual void merge(const Image* src, int x, int y, int opacity, int blend_mode) = 0;
|
||||
virtual void hline(int x1, int y, int x2, int color) = 0;
|
||||
virtual void rectfill(int x1, int y1, int x2, int y2, int color) = 0;
|
||||
virtual void rectblend(int x1, int y1, int x2, int y2, int color, int opacity) = 0;
|
||||
virtual void to_allegro(BITMAP* bmp, int x, int y, const Palette* palette) const = 0;
|
||||
};
|
||||
|
||||
@ -90,6 +91,7 @@ void image_hline(Image* image, int x1, int y, int x2, int color);
|
||||
void image_vline(Image* image, int x, int y1, int y2, int color);
|
||||
void image_rect(Image* image, int x1, int y1, int x2, int y2, int color);
|
||||
void image_rectfill(Image* image, int x1, int y1, int x2, int y2, int color);
|
||||
void image_rectblend(Image* image, int x1, int y1, int x2, int y2, int color, int opacity);
|
||||
void image_line(Image* image, int x1, int y1, int x2, int y2, int color);
|
||||
void image_ellipse(Image* image, int x1, int y1, int x2, int y2, int color);
|
||||
void image_ellipsefill(Image* image, int x1, int y1, int x2, int y2, int color);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#ifndef RASTER_IMAGE_IMPL_H_INCLUDED
|
||||
#define RASTER_IMAGE_IMPL_H_INCLUDED
|
||||
|
||||
#include "raster/blend.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/palette.h"
|
||||
|
||||
@ -221,6 +222,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void rectblend(int x1, int y1, int x2, int y2, int color, int opacity)
|
||||
{
|
||||
rectfill(x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
virtual void to_allegro(BITMAP* bmp, int x, int y, const Palette* palette) const;
|
||||
|
||||
};
|
||||
@ -228,6 +234,21 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Specializations
|
||||
|
||||
template<>
|
||||
void ImageImpl<RgbTraits>::rectblend(int x1, int y1, int x2, int y2, int color, int opacity)
|
||||
{
|
||||
address_t addr;
|
||||
int x, y;
|
||||
|
||||
for (y=y1; y<=y2; ++y) {
|
||||
addr = line_address(y)+x1;
|
||||
for (x=x1; x<=x2; ++x) {
|
||||
*addr = _rgba_blend_normal(*addr, color, opacity);
|
||||
++addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void ImageImpl<IndexedTraits>::clear(int color)
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "util/misc.h"
|
||||
#include "util/render.h"
|
||||
#include "widgets/color_bar.h"
|
||||
#include "widgets/editor/editor_decorator.h"
|
||||
#include "widgets/editor/standby_state.h"
|
||||
#include "widgets/statebar.h"
|
||||
|
||||
@ -50,6 +51,68 @@
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
class EditorPreRenderImpl : public EditorPreRender
|
||||
{
|
||||
public:
|
||||
EditorPreRenderImpl(Editor* editor, Image* image, Point& offset, int zoom)
|
||||
: m_editor(editor)
|
||||
, m_image(image)
|
||||
, m_offset(offset)
|
||||
, m_zoom(zoom)
|
||||
{
|
||||
}
|
||||
|
||||
Editor* getEditor() OVERRIDE
|
||||
{
|
||||
return m_editor;
|
||||
}
|
||||
|
||||
Image* getImage() OVERRIDE
|
||||
{
|
||||
return m_image;
|
||||
}
|
||||
|
||||
void fillRect(const gfx::Rect& rect, uint32_t rgbaColor, int opacity) OVERRIDE
|
||||
{
|
||||
image_rectblend(m_image,
|
||||
m_offset.x + (rect.x << m_zoom),
|
||||
m_offset.y + (rect.y << m_zoom),
|
||||
m_offset.x + ((rect.x+rect.w) << m_zoom) - 1,
|
||||
m_offset.y + ((rect.y+rect.h) << m_zoom) - 1, rgbaColor, opacity);
|
||||
}
|
||||
|
||||
private:
|
||||
Editor* m_editor;
|
||||
Image* m_image;
|
||||
Point m_offset;
|
||||
int m_zoom;
|
||||
};
|
||||
|
||||
class EditorPostRenderImpl : public EditorPostRender
|
||||
{
|
||||
public:
|
||||
EditorPostRenderImpl(Editor* editor)
|
||||
: m_editor(editor)
|
||||
{
|
||||
}
|
||||
|
||||
Editor* getEditor()
|
||||
{
|
||||
return m_editor;
|
||||
}
|
||||
|
||||
void drawLine(int x1, int y1, int x2, int y2, int screenColor)
|
||||
{
|
||||
int u1, v1, u2, v2;
|
||||
m_editor->editorToScreen(x1, y1, &u1, &v1);
|
||||
m_editor->editorToScreen(x2, y2, &u2, &v2);
|
||||
line(ji_screen, u1, v1, u2, v2, screenColor);
|
||||
}
|
||||
|
||||
private:
|
||||
Editor* m_editor;
|
||||
};
|
||||
|
||||
Editor::Editor()
|
||||
: Widget(editor_type())
|
||||
, m_defaultState(EditorStatePtr(new StandbyState()))
|
||||
@ -328,6 +391,13 @@ void Editor::drawSprite(int x1, int y1, int x2, int y2)
|
||||
m_zoom, true);
|
||||
|
||||
if (rendered) {
|
||||
// Pre-render decorator.
|
||||
if (EditorDecorator* decorator = m_defaultState->getDecorator()) {
|
||||
EditorPreRenderImpl preRender(this, rendered,
|
||||
Point(-source_x, -source_y), m_zoom);
|
||||
decorator->preRenderDecorator(&preRender);
|
||||
}
|
||||
|
||||
#ifdef DRAWSPRITE_DOUBLEBUFFERED
|
||||
BITMAP *bmp = create_bitmap(width, height);
|
||||
|
||||
@ -362,6 +432,12 @@ void Editor::drawSprite(int x1, int y1, int x2, int y2)
|
||||
if (settings->getGridVisible())
|
||||
this->drawGrid(settings->getGridBounds(),
|
||||
settings->getGridColor());
|
||||
|
||||
// Post-render decorator.
|
||||
if (EditorDecorator* decorator = m_defaultState->getDecorator()) {
|
||||
EditorPostRenderImpl postRender(this);
|
||||
decorator->postRenderDecorator(&postRender);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::drawSpriteSafe(int x1, int y1, int x2, int y2)
|
||||
@ -690,10 +766,10 @@ void Editor::removeListener(EditorListener* listener)
|
||||
}
|
||||
|
||||
// Returns the visible area of the active sprite.
|
||||
gfx::Rect Editor::getVisibleSpriteBounds()
|
||||
Rect Editor::getVisibleSpriteBounds()
|
||||
{
|
||||
// Return an empty rectangle if there is not a active sprite.
|
||||
if (!m_sprite) return gfx::Rect();
|
||||
if (!m_sprite) return Rect();
|
||||
|
||||
View* view = View::getView(this);
|
||||
Rect vp = view->getViewportBounds();
|
||||
|
56
src/widgets/editor/editor_decorator.h
Normal file
56
src/widgets/editor/editor_decorator.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2011 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
|
||||
*/
|
||||
|
||||
#ifndef WIDGETS_EDITOR_EDITOR_DECORATOR_H_INCLUDED
|
||||
#define WIDGETS_EDITOR_EDITOR_DECORATOR_H_INCLUDED
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
class Editor;
|
||||
class EditorDecorator;
|
||||
class Graphics;
|
||||
class Image;
|
||||
|
||||
class EditorPreRender
|
||||
{
|
||||
public:
|
||||
virtual ~EditorPreRender() { }
|
||||
virtual Editor* getEditor() = 0;
|
||||
virtual Image* getImage() = 0;
|
||||
virtual void fillRect(const gfx::Rect& rect, uint32_t rgbaColor, int opacity) = 0;
|
||||
};
|
||||
|
||||
class EditorPostRender
|
||||
{
|
||||
public:
|
||||
virtual ~EditorPostRender() { }
|
||||
virtual Editor* getEditor() = 0;
|
||||
virtual void drawLine(int x1, int y1, int x2, int y2, int screenColor) = 0;
|
||||
};
|
||||
|
||||
class EditorDecorator
|
||||
{
|
||||
public:
|
||||
virtual ~EditorDecorator() { }
|
||||
virtual void preRenderDecorator(EditorPreRender* render) = 0;
|
||||
virtual void postRenderDecorator(EditorPostRender* render) = 0;
|
||||
};
|
||||
|
||||
#endif // WIDGETS_EDITOR_EDITOR_DECORATOR_H_INCLUDED
|
@ -20,6 +20,7 @@
|
||||
#define WIDGETS_EDITOR_EDITOR_STATE_H_INCLUDED
|
||||
|
||||
class Editor;
|
||||
class EditorDecorator;
|
||||
union Message;
|
||||
|
||||
// Represents one state of the sprite's editor (Editor class). This
|
||||
@ -76,6 +77,9 @@ public:
|
||||
// drawing cursor.
|
||||
virtual bool requirePenPreview() { return false; }
|
||||
|
||||
// Called after the sprite is painted.
|
||||
virtual EditorDecorator* getDecorator() { return NULL; }
|
||||
|
||||
};
|
||||
|
||||
#endif // WIDGETS_EDITOR_EDITOR_STATE_H_INCLUDED
|
||||
|
61
src/widgets/editor/ruler.h
Normal file
61
src/widgets/editor/ruler.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2011 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
|
||||
*/
|
||||
|
||||
#ifndef WIDGETS_EDITOR_RULER_H_INCLUDED
|
||||
#define WIDGETS_EDITOR_RULER_H_INCLUDED
|
||||
|
||||
// A ruler inside the editor. It is used by SelectTileState to show
|
||||
// rulers that can be dragged by the user.
|
||||
class Ruler
|
||||
{
|
||||
public:
|
||||
enum Orientation { Horizontal, Vertical };
|
||||
|
||||
Ruler()
|
||||
: m_orientation(Horizontal)
|
||||
, m_position(0)
|
||||
{
|
||||
}
|
||||
|
||||
Ruler(Orientation orientation, int position)
|
||||
: m_orientation(orientation)
|
||||
, m_position(position)
|
||||
{
|
||||
}
|
||||
|
||||
Orientation getOrientation() const
|
||||
{
|
||||
return m_orientation;
|
||||
}
|
||||
|
||||
int getPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void setPosition(int position)
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
private:
|
||||
Orientation m_orientation;
|
||||
int m_position;
|
||||
};
|
||||
|
||||
#endif // WIDGETS_EDITOR_RULER_H_INCLUDED
|
189
src/widgets/editor/select_tile_state.cpp
Normal file
189
src/widgets/editor/select_tile_state.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2011 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 "config.h"
|
||||
|
||||
#include "widgets/editor/select_tile_state.h"
|
||||
|
||||
#include "gfx/rect.h"
|
||||
#include "gui/message.h"
|
||||
#include "gui/system.h"
|
||||
#include "gui/view.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/sprite.h"
|
||||
#include "widgets/editor/editor.h"
|
||||
|
||||
#include <allegro/color.h>
|
||||
|
||||
SelectTileState::SelectTileState(SelectTileDelegate* delegate, const gfx::Rect& rc)
|
||||
: m_delegate(delegate)
|
||||
, m_rulers(4)
|
||||
, m_movingRuler(-1)
|
||||
{
|
||||
m_rulers[H1] = Ruler(Ruler::Horizontal, rc.y);
|
||||
m_rulers[H2] = Ruler(Ruler::Horizontal, rc.y+rc.h);
|
||||
m_rulers[V1] = Ruler(Ruler::Vertical, rc.x);
|
||||
m_rulers[V2] = Ruler(Ruler::Vertical, rc.x+rc.w);
|
||||
}
|
||||
|
||||
bool SelectTileState::onMouseDown(Editor* editor, Message* msg)
|
||||
{
|
||||
if (msg->mouse.left || msg->mouse.right) {
|
||||
m_movingRuler = -1;
|
||||
|
||||
for (int i=0; i<(int)m_rulers.size(); ++i) {
|
||||
if (touchRuler(editor, m_rulers[i], msg->mouse.x, msg->mouse.y)) {
|
||||
m_movingRuler = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
editor->captureMouse();
|
||||
return true;
|
||||
}
|
||||
|
||||
return StandbyState::onMouseDown(editor, msg);
|
||||
}
|
||||
|
||||
bool SelectTileState::onMouseUp(Editor* editor, Message* msg)
|
||||
{
|
||||
m_movingRuler = -1;
|
||||
return StandbyState::onMouseUp(editor, msg);
|
||||
}
|
||||
|
||||
bool SelectTileState::onMouseMove(Editor* editor, Message* msg)
|
||||
{
|
||||
if (m_movingRuler >= 0) {
|
||||
int u, v;
|
||||
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &u, &v);
|
||||
|
||||
switch (m_rulers[m_movingRuler].getOrientation()) {
|
||||
|
||||
case Ruler::Horizontal:
|
||||
m_rulers[m_movingRuler].setPosition(v);
|
||||
break;
|
||||
|
||||
case Ruler::Vertical:
|
||||
m_rulers[m_movingRuler].setPosition(u);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_delegate)
|
||||
m_delegate->onChangeRectangle(getBoxBounds());
|
||||
|
||||
editor->invalidate();
|
||||
return true;
|
||||
}
|
||||
return StandbyState::onMouseMove(editor, msg);
|
||||
}
|
||||
|
||||
bool SelectTileState::onSetCursor(Editor* editor)
|
||||
{
|
||||
int x = jmouse_x(0);
|
||||
int y = jmouse_y(0);
|
||||
|
||||
for (Rulers::iterator it = m_rulers.begin(), end = m_rulers.end(); it != end; ++it) {
|
||||
if (touchRuler(editor, *it, x, y)) {
|
||||
switch (it->getOrientation()) {
|
||||
case Ruler::Horizontal:
|
||||
jmouse_set_cursor(JI_CURSOR_SIZE_T);
|
||||
return true;
|
||||
case Ruler::Vertical:
|
||||
jmouse_set_cursor(JI_CURSOR_SIZE_L);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EditorDecorator* SelectTileState::getDecorator()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void SelectTileState::preRenderDecorator(EditorPreRender* render)
|
||||
{
|
||||
gfx::Rect rc = getBoxBounds();
|
||||
Image* image = render->getImage();
|
||||
Sprite* sprite = render->getEditor()->getSprite();
|
||||
int sprite_w = sprite->getWidth();
|
||||
int sprite_h = sprite->getHeight();
|
||||
|
||||
// Top band
|
||||
if (rc.y > 0)
|
||||
render->fillRect(gfx::Rect(0, 0, sprite_w, rc.y), _rgba(0, 0, 0, 255), 128);
|
||||
|
||||
// Bottom band
|
||||
if (rc.y+rc.h < sprite_h)
|
||||
render->fillRect(gfx::Rect(0, rc.y+rc.h, sprite_w, sprite_h-(rc.y+rc.h)), _rgba(0, 0, 0, 255), 128);
|
||||
|
||||
// Left band
|
||||
if (rc.x > 0)
|
||||
render->fillRect(gfx::Rect(0, rc.y, rc.x, rc.h), _rgba(0, 0, 0, 255), 128);
|
||||
|
||||
// Right band
|
||||
if (rc.x+rc.w < sprite_w)
|
||||
render->fillRect(gfx::Rect(rc.x+rc.w, rc.y, sprite_w-(rc.x+rc.w), rc.h), _rgba(0, 0, 0, 255), 128);
|
||||
}
|
||||
|
||||
void SelectTileState::postRenderDecorator(EditorPostRender* render)
|
||||
{
|
||||
Editor* editor = render->getEditor();
|
||||
int zoom = editor->getZoom();
|
||||
gfx::Rect vp = View::getView(editor)->getViewportBounds();
|
||||
int rulerColor = makecol(0, 0, 255);
|
||||
|
||||
vp.w += 1<<zoom;
|
||||
vp.h += 1<<zoom;
|
||||
editor->screenToEditor(vp, &vp);
|
||||
|
||||
for (Rulers::iterator it = m_rulers.begin(), end = m_rulers.end(); it != end; ++it) {
|
||||
switch (it->getOrientation()) {
|
||||
case Ruler::Horizontal:
|
||||
render->drawLine(vp.x, it->getPosition(), vp.x+vp.w-1, it->getPosition(), rulerColor);
|
||||
break;
|
||||
case Ruler::Vertical:
|
||||
render->drawLine(it->getPosition(), vp.y, it->getPosition(), vp.y+vp.h-1, rulerColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Rect SelectTileState::getBoxBounds() const
|
||||
{
|
||||
int x1 = std::min(m_rulers[V1].getPosition(), m_rulers[V2].getPosition());
|
||||
int y1 = std::min(m_rulers[H1].getPosition(), m_rulers[H2].getPosition());
|
||||
int x2 = std::max(m_rulers[V1].getPosition(), m_rulers[V2].getPosition());
|
||||
int y2 = std::max(m_rulers[H1].getPosition(), m_rulers[H2].getPosition());
|
||||
return gfx::Rect(x1, y1, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
bool SelectTileState::touchRuler(Editor* editor, Ruler& ruler, int x, int y)
|
||||
{
|
||||
int u, v;
|
||||
editor->editorToScreen(ruler.getPosition(), ruler.getPosition(), &u, &v);
|
||||
|
||||
switch (ruler.getOrientation()) {
|
||||
case Ruler::Horizontal: return (y >= v-2 && y <= v+2);
|
||||
case Ruler::Vertical: return (x >= u-2 && x <= u+2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
74
src/widgets/editor/select_tile_state.h
Normal file
74
src/widgets/editor/select_tile_state.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* ASE - Allegro Sprite Editor
|
||||
* Copyright (C) 2001-2011 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
|
||||
*/
|
||||
|
||||
#ifndef WIDGETS_EDITOR_SELECT_TILE_STATE_H_INCLUDED
|
||||
#define WIDGETS_EDITOR_SELECT_TILE_STATE_H_INCLUDED
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "widgets/editor/editor_decorator.h"
|
||||
#include "widgets/editor/ruler.h"
|
||||
#include "widgets/editor/standby_state.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class SelectTileDelegate
|
||||
{
|
||||
public:
|
||||
virtual ~SelectTileDelegate() { }
|
||||
virtual void onChangeRectangle(const gfx::Rect& rect) = 0;
|
||||
};
|
||||
|
||||
class SelectTileState : public StandbyState
|
||||
, public EditorDecorator
|
||||
{
|
||||
enum { H1, H2, V1, V2 };
|
||||
|
||||
public:
|
||||
SelectTileState(SelectTileDelegate* delegate, const gfx::Rect& rc);
|
||||
|
||||
// EditorState overrides
|
||||
virtual bool onMouseDown(Editor* editor, Message* msg) OVERRIDE;
|
||||
virtual bool onMouseUp(Editor* editor, Message* msg) OVERRIDE;
|
||||
virtual bool onMouseMove(Editor* editor, Message* msg) OVERRIDE;
|
||||
virtual bool onSetCursor(Editor* editor) OVERRIDE;
|
||||
virtual EditorDecorator* getDecorator() OVERRIDE;
|
||||
|
||||
// Returns false as it overrides default standby state behavior &
|
||||
// look. This state uses normal arrow cursors.
|
||||
virtual bool requirePenPreview() OVERRIDE { return false; }
|
||||
|
||||
// EditorDecorator overrides
|
||||
virtual void preRenderDecorator(EditorPreRender* render) OVERRIDE;
|
||||
virtual void postRenderDecorator(EditorPostRender* render) OVERRIDE;
|
||||
|
||||
private:
|
||||
typedef std::vector<Ruler> Rulers;
|
||||
|
||||
// Returns the bounding box arranged by the rulers.
|
||||
gfx::Rect getBoxBounds() const;
|
||||
|
||||
// Returns true if the position screen position (x, y) is touching
|
||||
// the given ruler.
|
||||
bool touchRuler(Editor* editor, Ruler& ruler, int x, int y);
|
||||
|
||||
SelectTileDelegate* m_delegate;
|
||||
Rulers m_rulers;
|
||||
int m_movingRuler;
|
||||
};
|
||||
|
||||
#endif // WIDGETS_EDITOR_STANDBY_STATE_H_INCLUDED
|
Loading…
Reference in New Issue
Block a user