diff --git a/src/app/ui/palette_view.cpp b/src/app/ui/palette_view.cpp index b7dfa4ba8..0f096877a 100644 --- a/src/app/ui/palette_view.cpp +++ b/src/app/ui/palette_view.cpp @@ -68,6 +68,7 @@ PaletteView::PaletteView(bool editable, PaletteViewDelegate* delegate, int boxsi , m_clipboardEntries(Palette::MaxColors) , m_isUpdatingColumns(false) , m_hot(Hit::NONE) + , m_copy(false) , m_clipboardEditor(nullptr) { setFocusStop(true); @@ -253,9 +254,16 @@ bool PaletteView::onProcessMessage(Message* msg) return true; } } + + updateCopyFlag(msg); break; } + case kMouseEnterMessage: + case kKeyUpMessage: + updateCopyFlag(msg); + break; + case kMouseDownMessage: switch (m_hot.part) { @@ -350,10 +358,7 @@ bool PaletteView::onProcessMessage(Message* msg) m_hot = hit; invalidate(); } - if (m_hot.part == Hit::OUTLINE) - ui::set_mouse_cursor(kMoveCursor); - else - ui::set_mouse_cursor(kArrowCursor); + setCursor(); return true; } @@ -588,24 +593,55 @@ PaletteView::Hit PaletteView::hitTest(const gfx::Point& pos) void PaletteView::dropColors(int beforeIndex) { - Palette* palette = get_current_palette(); - Remap remap = Remap::moveSelectedEntriesTo(m_selectedEntries, beforeIndex); + Palette palette(*get_current_palette()); + Palette newPalette(palette); + Remap remap(palette.size()); - auto oldSelectedCopies = m_selectedEntries; - Palette oldPalCopy(*palette); - for (int i=0; isize(); ++i) { - palette->setEntry(remap[i], oldPalCopy.getEntry(i)); - m_selectedEntries[remap[i]] = oldSelectedCopies[i]; + // Copy colors + if (m_copy) { + int picks = m_selectedEntries.picks(); + remap = create_remap_to_expand_palette(palette.size(), picks, beforeIndex); + + for (int i=0; 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; ionPaletteViewRemapColors(remap, palette); + m_delegate->onPaletteViewRemapColors(remap, &newPalette); m_delegate->onPaletteViewIndexChange(m_currentEntry, ui::kButtonLeft); } - set_current_palette(palette, false); + set_current_palette(&newPalette, false); getManager()->invalidate(); } @@ -671,4 +707,25 @@ void PaletteView::setClipboardEditor(Editor* editor) 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 diff --git a/src/app/ui/palette_view.h b/src/app/ui/palette_view.h index 35c98ef19..272615f64 100644 --- a/src/app/ui/palette_view.h +++ b/src/app/ui/palette_view.h @@ -121,6 +121,8 @@ namespace app { int outlineWidth) const; bool pickedXY(const doc::PalettePicks& entries, int i, int dx, int dy) const; void setClipboardEditor(Editor* editor); + void updateCopyFlag(ui::Message* msg); + void setCursor(); State m_state; bool m_editable; @@ -134,6 +136,7 @@ namespace app { bool m_isUpdatingColumns; ScopedConnection m_conn; Hit m_hot; + bool m_copy; Editor* m_clipboardEditor; }; diff --git a/src/doc/remap.cpp b/src/doc/remap.cpp index 6ae5b7638..dd4266ee1 100644 --- a/src/doc/remap.cpp +++ b/src/doc/remap.cpp @@ -14,10 +14,7 @@ namespace doc { -// TODO this should be a non-member function, it's related to PalettePicks and Remap - -// static -Remap Remap::moveSelectedEntriesTo(const PalettePicks& picks, int beforeIndex) +Remap create_remap_to_move_picks(const PalettePicks& picks, int beforeIndex) { Remap map(picks.size()); @@ -48,6 +45,24 @@ Remap Remap::moveSelectedEntriesTo(const PalettePicks& picks, int beforeIndex) 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 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 #endif diff --git a/src/doc/remap_tests.cpp b/src/doc/remap_tests.cpp index 9353ed24a..e0f8b0f15 100644 --- a/src/doc/remap_tests.cpp +++ b/src/doc/remap_tests.cpp @@ -11,18 +11,19 @@ #include #include "doc/remap.h" +#include "doc/palette_picks.h" using namespace doc; -TEST(Remap, Basics) +TEST(Remap, RemapToMovePicks) { - std::vector entries(20); + PalettePicks entries(20); std::fill(entries.begin(), entries.end(), false); entries[6] = entries[7] = 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(4, map[1]); @@ -45,7 +46,7 @@ TEST(Remap, Basics) EXPECT_EQ(18, map[18]); 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(1, map[1]); @@ -69,6 +70,35 @@ TEST(Remap, Basics) 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) { ::testing::InitGoogleTest(&argc, argv);