mirror of
https://github.com/aseprite/aseprite.git
synced 2024-12-29 18:20:44 +00:00
Add Import Sprite Sheet padding (fix #78)
This commit is contained in:
parent
67e0da478d
commit
d4607e889b
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2018 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018-2019 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2014-2018 David Capello -->
|
||||
<preferences>
|
||||
|
||||
@ -436,6 +436,7 @@
|
||||
<section id="import_sprite_sheet">
|
||||
<option id="type" type="app::SpriteSheetType" default="app::SpriteSheetType::Rows" />
|
||||
<option id="bounds" type="gfx::Rect" default="gfx::Rect(0, 0, 0, 0)" />
|
||||
<option id="padding_bounds" type="gfx::Size" default="gfx::Size(0, 0)" />
|
||||
<option id="partial_tiles" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="preview" text="Preview">
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Aseprite
|
||||
# Copyright (C) 2018 Igara Studio S.A.
|
||||
# Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
# Copyright (C) 2016-2018 David Capello
|
||||
|
||||
[advanced_mode]
|
||||
@ -624,6 +624,8 @@ x = X:
|
||||
y = Y:
|
||||
width = Width:
|
||||
height = Height:
|
||||
horizontal_padding = Horizontal:
|
||||
vertical_padding = Vertical:
|
||||
partial_tiles = Include partial tiles at bottom/right edges
|
||||
import = &Import
|
||||
cancel = &Cancel
|
||||
|
@ -1,34 +1,49 @@
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2019 by Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2001-2018 by David Capello -->
|
||||
<gui>
|
||||
<window id="import_sprite_sheet" text="@.title">
|
||||
<grid columns="4">
|
||||
<button id="select_file" text="@.select_file" cell_hspan="4" />
|
||||
<vbox>
|
||||
<grid columns="4">
|
||||
<button id="select_file" text="@.select_file" cell_hspan="4" />
|
||||
|
||||
<label text="@.type" />
|
||||
<combobox id="sheet_type" cell_hspan="3" />
|
||||
<label text="@.type" />
|
||||
<combobox id="sheet_type" cell_hspan="3" />
|
||||
|
||||
<label text="@.x" />
|
||||
<expr id="x" text="0" />
|
||||
<separator text="Tiles:" horizontal="true" cell_hspan="4" />
|
||||
|
||||
<label text="@.y" />
|
||||
<expr id="y" text="0" />
|
||||
<label text="@.x" />
|
||||
<expr id="x" text="0" />
|
||||
|
||||
<label text="@.width" />
|
||||
<expr id="width" text="16" />
|
||||
<label text="@.y" />
|
||||
<expr id="y" text="0" />
|
||||
|
||||
<label text="@.height" />
|
||||
<expr id="height" text="16" />
|
||||
<label text="@.width" />
|
||||
<expr id="width" text="16" />
|
||||
|
||||
<check id="partial_tiles" text="@.partial_tiles" cell_hspan="4" />
|
||||
<label text="@.height" />
|
||||
<expr id="height" text="16" />
|
||||
|
||||
<hbox cell_hspan="4">
|
||||
<boxfiller />
|
||||
<hbox>
|
||||
</hbox>
|
||||
<button id="import" text="@.import" minwidth="60" magnet="true" cell_align="center" closewindow="true" />
|
||||
<button id="cancel" text="@.cancel" minwidth="60" cell_align="center" closewindow="true" />
|
||||
</hbox>
|
||||
</grid>
|
||||
<separator text="Padding:" horizontal="true" cell_hspan="4" />
|
||||
|
||||
<label text="@.horizontal_padding" />
|
||||
<expr id="horizontal_padding" text="0" />
|
||||
<label text="" cell_hspan="2" />
|
||||
|
||||
<label text="@.vertical_padding" />
|
||||
<expr id="vertical_padding" text="0" />
|
||||
<label text="" cell_hspan="2" />
|
||||
|
||||
<check id="partial_tiles" text="@.partial_tiles" cell_hspan="4" />
|
||||
|
||||
<hbox cell_hspan="4">
|
||||
<boxfiller />
|
||||
<hbox>
|
||||
</hbox>
|
||||
<button id="import" text="@.import" minwidth="60" magnet="true" cell_align="center" closewindow="true" />
|
||||
<button id="cancel" text="@.cancel" minwidth="60" cell_align="center" closewindow="true" />
|
||||
</hbox>
|
||||
</grid>
|
||||
</vbox>
|
||||
</window>
|
||||
</gui>
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -73,6 +74,9 @@ public:
|
||||
y()->Change.connect(base::Bind<void>(&ImportSpriteSheetWindow::onEntriesChange, this));
|
||||
width()->Change.connect(base::Bind<void>(&ImportSpriteSheetWindow::onEntriesChange, this));
|
||||
height()->Change.connect(base::Bind<void>(&ImportSpriteSheetWindow::onEntriesChange, this));
|
||||
horizontalPadding()->Change.connect(base::Bind<void>(&ImportSpriteSheetWindow::onEntriesChange, this));
|
||||
verticalPadding()->Change.connect(base::Bind<void>(&ImportSpriteSheetWindow::onEntriesChange, this));
|
||||
partialTiles()->Click.connect(base::Bind<void>(&ImportSpriteSheetWindow::onEntriesChange, this));
|
||||
selectFile()->Click.connect(base::Bind<void>(&ImportSpriteSheetWindow::onSelectFile, this));
|
||||
|
||||
remapWindow();
|
||||
@ -113,6 +117,10 @@ public:
|
||||
return m_rect;
|
||||
}
|
||||
|
||||
gfx::Size paddingThickness() const {
|
||||
return m_padding;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void onSheetTypeChange() {
|
||||
@ -144,16 +152,31 @@ protected:
|
||||
std::max<int>(1, h));
|
||||
}
|
||||
|
||||
gfx::Size getPaddingFromEntries() {
|
||||
int padW = horizontalPadding()->textInt();
|
||||
int padH = verticalPadding()->textInt();
|
||||
if (padW < 0)
|
||||
padW = 0;
|
||||
if (padH < 0)
|
||||
padH = 0;
|
||||
return gfx::Size(padW, padH);
|
||||
}
|
||||
|
||||
void onEntriesChange() {
|
||||
m_rect = getRectFromEntries();
|
||||
m_padding = getPaddingFromEntries();
|
||||
|
||||
// Redraw new rulers position
|
||||
if (m_editor) {
|
||||
EditorStatePtr state = m_editor->getState();
|
||||
if (SelectBoxState* boxState = dynamic_cast<SelectBoxState*>(state.get())) {
|
||||
boxState->setBoxBounds(m_rect);
|
||||
m_editor->invalidate();
|
||||
}
|
||||
SelectBoxState* boxState = dynamic_cast<SelectBoxState*>(state.get());
|
||||
boxState->setBoxBounds(m_rect);
|
||||
boxState->setPaddingBounds(m_padding);
|
||||
if (partialTilesValue())
|
||||
boxState->setFlag(SelectBoxState::Flags::IncludePartialTiles);
|
||||
else
|
||||
boxState->clearFlag(SelectBoxState::Flags::IncludePartialTiles);
|
||||
m_editor->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,6 +207,16 @@ protected:
|
||||
height()->setTextf("%d", m_rect.h);
|
||||
}
|
||||
|
||||
void onChangePadding(const gfx::Size& padding) override {
|
||||
m_padding = padding;
|
||||
if (padding.w < 0)
|
||||
m_padding.w = 0;
|
||||
if (padding.h < 0)
|
||||
m_padding.h = 0;
|
||||
horizontalPadding()->setTextf("%d", m_padding.w);
|
||||
verticalPadding()->setTextf("%d", m_padding.h);
|
||||
}
|
||||
|
||||
std::string onGetContextBarHelp() override {
|
||||
return "Select bounds to identify sprite frames";
|
||||
}
|
||||
@ -218,9 +251,11 @@ private:
|
||||
sheetType()->setSelectedItemIndex((int)app::SpriteSheetType::Rows-1);
|
||||
|
||||
gfx::Rect defBounds = m_docPref->importSpriteSheet.bounds();
|
||||
gfx::Size defPaddingBounds = m_docPref->importSpriteSheet.paddingBounds();
|
||||
if (defBounds.isEmpty())
|
||||
defBounds = m_docPref->grid.bounds();
|
||||
onChangeRectangle(defBounds);
|
||||
onChangePadding(defPaddingBounds);
|
||||
|
||||
partialTiles()->setSelected(m_docPref->importSpriteSheet.partialTiles());
|
||||
onEntriesChange();
|
||||
@ -232,13 +267,17 @@ private:
|
||||
|
||||
if (m_document && !m_editor) {
|
||||
m_rect = getRectFromEntries();
|
||||
m_padding = getPaddingFromEntries();
|
||||
m_editor = current_editor;
|
||||
m_editorState.reset(
|
||||
new SelectBoxState(
|
||||
this, m_rect,
|
||||
SelectBoxState::Flags(
|
||||
int(SelectBoxState::Flags::Rulers) |
|
||||
int(SelectBoxState::Flags::Grid))));
|
||||
int(SelectBoxState::Flags::Grid) |
|
||||
int(SelectBoxState::Flags::DarkOutside) |
|
||||
int(SelectBoxState::Flags::PaddingRulers)
|
||||
)));
|
||||
|
||||
m_editor->setState(m_editorState);
|
||||
updateGridState();
|
||||
@ -249,7 +288,8 @@ private:
|
||||
if (!m_editorState)
|
||||
return;
|
||||
|
||||
int flags = int(SelectBoxState::Flags::Rulers);
|
||||
int flags = (int)static_cast<SelectBoxState*>(m_editorState.get())->getFlags();
|
||||
flags = flags & ~((int)SelectBoxState::Flags::HGrid | (int)SelectBoxState::Flags::VGrid);
|
||||
switch (sheetTypeValue()) {
|
||||
case SpriteSheetType::Horizontal:
|
||||
flags |= int(SelectBoxState::Flags::HGrid);
|
||||
@ -279,6 +319,7 @@ private:
|
||||
Editor* m_editor;
|
||||
EditorStatePtr m_editorState;
|
||||
gfx::Rect m_rect;
|
||||
gfx::Size m_padding;
|
||||
|
||||
// True if the user has been opened the file (instead of selecting
|
||||
// the current document).
|
||||
@ -311,6 +352,7 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
|
||||
Doc* document = window.document();
|
||||
DocumentPreferences* docPref = window.docPref();
|
||||
gfx::Rect frameBounds = window.frameBounds();
|
||||
gfx::Size padThickness = window.paddingThickness();
|
||||
bool partialTiles = window.partialTilesValue();
|
||||
auto sheetType = window.sheetTypeValue();
|
||||
|
||||
@ -337,25 +379,25 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
|
||||
|
||||
switch (sheetType) {
|
||||
case app::SpriteSheetType::Horizontal:
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x += frameBounds.w) {
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) {
|
||||
tileRects.push_back(gfx::Rect(x, frameBounds.y, frameBounds.w, frameBounds.h));
|
||||
}
|
||||
break;
|
||||
case app::SpriteSheetType::Vertical:
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y += frameBounds.h) {
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) {
|
||||
tileRects.push_back(gfx::Rect(frameBounds.x, y, frameBounds.w, frameBounds.h));
|
||||
}
|
||||
break;
|
||||
case app::SpriteSheetType::Rows:
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y += frameBounds.h) {
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x += frameBounds.w) {
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) {
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) {
|
||||
tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case app::SpriteSheetType::Columns:
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=sprite->width(); x += frameBounds.w) {
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=sprite->height(); y += frameBounds.h) {
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) {
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) {
|
||||
tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h));
|
||||
}
|
||||
}
|
||||
@ -422,6 +464,7 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
|
||||
docPref->importSpriteSheet.type(sheetType);
|
||||
docPref->importSpriteSheet.bounds(frameBounds);
|
||||
docPref->importSpriteSheet.partialTiles(partialTiles);
|
||||
docPref->importSpriteSheet.paddingBounds(padThickness);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -29,12 +30,16 @@ using namespace ui;
|
||||
|
||||
SelectBoxState::SelectBoxState(SelectBoxDelegate* delegate, const gfx::Rect& rc, Flags flags)
|
||||
: m_delegate(delegate)
|
||||
, m_rulers(4)
|
||||
, m_rulers((int(flags) & int(Flags::PaddingRulers))? 6: 4)
|
||||
, m_rulersDragAlign(0)
|
||||
, m_selectingBox(false)
|
||||
, m_flags(flags)
|
||||
{
|
||||
setBoxBounds(rc);
|
||||
if (hasFlag(Flags::PaddingRulers)) {
|
||||
gfx::Size padding(0, 0);
|
||||
setPaddingBounds(padding);
|
||||
}
|
||||
}
|
||||
|
||||
SelectBoxState::~SelectBoxState()
|
||||
@ -43,18 +48,33 @@ SelectBoxState::~SelectBoxState()
|
||||
contextBar->updateForActiveTool();
|
||||
}
|
||||
|
||||
SelectBoxState::Flags SelectBoxState::getFlags()
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
void SelectBoxState::setFlags(Flags flags)
|
||||
{
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
void SelectBoxState::setFlag(Flags flag)
|
||||
{
|
||||
m_flags = Flags(int(flag) | int(m_flags));
|
||||
}
|
||||
|
||||
void SelectBoxState::clearFlag(Flags flag)
|
||||
{
|
||||
m_flags = Flags(~(int(flag)) & int(m_flags));
|
||||
}
|
||||
|
||||
gfx::Rect SelectBoxState::getBoxBounds() const
|
||||
{
|
||||
int x1 = std::min(m_rulers[V1].position(), m_rulers[V2].position());
|
||||
int y1 = std::min(m_rulers[H1].position(), m_rulers[H2].position());
|
||||
int x2 = std::max(m_rulers[V1].position(), m_rulers[V2].position());
|
||||
int y2 = std::max(m_rulers[H1].position(), m_rulers[H2].position());
|
||||
return gfx::Rect(x1, y1, x2 - x1, y2 - y1);
|
||||
return gfx::Rect(x1, y1, x2-x1, y2-y1);
|
||||
}
|
||||
|
||||
void SelectBoxState::setBoxBounds(const gfx::Rect& box)
|
||||
@ -65,6 +85,26 @@ void SelectBoxState::setBoxBounds(const gfx::Rect& box)
|
||||
m_rulers[V2] = Ruler(Ruler::Vertical, box.x+box.w);
|
||||
}
|
||||
|
||||
// Get and Set Padding for Import Sprite Sheet box state
|
||||
gfx::Size SelectBoxState::getPaddingBounds() const
|
||||
{
|
||||
ASSERT(hasFlag(Flags::PaddingRulers));
|
||||
int w = m_rulers[PV].position() - m_rulers[V2].position();
|
||||
int h = m_rulers[PH].position() - m_rulers[H2].position();
|
||||
if (w < 0)
|
||||
w = 0;
|
||||
if (h < 0)
|
||||
h = 0;
|
||||
return gfx::Size(w, h);
|
||||
}
|
||||
|
||||
void SelectBoxState::setPaddingBounds(const gfx::Size& padding)
|
||||
{
|
||||
ASSERT(hasFlag(Flags::PaddingRulers));
|
||||
m_rulers[PH] = Ruler(Ruler::Horizontal, m_rulers[H2].position() + padding.h);
|
||||
m_rulers[PV] = Ruler(Ruler::Vertical, m_rulers[V2].position() + padding.w);
|
||||
}
|
||||
|
||||
void SelectBoxState::onEnterState(Editor* editor)
|
||||
{
|
||||
StandbyState::onEnterState(editor);
|
||||
@ -178,8 +218,11 @@ bool SelectBoxState::onMouseMove(Editor* editor, MouseMessage* msg)
|
||||
}
|
||||
|
||||
if (used) {
|
||||
if (m_delegate)
|
||||
if (m_delegate) {
|
||||
m_delegate->onChangeRectangle(getBoxBounds());
|
||||
if (hasFlag(Flags::PaddingRulers))
|
||||
m_delegate->onChangePadding(getPaddingBounds());
|
||||
}
|
||||
|
||||
editor->invalidate();
|
||||
return true;
|
||||
@ -250,47 +293,220 @@ void SelectBoxState::postRenderDecorator(EditorPostRender* render)
|
||||
const gfx::Color gridColor = skin::SkinTheme::instance()->colors.selectBoxGrid();
|
||||
const gfx::Point mainOffset = editor->mainTilePosition();
|
||||
gfx::Rect rc = getBoxBounds();
|
||||
gfx::Size padding;
|
||||
if (hasFlag(Flags::PaddingRulers))
|
||||
padding = getPaddingBounds();
|
||||
rc.offset(mainOffset);
|
||||
sp.offset(mainOffset);
|
||||
|
||||
// With black shadow?
|
||||
if (hasFlag(Flags::DarkOutside)) {
|
||||
const gfx::Color dark = doc::rgba(0, 0, 0, 128);
|
||||
// Top band
|
||||
if (rc.y > vp.y)
|
||||
render->fillRect(dark, gfx::Rect(vp.x, vp.y, vp.w, rc.y-vp.y));
|
||||
// Bottom band
|
||||
if (rc.y2() < vp.y2())
|
||||
render->fillRect(dark, gfx::Rect(vp.x, rc.y2(), vp.w, vp.y2()-rc.y2()));
|
||||
// Left band
|
||||
if (rc.x > vp.x)
|
||||
render->fillRect(dark, gfx::Rect(vp.x, rc.y, rc.x-vp.x, rc.h));
|
||||
// Right band
|
||||
if (rc.x2() < vp.x2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x2(), rc.y, vp.x2()-rc.x2(), rc.h));
|
||||
}
|
||||
if (hasFlag(Flags::PaddingRulers)) {
|
||||
const gfx::Color dark = doc::rgba(0, 0, 0, 128);
|
||||
// Top band
|
||||
if (rc.y > vp.y)
|
||||
render->fillRect(dark, gfx::Rect(vp.x, vp.y, vp.w, rc.y-vp.y));
|
||||
// Left band
|
||||
if (rc.x > vp.x)
|
||||
render->fillRect(dark, gfx::Rect(vp.x, rc.y, rc.x-vp.x, vp.y2()-rc.y));
|
||||
if (hasFlag(Flags::VGrid)) {
|
||||
// Bottom band
|
||||
if (sp.y2() < vp.y2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x, sp.y2(), vp.x2()-rc.x, vp.y2()-sp.y2()));
|
||||
// Right band
|
||||
if (hasFlag(Flags::HGrid)) {
|
||||
// VGrid Active, HGrid Active:
|
||||
if (sp.x2() < vp.x2())
|
||||
render->fillRect(dark, gfx::Rect(sp.x2(), rc.y, vp.x2()-sp.x2(), sp.y2()-rc.y));
|
||||
}
|
||||
else {
|
||||
// Just VGrid Active, HGrid disabled:
|
||||
if (rc.x2() < vp.x2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x2(), rc.y, vp.x2()-rc.x2(), sp.y2()-rc.y));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (hasFlag(Flags::HGrid)) {
|
||||
// Just HGrid Active, VGrid disabled
|
||||
// Bottom band
|
||||
if (rc.y2() < vp.y2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x, rc.y2(), vp.x2()-rc.x, vp.y2()-rc.y2()));
|
||||
// Right band
|
||||
if (sp.x2() < vp.x2())
|
||||
render->fillRect(dark, gfx::Rect(sp.x2(), rc.y, vp.x2()-sp.x2(), rc.h));
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFlag(Flags::Grid)) {
|
||||
if (rc.w > 0) {
|
||||
for (int x=rc.x+rc.w*2; x<=sp.x+sp.w; x+=rc.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, sp.y+sp.h);
|
||||
// Draw vertical dark padding big bands
|
||||
if (hasFlag(Flags::VGrid) && hasFlag(Flags::HGrid)) {
|
||||
std::vector<int> padXTips;
|
||||
std::vector<int> padYTips;
|
||||
if (rc.w > 0) {
|
||||
for (int x=rc.x+rc.w; x<=sp.x+sp.w; x+=(rc.w+padding.w)) {
|
||||
if (x + padding.w > sp.x2())
|
||||
render->fillRect(dark, gfx::Rect(x, rc.y, sp.x2()-x, sp.h-rc.y));
|
||||
else
|
||||
render->fillRect(dark, gfx::Rect(x, rc.y, padding.w, sp.h-rc.y));
|
||||
padXTips.push_back(x);
|
||||
}
|
||||
}
|
||||
if (rc.h > 0) {
|
||||
// Draw horizontal dark chopped padding bands (to complete the dark grid)
|
||||
for (int y=rc.y+rc.h; y<=sp.y+sp.h; y+=(rc.h+padding.h)) {
|
||||
for (const int& padXTip : padXTips) {
|
||||
if (y+padding.h > sp.y2())
|
||||
render->fillRect(dark, gfx::Rect(padXTip-rc.w, y, rc.w, sp.y2()-y));
|
||||
else
|
||||
render->fillRect(dark, gfx::Rect(padXTip-rc.w, y, rc.w, padding.h));
|
||||
}
|
||||
if (!padXTips.empty()) {
|
||||
if (padXTips.back() + padding.w < sp.x2()) {
|
||||
if (y + padding.h > sp.y2())
|
||||
render->fillRect(dark, gfx::Rect(padXTips.back() + padding.w, y,
|
||||
sp.x2() - padXTips.back() - padding.w,
|
||||
sp.y2() - y));
|
||||
else
|
||||
render->fillRect(dark, gfx::Rect(padXTips.back() + padding.w, y,
|
||||
sp.x2() - padXTips.back() - padding.w,
|
||||
padding.h));
|
||||
}
|
||||
}
|
||||
padYTips.push_back(y);
|
||||
}
|
||||
}
|
||||
// Draw chopped dark rectangles to ban partial tiles
|
||||
if (!hasFlag(Flags::IncludePartialTiles)) {
|
||||
if (!padXTips.empty() && !padYTips.empty()) {
|
||||
if (padXTips.back() + padding.w < sp.x2()) {
|
||||
for (const int& padYTip : padYTips)
|
||||
render->fillRect(dark, gfx::Rect(padXTips.back() + padding.w, padYTip - rc.h,
|
||||
sp.x2() - padXTips.back() - padding.w, rc.h));
|
||||
if (padYTips.back() + padding.h < sp.y2()) {
|
||||
render->fillRect(dark, gfx::Rect(padXTips.back() + padding.w,
|
||||
padYTips.back() + padding.h,
|
||||
sp.x2() - padXTips.back() - padding.w,
|
||||
sp.y2() - padYTips.back() - padding.h));
|
||||
}
|
||||
}
|
||||
if (padYTips.back() + padding.h < sp.y2()) {
|
||||
for (const int& padXTip : padXTips)
|
||||
render->fillRect(dark, gfx::Rect(padXTip - rc.w, padYTips.back() + padding.h,
|
||||
rc.w, sp.y2() - padYTips.back() - padding.h));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::HGrid)) {
|
||||
if (rc.w > 0) {
|
||||
int lastX = 0;
|
||||
for (int x=rc.x+rc.w; x<=sp.x+sp.w; x+=rc.w+padding.w) {
|
||||
if (x + padding.w > sp.x2())
|
||||
render->fillRect(dark, gfx::Rect(x, rc.y, sp.x2()-x, rc.h));
|
||||
else
|
||||
render->fillRect(dark, gfx::Rect(x, rc.y, padding.w, rc.h));
|
||||
lastX = x;
|
||||
}
|
||||
if (!hasFlag(Flags::IncludePartialTiles) && (lastX > 0)) {
|
||||
if (lastX + padding.w < sp.x2())
|
||||
render->fillRect(dark, gfx::Rect(lastX + padding.w, rc.y,
|
||||
sp.x2() - lastX - padding.w, rc.h));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::VGrid)) {
|
||||
if (rc.h > 0) {
|
||||
int lastY = 0;
|
||||
for (int y=rc.y+rc.h; y<=sp.y+sp.h; y+=rc.h+padding.h) {
|
||||
if (y + padding.h > sp.y2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x, y, rc.w, sp.y2()-y));
|
||||
else
|
||||
render->fillRect(dark, gfx::Rect(rc.x, y, rc.w, padding.h));
|
||||
lastY = y;
|
||||
}
|
||||
if (!hasFlag(Flags::IncludePartialTiles) && (lastY > 0)) {
|
||||
if (lastY + padding.h < sp.y2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x, lastY + padding.h,
|
||||
rc.w, sp.y2() - lastY - padding.h));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Draw dark zones when SelectBoxState is a simple box
|
||||
const gfx::Color dark = doc::rgba(0, 0, 0, 128);
|
||||
// Top band
|
||||
if (rc.y > vp.y)
|
||||
render->fillRect(dark, gfx::Rect(vp.x, vp.y, vp.w, rc.y-vp.y));
|
||||
// Bottom band
|
||||
if (rc.y2() < vp.y2())
|
||||
render->fillRect(dark, gfx::Rect(vp.x, rc.y2(), vp.w, vp.y2()-rc.y2()));
|
||||
// Left band
|
||||
if (rc.x > vp.x)
|
||||
render->fillRect(dark, gfx::Rect(vp.x, rc.y, rc.x-vp.x, rc.h));
|
||||
// Right band
|
||||
if (rc.x2() < vp.x2())
|
||||
render->fillRect(dark, gfx::Rect(rc.x2(), rc.y, vp.x2()-rc.x2(), rc.h));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the grid rulers when padding is posible (i.e. Flag::PaddingRulers=true)
|
||||
if (hasFlag(Flags::PaddingRulers)) {
|
||||
if (hasFlag(Flags::HGrid) && hasFlag(Flags::VGrid)) {
|
||||
if (rc.w > 0 && padding.w == 0) {
|
||||
for (int x=rc.x+rc.w*2+padding.w; x<=sp.x+sp.w; x+=rc.w+padding.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, sp.y2());
|
||||
for (int x=rc.x+rc.w+padding.w; x<=sp.x+sp.w; x+=rc.w+padding.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, sp.y2());
|
||||
}
|
||||
|
||||
if (rc.h > 0) {
|
||||
for (int y=rc.y+rc.h*2; y<=sp.y+sp.h; y+=rc.h)
|
||||
render->drawLine(gridColor, rc.x, y, sp.x+sp.w, y);
|
||||
if (rc.h > 0 && padding.h == 0) {
|
||||
for (int y=rc.y+rc.h*2+padding.h; y<=sp.y+sp.h; y+=rc.h+padding.h)
|
||||
render->drawLine(gridColor, rc.x, y, sp.x2(), y);
|
||||
for (int y=rc.y+rc.h+padding.h; y<=sp.y+sp.h; y+=rc.h+padding.h)
|
||||
render->drawLine(gridColor, rc.x, y, sp.x2(), y);
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::HGrid)) {
|
||||
if (rc.w > 0 && padding.w == 0) {
|
||||
for (int x=rc.x+rc.w*2+padding.w; x<=sp.x+sp.w; x+=rc.w+padding.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, rc.y2());
|
||||
for (int x=rc.x+rc.w+padding.w; x<=sp.x+sp.w; x+=rc.w+padding.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, rc.y2());
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::VGrid)) {
|
||||
if (rc.h > 0 && padding.h == 0) {
|
||||
for (int y=rc.y+rc.h*2+padding.h; y<=sp.y+sp.h; y+=rc.h+padding.h)
|
||||
render->drawLine(gridColor, rc.x, y, rc.x2(), y);
|
||||
for (int y=rc.y+rc.h+padding.h; y<=sp.y+sp.h; y+=rc.h+padding.h)
|
||||
render->drawLine(gridColor, rc.x, y, rc.x2(), y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::HGrid)) {
|
||||
if (rc.w > 0) {
|
||||
for (int x=rc.x+rc.w*2; x<=sp.x+sp.w; x+=rc.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, rc.y+rc.h);
|
||||
else {
|
||||
// Draw the grid rulers when padding is not posible (i.e. Flag::PaddingRulers=false)
|
||||
if (hasFlag(Flags::Grid)) {
|
||||
if (rc.w > 0) {
|
||||
for (int x=rc.x+rc.w*2; x<=sp.x+sp.w; x+=rc.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, sp.y+sp.h);
|
||||
}
|
||||
|
||||
if (rc.h > 0) {
|
||||
for (int y=rc.y+rc.h*2; y<=sp.y+sp.h; y+=rc.h)
|
||||
render->drawLine(gridColor, rc.x, y, sp.x+sp.w, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::VGrid)) {
|
||||
if (rc.h > 0) {
|
||||
for (int y=rc.y+rc.h*2; y<=sp.y+sp.h; y+=rc.h)
|
||||
render->drawLine(gridColor, rc.x, y, rc.x+rc.w, y);
|
||||
else if (hasFlag(Flags::HGrid)) {
|
||||
if (rc.w > 0) {
|
||||
for (int x=rc.x+rc.w*2; x<=sp.x+sp.w; x+=rc.w)
|
||||
render->drawLine(gridColor, x, rc.y, x, rc.y+rc.h);
|
||||
}
|
||||
}
|
||||
else if (hasFlag(Flags::VGrid)) {
|
||||
if (rc.h > 0) {
|
||||
for (int y=rc.y+rc.h*2; y<=sp.y+sp.h; y+=rc.h)
|
||||
render->drawLine(gridColor, rc.x, y, rc.x+rc.w, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,7 +554,7 @@ int SelectBoxState::hitTestRulers(Editor* editor,
|
||||
ASSERT(H2 == 1);
|
||||
ASSERT(V1 == 2);
|
||||
ASSERT(V2 == 3);
|
||||
int aligns[] = { TOP, BOTTOM, LEFT, RIGHT };
|
||||
int aligns[] = { TOP, BOTTOM, LEFT, RIGHT, BOTTOM, RIGHT };
|
||||
int align = 0;
|
||||
|
||||
if (updateMovingRulers)
|
||||
@ -360,7 +576,7 @@ int SelectBoxState::hitTestRulers(Editor* editor,
|
||||
align = LEFT | TOP | RIGHT | BOTTOM;
|
||||
if (updateMovingRulers) {
|
||||
// Add all rulers
|
||||
for (int i=0; i<4; ++i)
|
||||
for (int i=0; i<m_rulers.size(); ++i)
|
||||
m_movingRulers.push_back(i);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -11,6 +12,7 @@
|
||||
#include "app/ui/editor/editor_decorator.h"
|
||||
#include "app/ui/editor/ruler.h"
|
||||
#include "app/ui/editor/standby_state.h"
|
||||
#include "gfx/fwd.h"
|
||||
#include "ui/cursor_type.h"
|
||||
#include "ui/mouse_buttons.h"
|
||||
|
||||
@ -26,6 +28,7 @@ namespace app {
|
||||
// Called each time the selected box is modified (e.g. rulers are
|
||||
// moved).
|
||||
virtual void onChangeRectangle(const gfx::Rect& rect) { }
|
||||
virtual void onChangePadding(const gfx::Size& padding) { }
|
||||
|
||||
// Called only in QUICKBOX mode, when the user released the mouse
|
||||
// button.
|
||||
@ -38,7 +41,7 @@ namespace app {
|
||||
|
||||
class SelectBoxState : public StandbyState
|
||||
, public EditorDecorator {
|
||||
enum { H1, H2, V1, V2 };
|
||||
enum { H1, H2, V1, V2, PH, PV };
|
||||
|
||||
public:
|
||||
enum class Flags {
|
||||
@ -59,6 +62,12 @@ namespace app {
|
||||
|
||||
// Select the box as in selection tool, drawing a boxu
|
||||
QuickBox = 16,
|
||||
|
||||
// Adding 2 rules more for padding. Used in Import Sprite Sheet render
|
||||
PaddingRulers = 32,
|
||||
|
||||
// Include Partial Tiles at the end of the sprite? Used in Import Sprite Sheet render
|
||||
IncludePartialTiles = 64
|
||||
};
|
||||
|
||||
SelectBoxState(SelectBoxDelegate* delegate,
|
||||
@ -66,12 +75,19 @@ namespace app {
|
||||
Flags flags);
|
||||
~SelectBoxState();
|
||||
|
||||
Flags getFlags();
|
||||
void setFlags(Flags flags);
|
||||
void setFlag(Flags flag);
|
||||
void clearFlag(Flags flag);
|
||||
|
||||
// Returns the bounding box arranged by the rulers.
|
||||
gfx::Rect getBoxBounds() const;
|
||||
void setBoxBounds(const gfx::Rect& rc);
|
||||
|
||||
// Get & Set the size of the padding rulers during Import Sprite Sheet Dialog
|
||||
gfx::Size getPaddingBounds() const;
|
||||
void setPaddingBounds(const gfx::Size& padding);
|
||||
|
||||
// EditorState overrides
|
||||
virtual void onEnterState(Editor* editor) override;
|
||||
virtual void onBeforePopState(Editor* editor) override;
|
||||
|
Loading…
Reference in New Issue
Block a user