mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 12:39:57 +00:00
Add ability to copy colors using Ctrl + drag & drop
This commit is contained in:
parent
cea0970d9d
commit
11d86bb7c5
@ -68,6 +68,7 @@ PaletteView::PaletteView(bool editable, PaletteViewDelegate* delegate, int boxsi
|
|||||||
, m_clipboardEntries(Palette::MaxColors)
|
, m_clipboardEntries(Palette::MaxColors)
|
||||||
, m_isUpdatingColumns(false)
|
, m_isUpdatingColumns(false)
|
||||||
, m_hot(Hit::NONE)
|
, m_hot(Hit::NONE)
|
||||||
|
, m_copy(false)
|
||||||
, m_clipboardEditor(nullptr)
|
, m_clipboardEditor(nullptr)
|
||||||
{
|
{
|
||||||
setFocusStop(true);
|
setFocusStop(true);
|
||||||
@ -253,9 +254,16 @@ bool PaletteView::onProcessMessage(Message* msg)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCopyFlag(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kMouseEnterMessage:
|
||||||
|
case kKeyUpMessage:
|
||||||
|
updateCopyFlag(msg);
|
||||||
|
break;
|
||||||
|
|
||||||
case kMouseDownMessage:
|
case kMouseDownMessage:
|
||||||
switch (m_hot.part) {
|
switch (m_hot.part) {
|
||||||
|
|
||||||
@ -350,10 +358,7 @@ bool PaletteView::onProcessMessage(Message* msg)
|
|||||||
m_hot = hit;
|
m_hot = hit;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
if (m_hot.part == Hit::OUTLINE)
|
setCursor();
|
||||||
ui::set_mouse_cursor(kMoveCursor);
|
|
||||||
else
|
|
||||||
ui::set_mouse_cursor(kArrowCursor);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,24 +593,55 @@ PaletteView::Hit PaletteView::hitTest(const gfx::Point& pos)
|
|||||||
|
|
||||||
void PaletteView::dropColors(int beforeIndex)
|
void PaletteView::dropColors(int beforeIndex)
|
||||||
{
|
{
|
||||||
Palette* palette = get_current_palette();
|
Palette palette(*get_current_palette());
|
||||||
Remap remap = Remap::moveSelectedEntriesTo(m_selectedEntries, beforeIndex);
|
Palette newPalette(palette);
|
||||||
|
Remap remap(palette.size());
|
||||||
|
|
||||||
auto oldSelectedCopies = m_selectedEntries;
|
// Copy colors
|
||||||
Palette oldPalCopy(*palette);
|
if (m_copy) {
|
||||||
for (int i=0; i<palette->size(); ++i) {
|
int picks = m_selectedEntries.picks();
|
||||||
palette->setEntry(remap[i], oldPalCopy.getEntry(i));
|
remap = create_remap_to_expand_palette(palette.size(), picks, beforeIndex);
|
||||||
m_selectedEntries[remap[i]] = oldSelectedCopies[i];
|
|
||||||
|
for (int i=0; i<palette.size(); ++i)
|
||||||
|
newPalette.setEntry(remap[i], palette.getEntry(i));
|
||||||
|
|
||||||
|
for (int i=0, j=0; i<palette.size(); ++i) {
|
||||||
|
if (m_selectedEntries[i])
|
||||||
|
newPalette.setEntry(beforeIndex + (j++), palette.getEntry(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0, j=0; i<palette.size(); ++i) {
|
||||||
|
if (m_selectedEntries[i]) {
|
||||||
|
if (m_currentEntry == i) {
|
||||||
|
m_currentEntry = beforeIndex + j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<palette.size(); ++i)
|
||||||
|
m_selectedEntries[i] = (i >= beforeIndex && i < beforeIndex + picks);
|
||||||
|
}
|
||||||
|
// Move colors
|
||||||
|
else {
|
||||||
|
remap = create_remap_to_move_picks(m_selectedEntries, beforeIndex);
|
||||||
|
|
||||||
|
auto oldSelectedCopies = m_selectedEntries;
|
||||||
|
for (int i=0; i<palette.size(); ++i) {
|
||||||
|
newPalette.setEntry(remap[i], palette.getEntry(i));
|
||||||
|
m_selectedEntries[remap[i]] = oldSelectedCopies[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentEntry = remap[m_currentEntry];
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentEntry = remap[m_currentEntry];
|
|
||||||
|
|
||||||
if (m_delegate) {
|
if (m_delegate) {
|
||||||
m_delegate->onPaletteViewRemapColors(remap, palette);
|
m_delegate->onPaletteViewRemapColors(remap, &newPalette);
|
||||||
m_delegate->onPaletteViewIndexChange(m_currentEntry, ui::kButtonLeft);
|
m_delegate->onPaletteViewIndexChange(m_currentEntry, ui::kButtonLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_current_palette(palette, false);
|
set_current_palette(&newPalette, false);
|
||||||
getManager()->invalidate();
|
getManager()->invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,4 +707,25 @@ void PaletteView::setClipboardEditor(Editor* editor)
|
|||||||
m_clipboardEditor->addObserver(this);
|
m_clipboardEditor->addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaletteView::updateCopyFlag(ui::Message* msg)
|
||||||
|
{
|
||||||
|
bool oldCopy = m_copy;
|
||||||
|
m_copy = (msg->ctrlPressed() || msg->altPressed());
|
||||||
|
if (oldCopy != m_copy)
|
||||||
|
setCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteView::setCursor()
|
||||||
|
{
|
||||||
|
if (m_state == State::DRAGGING_OUTLINE ||
|
||||||
|
m_hot.part == Hit::OUTLINE) {
|
||||||
|
if (m_copy)
|
||||||
|
ui::set_mouse_cursor(kArrowPlusCursor);
|
||||||
|
else
|
||||||
|
ui::set_mouse_cursor(kMoveCursor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ui::set_mouse_cursor(kArrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -121,6 +121,8 @@ namespace app {
|
|||||||
int outlineWidth) const;
|
int outlineWidth) const;
|
||||||
bool pickedXY(const doc::PalettePicks& entries, int i, int dx, int dy) const;
|
bool pickedXY(const doc::PalettePicks& entries, int i, int dx, int dy) const;
|
||||||
void setClipboardEditor(Editor* editor);
|
void setClipboardEditor(Editor* editor);
|
||||||
|
void updateCopyFlag(ui::Message* msg);
|
||||||
|
void setCursor();
|
||||||
|
|
||||||
State m_state;
|
State m_state;
|
||||||
bool m_editable;
|
bool m_editable;
|
||||||
@ -134,6 +136,7 @@ namespace app {
|
|||||||
bool m_isUpdatingColumns;
|
bool m_isUpdatingColumns;
|
||||||
ScopedConnection m_conn;
|
ScopedConnection m_conn;
|
||||||
Hit m_hot;
|
Hit m_hot;
|
||||||
|
bool m_copy;
|
||||||
Editor* m_clipboardEditor;
|
Editor* m_clipboardEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,10 +14,7 @@
|
|||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
|
|
||||||
// TODO this should be a non-member function, it's related to PalettePicks and Remap
|
Remap create_remap_to_move_picks(const PalettePicks& picks, int beforeIndex)
|
||||||
|
|
||||||
// static
|
|
||||||
Remap Remap::moveSelectedEntriesTo(const PalettePicks& picks, int beforeIndex)
|
|
||||||
{
|
{
|
||||||
Remap map(picks.size());
|
Remap map(picks.size());
|
||||||
|
|
||||||
@ -48,6 +45,24 @@ Remap Remap::moveSelectedEntriesTo(const PalettePicks& picks, int beforeIndex)
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Remap create_remap_to_expand_palette(int size, int count, int beforeIndex)
|
||||||
|
{
|
||||||
|
Remap map(size);
|
||||||
|
|
||||||
|
int j, k = 0;
|
||||||
|
for (int i=0; i<size; ++i) {
|
||||||
|
if (i < beforeIndex)
|
||||||
|
j = i;
|
||||||
|
else if (i + count < size)
|
||||||
|
j = i + count;
|
||||||
|
else
|
||||||
|
j = beforeIndex + (k++);
|
||||||
|
|
||||||
|
map.map(i, j);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
void Remap::merge(const Remap& other)
|
void Remap::merge(const Remap& other)
|
||||||
{
|
{
|
||||||
for (int i=0; i<size(); ++i) {
|
for (int i=0; i<size(); ++i) {
|
||||||
|
@ -18,11 +18,6 @@ namespace doc {
|
|||||||
public:
|
public:
|
||||||
Remap(int entries) : m_map(entries, 0) { }
|
Remap(int entries) : m_map(entries, 0) { }
|
||||||
|
|
||||||
// Creates a map to move a set of selected entries before the
|
|
||||||
// given index "beforeIndex".
|
|
||||||
static Remap moveSelectedEntriesTo(
|
|
||||||
const PalettePicks& picks, int beforeIndex);
|
|
||||||
|
|
||||||
int size() const {
|
int size() const {
|
||||||
return (int)m_map.size();
|
return (int)m_map.size();
|
||||||
}
|
}
|
||||||
@ -50,6 +45,12 @@ namespace doc {
|
|||||||
std::vector<int> m_map;
|
std::vector<int> m_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Creates a map to move a set of selected entries before the given
|
||||||
|
// index "beforeIndex".
|
||||||
|
Remap create_remap_to_move_picks(const PalettePicks& picks, int beforeIndex);
|
||||||
|
|
||||||
|
Remap create_remap_to_expand_palette(int size, int count, int beforeIndex);
|
||||||
|
|
||||||
} // namespace doc
|
} // namespace doc
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,18 +11,19 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include "doc/remap.h"
|
#include "doc/remap.h"
|
||||||
|
#include "doc/palette_picks.h"
|
||||||
|
|
||||||
using namespace doc;
|
using namespace doc;
|
||||||
|
|
||||||
TEST(Remap, Basics)
|
TEST(Remap, RemapToMovePicks)
|
||||||
{
|
{
|
||||||
std::vector<bool> entries(20);
|
PalettePicks entries(20);
|
||||||
std::fill(entries.begin(), entries.end(), false);
|
std::fill(entries.begin(), entries.end(), false);
|
||||||
entries[6] =
|
entries[6] =
|
||||||
entries[7] =
|
entries[7] =
|
||||||
entries[14] = true;
|
entries[14] = true;
|
||||||
|
|
||||||
Remap map = Remap::moveSelectedEntriesTo(entries, 1);
|
Remap map = create_remap_to_move_picks(entries, 1);
|
||||||
|
|
||||||
EXPECT_EQ(0, map[0]);
|
EXPECT_EQ(0, map[0]);
|
||||||
EXPECT_EQ(4, map[1]);
|
EXPECT_EQ(4, map[1]);
|
||||||
@ -45,7 +46,7 @@ TEST(Remap, Basics)
|
|||||||
EXPECT_EQ(18, map[18]);
|
EXPECT_EQ(18, map[18]);
|
||||||
EXPECT_EQ(19, map[19]);
|
EXPECT_EQ(19, map[19]);
|
||||||
|
|
||||||
map = Remap::moveSelectedEntriesTo(entries, 18);
|
map = create_remap_to_move_picks(entries, 18);
|
||||||
|
|
||||||
EXPECT_EQ(0, map[0]);
|
EXPECT_EQ(0, map[0]);
|
||||||
EXPECT_EQ(1, map[1]);
|
EXPECT_EQ(1, map[1]);
|
||||||
@ -69,6 +70,35 @@ TEST(Remap, Basics)
|
|||||||
EXPECT_EQ(19, map[19]);
|
EXPECT_EQ(19, map[19]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Remap, RemapToExpandPalette)
|
||||||
|
{
|
||||||
|
Remap map = create_remap_to_expand_palette(10, 3, 1);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, map[0]);
|
||||||
|
EXPECT_EQ(4, map[1]);
|
||||||
|
EXPECT_EQ(5, map[2]);
|
||||||
|
EXPECT_EQ(6, map[3]);
|
||||||
|
EXPECT_EQ(7, map[4]);
|
||||||
|
EXPECT_EQ(8, map[5]);
|
||||||
|
EXPECT_EQ(9, map[6]);
|
||||||
|
EXPECT_EQ(1, map[7]);
|
||||||
|
EXPECT_EQ(2, map[8]);
|
||||||
|
EXPECT_EQ(3, map[9]);
|
||||||
|
|
||||||
|
map = create_remap_to_expand_palette(10, 3, 8);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, map[0]);
|
||||||
|
EXPECT_EQ(1, map[1]);
|
||||||
|
EXPECT_EQ(2, map[2]);
|
||||||
|
EXPECT_EQ(3, map[3]);
|
||||||
|
EXPECT_EQ(4, map[4]);
|
||||||
|
EXPECT_EQ(5, map[5]);
|
||||||
|
EXPECT_EQ(6, map[6]);
|
||||||
|
EXPECT_EQ(7, map[7]);
|
||||||
|
EXPECT_EQ(8, map[8]);
|
||||||
|
EXPECT_EQ(9, map[9]);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user