mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-28 00:35:30 +00:00
Add rotation pivot options in context bar (fix #370)
With these options we can configure to show the pivot and the default location when we select a sprite area.
This commit is contained in:
parent
9ca83e2624
commit
7cfdf76b0e
@ -52,6 +52,18 @@
|
|||||||
<value id="ALL_LAYERS" value="0" />
|
<value id="ALL_LAYERS" value="0" />
|
||||||
<value id="CURRENT_LAYER" value="1" />
|
<value id="CURRENT_LAYER" value="1" />
|
||||||
</enum>
|
</enum>
|
||||||
|
<enum id="PivotMode">
|
||||||
|
<value id="HIDDEN" value="0" />
|
||||||
|
<value id="NORTHWEST" value="1" />
|
||||||
|
<value id="NORTH" value="2" />
|
||||||
|
<value id="NORTHEAST" value="3" />
|
||||||
|
<value id="WEST" value="4" />
|
||||||
|
<value id="CENTER" value="5" />
|
||||||
|
<value id="EAST" value="6" />
|
||||||
|
<value id="SOUTHWEST" value="7" />
|
||||||
|
<value id="SOUTH" value="8" />
|
||||||
|
<value id="SOUTHEAST" value="9" />
|
||||||
|
</enum>
|
||||||
</types>
|
</types>
|
||||||
|
|
||||||
<global>
|
<global>
|
||||||
@ -110,6 +122,7 @@
|
|||||||
</section>
|
</section>
|
||||||
<section id="selection">
|
<section id="selection">
|
||||||
<option id="mode" type="app::tools::SelectionMode" default="app::tools::SelectionMode::DEFAULT" />
|
<option id="mode" type="app::tools::SelectionMode" default="app::tools::SelectionMode::DEFAULT" />
|
||||||
|
<option id="pivot" type="PivotMode" default="PivotMode::HIDDEN" />
|
||||||
<option id="opaque" type="bool" default="false" />
|
<option id="opaque" type="bool" default="false" />
|
||||||
<option id="auto_opaque" type="bool" default="true" />
|
<option id="auto_opaque" type="bool" default="true" />
|
||||||
<option id="transparent_color" type="app::Color" />
|
<option id="transparent_color" type="app::Color" />
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -377,6 +377,16 @@
|
|||||||
<part id="ink_lock_alpha" x="176" y="144" w="16" h="16" />
|
<part id="ink_lock_alpha" x="176" y="144" w="16" h="16" />
|
||||||
<part id="selection_opaque" x="208" y="176" w="16" h="10" />
|
<part id="selection_opaque" x="208" y="176" w="16" h="10" />
|
||||||
<part id="selection_masked" x="224" y="176" w="16" h="10" />
|
<part id="selection_masked" x="224" y="176" w="16" h="10" />
|
||||||
|
<part id="pivot_hidden" x="208" y="192" w="7" h="7" />
|
||||||
|
<part id="pivot_northwest" x="216" y="192" w="7" h="7" />
|
||||||
|
<part id="pivot_north" x="224" y="192" w="7" h="7" />
|
||||||
|
<part id="pivot_northeast" x="232" y="192" w="7" h="7" />
|
||||||
|
<part id="pivot_west" x="216" y="200" w="7" h="7" />
|
||||||
|
<part id="pivot_center" x="224" y="200" w="7" h="7" />
|
||||||
|
<part id="pivot_east" x="232" y="200" w="7" h="7" />
|
||||||
|
<part id="pivot_southwest" x="216" y="208" w="7" h="7" />
|
||||||
|
<part id="pivot_south" x="224" y="208" w="7" h="7" />
|
||||||
|
<part id="pivot_southeast" x="232" y="208" w="7" h="7" />
|
||||||
</parts>
|
</parts>
|
||||||
|
|
||||||
<stylesheet>
|
<stylesheet>
|
||||||
|
@ -322,6 +322,7 @@ add_library(app-lib
|
|||||||
ui/editor/moving_cel_state.cpp
|
ui/editor/moving_cel_state.cpp
|
||||||
ui/editor/moving_pixels_state.cpp
|
ui/editor/moving_pixels_state.cpp
|
||||||
ui/editor/navigate_state.cpp
|
ui/editor/navigate_state.cpp
|
||||||
|
ui/editor/pivot_helpers.cpp
|
||||||
ui/editor/pixels_movement.cpp
|
ui/editor/pixels_movement.cpp
|
||||||
ui/editor/play_state.cpp
|
ui/editor/play_state.cpp
|
||||||
ui/editor/scrolling_state.cpp
|
ui/editor/scrolling_state.cpp
|
||||||
|
@ -555,8 +555,77 @@ private:
|
|||||||
ContextBar* m_owner;
|
ContextBar* m_owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContextBar::RotAlgorithmField : public ComboBox
|
class ContextBar::PivotField : public ButtonSet {
|
||||||
{
|
public:
|
||||||
|
PivotField()
|
||||||
|
: ButtonSet(1) {
|
||||||
|
addItem(static_cast<SkinTheme*>(getTheme())->get_part(PART_PIVOT_HIDDEN));
|
||||||
|
|
||||||
|
ItemChange.connect(Bind<void>(&PivotField::onPopup, this));
|
||||||
|
|
||||||
|
Preferences::instance().selection.pivot.AfterChange.connect(
|
||||||
|
Bind<void>(&PivotField::onPivotChange, this));
|
||||||
|
|
||||||
|
onPivotChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void onPopup() {
|
||||||
|
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||||
|
|
||||||
|
gfx::Rect bounds = getBounds();
|
||||||
|
|
||||||
|
Menu menu;
|
||||||
|
CheckBox hidden("Hidden pivot by default");
|
||||||
|
HBox box;
|
||||||
|
ButtonSet buttonset(3);
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_NORTHWEST));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_NORTH));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_NORTHEAST));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_WEST));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_CENTER));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_EAST));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_SOUTHWEST));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_SOUTH));
|
||||||
|
buttonset.addItem(theme->get_part(PART_PIVOT_SOUTHEAST));
|
||||||
|
box.addChild(&buttonset);
|
||||||
|
|
||||||
|
menu.addChild(&hidden);
|
||||||
|
menu.addChild(new MenuSeparator);
|
||||||
|
menu.addChild(&box);
|
||||||
|
|
||||||
|
app::gen::PivotMode mode = Preferences::instance().selection.pivot();
|
||||||
|
if (mode == app::gen::PivotMode::HIDDEN)
|
||||||
|
hidden.setSelected(true);
|
||||||
|
else {
|
||||||
|
buttonset.setSelectedItem(int(mode)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden.Click.connect(
|
||||||
|
[&hidden](Event&){
|
||||||
|
Preferences::instance().selection.pivot(app::gen::PivotMode::HIDDEN);
|
||||||
|
hidden.closeWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
buttonset.ItemChange.connect(
|
||||||
|
[&buttonset](){
|
||||||
|
Preferences::instance().selection.pivot(app::gen::PivotMode(buttonset.selectedItem()+1));
|
||||||
|
buttonset.closeWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPivotChange() {
|
||||||
|
int part = PART_PIVOT_HIDDEN + int(Preferences::instance().selection.pivot());
|
||||||
|
getItem(0)->setIcon(
|
||||||
|
static_cast<SkinTheme*>(getTheme())->get_part(part));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ContextBar::RotAlgorithmField : public ComboBox {
|
||||||
public:
|
public:
|
||||||
RotAlgorithmField() {
|
RotAlgorithmField() {
|
||||||
// We use "m_lockChange" variable to avoid setting the rotation
|
// We use "m_lockChange" variable to avoid setting the rotation
|
||||||
@ -925,6 +994,7 @@ ContextBar::ContextBar()
|
|||||||
m_selectionOptionsBox->addChild(m_dropPixels = new DropPixelsField());
|
m_selectionOptionsBox->addChild(m_dropPixels = new DropPixelsField());
|
||||||
m_selectionOptionsBox->addChild(m_selectionMode = new SelectionModeField);
|
m_selectionOptionsBox->addChild(m_selectionMode = new SelectionModeField);
|
||||||
m_selectionOptionsBox->addChild(m_transparentColor = new TransparentColorField(this));
|
m_selectionOptionsBox->addChild(m_transparentColor = new TransparentColorField(this));
|
||||||
|
m_selectionOptionsBox->addChild(m_pivot = new PivotField);
|
||||||
m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField());
|
m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField());
|
||||||
|
|
||||||
addChild(m_brushType = new BrushTypeField(this));
|
addChild(m_brushType = new BrushTypeField(this));
|
||||||
@ -979,6 +1049,7 @@ ContextBar::ContextBar()
|
|||||||
tooltipManager->addTooltipFor(m_inkOpacity, "Opacity (paint intensity)", BOTTOM);
|
tooltipManager->addTooltipFor(m_inkOpacity, "Opacity (paint intensity)", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(m_sprayWidth, "Spray Width", BOTTOM);
|
tooltipManager->addTooltipFor(m_sprayWidth, "Spray Width", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(m_spraySpeed, "Spray Speed", BOTTOM);
|
tooltipManager->addTooltipFor(m_spraySpeed, "Spray Speed", BOTTOM);
|
||||||
|
tooltipManager->addTooltipFor(m_pivot, "Rotation Pivot", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(m_transparentColor, "Transparent Color", BOTTOM);
|
tooltipManager->addTooltipFor(m_transparentColor, "Transparent Color", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(m_rotAlgo, "Rotation Algorithm", BOTTOM);
|
tooltipManager->addTooltipFor(m_rotAlgo, "Rotation Algorithm", BOTTOM);
|
||||||
tooltipManager->addTooltipFor(m_freehandAlgo, "Freehand trace algorithm", BOTTOM);
|
tooltipManager->addTooltipFor(m_freehandAlgo, "Freehand trace algorithm", BOTTOM);
|
||||||
@ -1178,6 +1249,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
|||||||
m_sprayBox->setVisible(hasSprayOptions);
|
m_sprayBox->setVisible(hasSprayOptions);
|
||||||
m_selectionOptionsBox->setVisible(hasSelectOptions);
|
m_selectionOptionsBox->setVisible(hasSelectOptions);
|
||||||
m_selectionMode->setVisible(true);
|
m_selectionMode->setVisible(true);
|
||||||
|
m_pivot->setVisible(true);
|
||||||
m_dropPixels->setVisible(false);
|
m_dropPixels->setVisible(false);
|
||||||
m_selectBoxHelp->setVisible(false);
|
m_selectBoxHelp->setVisible(false);
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ namespace app {
|
|||||||
class SpraySpeedField;
|
class SpraySpeedField;
|
||||||
class SelectionModeField;
|
class SelectionModeField;
|
||||||
class TransparentColorField;
|
class TransparentColorField;
|
||||||
|
class PivotField;
|
||||||
class RotAlgorithmField;
|
class RotAlgorithmField;
|
||||||
class FreehandAlgorithmField;
|
class FreehandAlgorithmField;
|
||||||
class BrushPatternField;
|
class BrushPatternField;
|
||||||
@ -135,6 +136,7 @@ namespace app {
|
|||||||
ui::Box* m_selectionOptionsBox;
|
ui::Box* m_selectionOptionsBox;
|
||||||
SelectionModeField* m_selectionMode;
|
SelectionModeField* m_selectionMode;
|
||||||
TransparentColorField* m_transparentColor;
|
TransparentColorField* m_transparentColor;
|
||||||
|
PivotField* m_pivot;
|
||||||
RotAlgorithmField* m_rotAlgo;
|
RotAlgorithmField* m_rotAlgo;
|
||||||
DropPixelsField* m_dropPixels;
|
DropPixelsField* m_dropPixels;
|
||||||
doc::BrushRef m_activeBrush;
|
doc::BrushRef m_activeBrush;
|
||||||
|
@ -1457,8 +1457,8 @@ void Editor::pasteImage(const Image* image, const Mask* mask)
|
|||||||
mask2.setOrigin(x, y);
|
mask2.setOrigin(x, y);
|
||||||
|
|
||||||
PixelsMovementPtr pixelsMovement(
|
PixelsMovementPtr pixelsMovement(
|
||||||
new PixelsMovement(UIContext::instance(),
|
new PixelsMovement(UIContext::instance(), getSite(),
|
||||||
getSite(), image, &mask2, "Paste"));
|
image, &mask2, "Paste"));
|
||||||
|
|
||||||
setState(EditorStatePtr(new MovingPixelsState(this, NULL, pixelsMovement, NoHandle)));
|
setState(EditorStatePtr(new MovingPixelsState(this, NULL, pixelsMovement, NoHandle)));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/commands/commands.h"
|
#include "app/commands/commands.h"
|
||||||
#include "app/console.h"
|
#include "app/console.h"
|
||||||
|
#include "app/modules/gui.h"
|
||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
#include "app/tools/ink.h"
|
#include "app/tools/ink.h"
|
||||||
#include "app/tools/tool.h"
|
#include "app/tools/tool.h"
|
||||||
@ -127,6 +128,13 @@ void MovingPixelsState::translate(const gfx::Point& delta)
|
|||||||
m_pixelsMovement->dropImageTemporarily();
|
m_pixelsMovement->dropImageTemporarily();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MovingPixelsState::onEnterState(Editor* editor)
|
||||||
|
{
|
||||||
|
StandbyState::onEnterState(editor);
|
||||||
|
|
||||||
|
update_screen_for_document(editor->document());
|
||||||
|
}
|
||||||
|
|
||||||
EditorState::LeaveAction MovingPixelsState::onLeaveState(Editor* editor, EditorState* newState)
|
EditorState::LeaveAction MovingPixelsState::onLeaveState(Editor* editor, EditorState* newState)
|
||||||
{
|
{
|
||||||
ASSERT(m_pixelsMovement);
|
ASSERT(m_pixelsMovement);
|
||||||
|
@ -36,6 +36,7 @@ namespace app {
|
|||||||
void translate(const gfx::Point& delta);
|
void translate(const gfx::Point& delta);
|
||||||
|
|
||||||
// EditorState
|
// EditorState
|
||||||
|
virtual void onEnterState(Editor* editor) override;
|
||||||
virtual LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
|
virtual LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
|
||||||
virtual void onCurrentToolChange(Editor* editor) override;
|
virtual void onCurrentToolChange(Editor* editor) override;
|
||||||
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
|
60
src/app/ui/editor/pivot_helpers.cpp
Normal file
60
src/app/ui/editor/pivot_helpers.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2001-2015 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/ui/editor/pivot_helpers.h"
|
||||||
|
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
|
#include "gfx/transformation.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
void set_pivot_from_preferences(gfx::Transformation& t)
|
||||||
|
{
|
||||||
|
gfx::Transformation::Corners corners;
|
||||||
|
t.transformBox(corners);
|
||||||
|
gfx::PointT<double> nw(corners[gfx::Transformation::Corners::LEFT_TOP]);
|
||||||
|
gfx::PointT<double> ne(corners[gfx::Transformation::Corners::RIGHT_TOP]);
|
||||||
|
gfx::PointT<double> sw(corners[gfx::Transformation::Corners::LEFT_BOTTOM]);
|
||||||
|
gfx::PointT<double> se(corners[gfx::Transformation::Corners::RIGHT_BOTTOM]);
|
||||||
|
gfx::PointT<double> pivotPos((nw + se) / 2);
|
||||||
|
|
||||||
|
app::gen::PivotMode pivotMode = Preferences::instance().selection.pivot();
|
||||||
|
switch (pivotMode) {
|
||||||
|
case app::gen::PivotMode::NORTHWEST:
|
||||||
|
pivotPos = nw;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::NORTH:
|
||||||
|
pivotPos = (nw + ne) / 2.0;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::NORTHEAST:
|
||||||
|
pivotPos = ne;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::WEST:
|
||||||
|
pivotPos = (nw + sw) / 2.0;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::EAST:
|
||||||
|
pivotPos = (ne + se) / 2.0;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::SOUTHWEST:
|
||||||
|
pivotPos = sw;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::SOUTH:
|
||||||
|
pivotPos = (sw + se) / 2.0;
|
||||||
|
break;
|
||||||
|
case app::gen::PivotMode::SOUTHEAST:
|
||||||
|
pivotPos = se;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.displacePivotTo(gfx::Point(pivotPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace app
|
22
src/app/ui/editor/pivot_helpers.h
Normal file
22
src/app/ui/editor/pivot_helpers.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2001-2015 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.
|
||||||
|
|
||||||
|
#ifndef APP_UI_EDITOR_PIVOT_HELPERS_H_INCLUDED
|
||||||
|
#define APP_UI_EDITOR_PIVOT_HELPERS_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace gfx {
|
||||||
|
class Transformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
void set_pivot_from_preferences(gfx::Transformation& t);
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
@ -21,6 +21,7 @@
|
|||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
#include "app/snap_to_grid.h"
|
#include "app/snap_to_grid.h"
|
||||||
|
#include "app/ui/editor/pivot_helpers.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "app/util/expand_cel_canvas.h"
|
#include "app/util/expand_cel_canvas.h"
|
||||||
@ -66,12 +67,18 @@ PixelsMovement::PixelsMovement(
|
|||||||
, m_originalImage(Image::createCopy(moveThis))
|
, m_originalImage(Image::createCopy(moveThis))
|
||||||
, m_maskColor(m_sprite->transparentColor())
|
, m_maskColor(m_sprite->transparentColor())
|
||||||
{
|
{
|
||||||
m_initialData = gfx::Transformation(mask->bounds());
|
gfx::Transformation transform(mask->bounds());
|
||||||
m_currentData = m_initialData;
|
set_pivot_from_preferences(transform);
|
||||||
|
|
||||||
|
m_initialData = transform;
|
||||||
|
m_currentData = transform;
|
||||||
|
|
||||||
m_initialMask = new Mask(*mask);
|
m_initialMask = new Mask(*mask);
|
||||||
m_currentMask = new Mask(*mask);
|
m_currentMask = new Mask(*mask);
|
||||||
|
|
||||||
|
m_pivotConn =
|
||||||
|
Preferences::instance().selection.pivot.AfterChange.connect(
|
||||||
|
Bind<void>(&PixelsMovement::onPivotChange, this));
|
||||||
m_rotAlgoConn =
|
m_rotAlgoConn =
|
||||||
Preferences::instance().selection.rotationAlgorithm.AfterChange.connect(
|
Preferences::instance().selection.rotationAlgorithm.AfterChange.connect(
|
||||||
Bind<void>(&PixelsMovement::onRotationAlgorithmChange, this));
|
Bind<void>(&PixelsMovement::onRotationAlgorithmChange, this));
|
||||||
@ -84,7 +91,6 @@ PixelsMovement::PixelsMovement(
|
|||||||
|
|
||||||
redrawCurrentMask();
|
redrawCurrentMask();
|
||||||
updateDocumentMask();
|
updateDocumentMask();
|
||||||
update_screen_for_document(m_document);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelsMovement::~PixelsMovement()
|
PixelsMovement::~PixelsMovement()
|
||||||
@ -710,6 +716,12 @@ retry:; // In case that we don't have enough memory for RotSprite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PixelsMovement::onPivotChange()
|
||||||
|
{
|
||||||
|
set_pivot_from_preferences(m_currentData);
|
||||||
|
onRotationAlgorithmChange();
|
||||||
|
}
|
||||||
|
|
||||||
void PixelsMovement::onRotationAlgorithmChange()
|
void PixelsMovement::onRotationAlgorithmChange()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -89,6 +89,7 @@ namespace app {
|
|||||||
const gfx::Transformation& getTransformation() const { return m_currentData; }
|
const gfx::Transformation& getTransformation() const { return m_currentData; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void onPivotChange();
|
||||||
void onRotationAlgorithmChange();
|
void onRotationAlgorithmChange();
|
||||||
void redrawExtraImage();
|
void redrawExtraImage();
|
||||||
void redrawCurrentMask();
|
void redrawCurrentMask();
|
||||||
@ -117,6 +118,7 @@ namespace app {
|
|||||||
Mask* m_currentMask;
|
Mask* m_currentMask;
|
||||||
bool m_opaque;
|
bool m_opaque;
|
||||||
color_t m_maskColor;
|
color_t m_maskColor;
|
||||||
|
ScopedConnection m_pivotConn;
|
||||||
ScopedConnection m_rotAlgoConn;
|
ScopedConnection m_rotAlgoConn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/color_picker.h"
|
#include "app/color_picker.h"
|
||||||
#include "app/commands/commands.h"
|
|
||||||
#include "app/commands/cmd_eyedropper.h"
|
#include "app/commands/cmd_eyedropper.h"
|
||||||
|
#include "app/commands/commands.h"
|
||||||
#include "app/commands/params.h"
|
#include "app/commands/params.h"
|
||||||
#include "app/ini_file.h"
|
#include "app/ini_file.h"
|
||||||
#include "app/pref/preferences.h"
|
#include "app/pref/preferences.h"
|
||||||
@ -27,6 +27,7 @@
|
|||||||
#include "app/ui/editor/handle_type.h"
|
#include "app/ui/editor/handle_type.h"
|
||||||
#include "app/ui/editor/moving_cel_state.h"
|
#include "app/ui/editor/moving_cel_state.h"
|
||||||
#include "app/ui/editor/moving_pixels_state.h"
|
#include "app/ui/editor/moving_pixels_state.h"
|
||||||
|
#include "app/ui/editor/pivot_helpers.h"
|
||||||
#include "app/ui/editor/pixels_movement.h"
|
#include "app/ui/editor/pixels_movement.h"
|
||||||
#include "app/ui/editor/scrolling_state.h"
|
#include "app/ui/editor/scrolling_state.h"
|
||||||
#include "app/ui/editor/tool_loop_impl.h"
|
#include "app/ui/editor/tool_loop_impl.h"
|
||||||
@ -35,6 +36,7 @@
|
|||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "app/util/new_image_from_mask.h"
|
#include "app/util/new_image_from_mask.h"
|
||||||
|
#include "base/bind.h"
|
||||||
#include "base/pi.h"
|
#include "base/pi.h"
|
||||||
#include "doc/layer.h"
|
#include "doc/layer.h"
|
||||||
#include "doc/mask.h"
|
#include "doc/mask.h"
|
||||||
@ -89,6 +91,10 @@ StandbyState::~StandbyState()
|
|||||||
void StandbyState::onEnterState(Editor* editor)
|
void StandbyState::onEnterState(Editor* editor)
|
||||||
{
|
{
|
||||||
editor->setDecorator(m_decorator);
|
editor->setDecorator(m_decorator);
|
||||||
|
|
||||||
|
m_pivotConn =
|
||||||
|
Preferences::instance().selection.pivot.AfterChange.connect(
|
||||||
|
Bind<void>(&StandbyState::onPivotChange, this, editor));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandbyState::onCurrentToolChange(Editor* editor)
|
void StandbyState::onCurrentToolChange(Editor* editor)
|
||||||
@ -392,7 +398,9 @@ bool StandbyState::onUpdateStatusBar(Editor* editor)
|
|||||||
|
|
||||||
gfx::Transformation StandbyState::getTransformation(Editor* editor)
|
gfx::Transformation StandbyState::getTransformation(Editor* editor)
|
||||||
{
|
{
|
||||||
return editor->document()->getTransformation();
|
gfx::Transformation t = editor->document()->getTransformation();
|
||||||
|
set_pivot_from_preferences(t);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandbyState::startSelectionTransformation(Editor* editor, const gfx::Point& move)
|
void StandbyState::startSelectionTransformation(Editor* editor, const gfx::Point& move)
|
||||||
@ -458,6 +466,16 @@ void StandbyState::callEyedropper(Editor* editor)
|
|||||||
UIContext::instance()->executeCommand(eyedropper_cmd, params);
|
UIContext::instance()->executeCommand(eyedropper_cmd, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StandbyState::onPivotChange(Editor* editor)
|
||||||
|
{
|
||||||
|
if (editor->isActive() &&
|
||||||
|
editor->editorFlags() & Editor::kShowMask &&
|
||||||
|
editor->document()->isMaskVisible() &&
|
||||||
|
!editor->document()->mask()->isFrozen()) {
|
||||||
|
editor->invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Decorator
|
// Decorator
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "app/ui/editor/editor_decorator.h"
|
#include "app/ui/editor/editor_decorator.h"
|
||||||
#include "app/ui/editor/handle_type.h"
|
#include "app/ui/editor/handle_type.h"
|
||||||
#include "app/ui/editor/state_with_wheel_behavior.h"
|
#include "app/ui/editor/state_with_wheel_behavior.h"
|
||||||
|
#include "base/connection.h"
|
||||||
#include "gfx/transformation.h"
|
#include "gfx/transformation.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -66,8 +67,10 @@ namespace app {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void transformSelection(Editor* editor, ui::MouseMessage* msg, HandleType handle);
|
void transformSelection(Editor* editor, ui::MouseMessage* msg, HandleType handle);
|
||||||
|
void onPivotChange(Editor* editor);
|
||||||
|
|
||||||
Decorator* m_decorator;
|
Decorator* m_decorator;
|
||||||
|
ScopedConnection m_pivotConn;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "app/ui/editor/transform_handles.h"
|
#include "app/ui/editor/transform_handles.h"
|
||||||
|
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
#include "app/ui/editor/editor.h"
|
#include "app/ui/editor/editor.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
#include "base/pi.h"
|
#include "base/pi.h"
|
||||||
@ -51,14 +52,6 @@ static struct HandlesInfo {
|
|||||||
{ 2, 2, 224 << 16, { ScaleSEHandle, RotateSEHandle } },
|
{ 2, 2, 224 << 16, { ScaleSEHandle, RotateSEHandle } },
|
||||||
};
|
};
|
||||||
|
|
||||||
TransformHandles::TransformHandles()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TransformHandles::~TransformHandles()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform)
|
HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform)
|
||||||
{
|
{
|
||||||
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
|
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
|
||||||
@ -88,7 +81,7 @@ HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the cursor is in the pivot
|
// Check if the cursor is in the pivot
|
||||||
if (angle != 0 && getPivotHandleBounds(editor, transform, corners).contains(pt))
|
if (visiblePivot(angle) && getPivotHandleBounds(editor, transform, corners).contains(pt))
|
||||||
return PivotHandle;
|
return PivotHandle;
|
||||||
|
|
||||||
return NoHandle;
|
return NoHandle;
|
||||||
@ -111,19 +104,16 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
|
|||||||
#if 0 // Uncomment this if you want to see the bounds in red (only for debugging purposes)
|
#if 0 // Uncomment this if you want to see the bounds in red (only for debugging purposes)
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
{
|
{
|
||||||
int x1, y1, x2, y2;
|
gfx::Point
|
||||||
x1 = transform.bounds().x;
|
a(transform.bounds().getOrigin()),
|
||||||
y1 = transform.bounds().y;
|
b(transform.bounds().getPoint2());
|
||||||
x2 = x1 + transform.bounds().w;
|
a = editor->editorToScreen(a);
|
||||||
y2 = y1 + transform.bounds().h;
|
b = editor->editorToScreen(b);
|
||||||
editor->editorToScreen(x1, y1, &x1, &y1);
|
g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(a, b));
|
||||||
editor->editorToScreen(x2, y2, &x2, &y2);
|
|
||||||
g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(x1, y1, x2-x1+1, y2-y1+1));
|
|
||||||
|
|
||||||
x1 = transform.pivot().x;
|
a = transform.pivot();
|
||||||
y1 = transform.pivot().y;
|
a = editor->editorToScreen(a);
|
||||||
editor->editorToScreen(x1, y1, &x1, &y1);
|
g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(a.x-2, a.y-2, 5, 5));
|
||||||
g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(x1-2, y1-2, 5, 5));
|
|
||||||
}
|
}
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
@ -137,7 +127,7 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw the pivot
|
// Draw the pivot
|
||||||
if (angle != 0) {
|
if (visiblePivot(angle)) {
|
||||||
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
|
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
|
||||||
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
|
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
|
||||||
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
|
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
|
||||||
@ -171,7 +161,7 @@ void TransformHandles::invalidateHandles(Editor* editor, const gfx::Transformati
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invalidate area where the pivot is.
|
// Invalidate area where the pivot is.
|
||||||
if (angle != 0) {
|
if (visiblePivot(angle)) {
|
||||||
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
|
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
|
||||||
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
|
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
|
||||||
|
|
||||||
@ -264,4 +254,10 @@ void TransformHandles::adjustHandle(int& x, int& y, int handle_w, int handle_h,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TransformHandles::visiblePivot(fixmath::fixed angle) const
|
||||||
|
{
|
||||||
|
return (Preferences::instance().selection.pivot() != app::gen::PivotMode::HIDDEN ||
|
||||||
|
angle != 0);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -25,9 +25,6 @@ namespace app {
|
|||||||
// and rotation pivot.
|
// and rotation pivot.
|
||||||
class TransformHandles {
|
class TransformHandles {
|
||||||
public:
|
public:
|
||||||
TransformHandles();
|
|
||||||
~TransformHandles();
|
|
||||||
|
|
||||||
// Returns the handle in the given mouse point (pt) when the user
|
// Returns the handle in the given mouse point (pt) when the user
|
||||||
// has applied the given transformation to the selection.
|
// has applied the given transformation to the selection.
|
||||||
HandleType getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform);
|
HandleType getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform);
|
||||||
@ -43,6 +40,7 @@ namespace app {
|
|||||||
bool inHandle(const gfx::Point& pt, int x, int y, int gfx_w, int gfx_h, fixmath::fixed angle);
|
bool inHandle(const gfx::Point& pt, int x, int y, int gfx_w, int gfx_h, fixmath::fixed angle);
|
||||||
void drawHandle(ui::Graphics* g, int x, int y, fixmath::fixed angle);
|
void drawHandle(ui::Graphics* g, int x, int y, fixmath::fixed angle);
|
||||||
void adjustHandle(int& x, int& y, int handle_w, int handle_h, fixmath::fixed angle);
|
void adjustHandle(int& x, int& y, int handle_w, int handle_h, fixmath::fixed angle);
|
||||||
|
bool visiblePivot(fixmath::fixed angle) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -183,6 +183,17 @@ namespace app {
|
|||||||
PART_SELECTION_OPAQUE,
|
PART_SELECTION_OPAQUE,
|
||||||
PART_SELECTION_MASKED,
|
PART_SELECTION_MASKED,
|
||||||
|
|
||||||
|
PART_PIVOT_HIDDEN,
|
||||||
|
PART_PIVOT_NORTHWEST,
|
||||||
|
PART_PIVOT_NORTH,
|
||||||
|
PART_PIVOT_NORTHEAST,
|
||||||
|
PART_PIVOT_WEST,
|
||||||
|
PART_PIVOT_CENTER,
|
||||||
|
PART_PIVOT_EAST,
|
||||||
|
PART_PIVOT_SOUTHWEST,
|
||||||
|
PART_PIVOT_SOUTH,
|
||||||
|
PART_PIVOT_SOUTHEAST,
|
||||||
|
|
||||||
PARTS
|
PARTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -283,6 +283,16 @@ SkinTheme::SkinTheme()
|
|||||||
sheet_mapping["ink_lock_alpha"] = PART_INK_LOCK_ALPHA;
|
sheet_mapping["ink_lock_alpha"] = PART_INK_LOCK_ALPHA;
|
||||||
sheet_mapping["selection_opaque"] = PART_SELECTION_OPAQUE;
|
sheet_mapping["selection_opaque"] = PART_SELECTION_OPAQUE;
|
||||||
sheet_mapping["selection_masked"] = PART_SELECTION_MASKED;
|
sheet_mapping["selection_masked"] = PART_SELECTION_MASKED;
|
||||||
|
sheet_mapping["pivot_hidden"] = PART_PIVOT_HIDDEN;
|
||||||
|
sheet_mapping["pivot_northwest"] = PART_PIVOT_NORTHWEST;
|
||||||
|
sheet_mapping["pivot_north"] = PART_PIVOT_NORTH;
|
||||||
|
sheet_mapping["pivot_northeast"] = PART_PIVOT_NORTHEAST;
|
||||||
|
sheet_mapping["pivot_west"] = PART_PIVOT_WEST;
|
||||||
|
sheet_mapping["pivot_center"] = PART_PIVOT_CENTER;
|
||||||
|
sheet_mapping["pivot_east"] = PART_PIVOT_EAST;
|
||||||
|
sheet_mapping["pivot_southwest"] = PART_PIVOT_SOUTHWEST;
|
||||||
|
sheet_mapping["pivot_south"] = PART_PIVOT_SOUTH;
|
||||||
|
sheet_mapping["pivot_southeast"] = PART_PIVOT_SOUTHEAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkinTheme::~SkinTheme()
|
SkinTheme::~SkinTheme()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user