mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +00:00
Add UI to drag and drop colors in PaletteView
This commit is contained in:
parent
26970832ac
commit
d41b08caa8
@ -51,6 +51,7 @@ WidgetType palette_view_type()
|
|||||||
|
|
||||||
PaletteView::PaletteView(bool editable)
|
PaletteView::PaletteView(bool editable)
|
||||||
: Widget(palette_view_type())
|
: Widget(palette_view_type())
|
||||||
|
, m_state(State::WAITING)
|
||||||
, m_editable(editable)
|
, m_editable(editable)
|
||||||
, m_columns(16)
|
, m_columns(16)
|
||||||
, m_boxsize(7*guiscale())
|
, m_boxsize(7*guiscale())
|
||||||
@ -172,29 +173,42 @@ bool PaletteView::onProcessMessage(Message* msg)
|
|||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
|
|
||||||
case kMouseDownMessage:
|
case kMouseDownMessage:
|
||||||
|
switch (m_hot.part) {
|
||||||
|
case Hit::COLOR:
|
||||||
|
m_state = State::SELECTING_COLOR;
|
||||||
|
break;
|
||||||
|
case Hit::OUTLINE:
|
||||||
|
m_state = State::DRAGGING_OUTLINE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
captureMouse();
|
captureMouse();
|
||||||
|
|
||||||
// Continue...
|
// Continue...
|
||||||
|
|
||||||
case kMouseMoveMessage: {
|
case kMouseMoveMessage: {
|
||||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||||
|
|
||||||
if (m_hot.part == Hit::COLOR) {
|
if (m_state == State::SELECTING_COLOR) {
|
||||||
int idx = m_hot.color;
|
if (m_hot.part == Hit::COLOR) {
|
||||||
|
int idx = m_hot.color;
|
||||||
|
|
||||||
StatusBar::instance()->showColor(0, "",
|
StatusBar::instance()->showColor(0, "",
|
||||||
app::Color::fromIndex(idx), 255);
|
app::Color::fromIndex(idx), 255);
|
||||||
|
|
||||||
if (hasCapture() && idx != m_currentEntry) {
|
if (hasCapture() && idx != m_currentEntry) {
|
||||||
clearSelection();
|
if (!msg->ctrlPressed())
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
if (msg->type() == kMouseMoveMessage)
|
if (msg->type() == kMouseMoveMessage)
|
||||||
selectRange(m_rangeAnchor, idx);
|
selectRange(m_rangeAnchor, idx);
|
||||||
else
|
else
|
||||||
selectColor(idx);
|
selectColor(idx);
|
||||||
|
|
||||||
// Emit signal
|
// Emit signal
|
||||||
PaletteIndexChangeEvent ev(this, idx, mouseMsg->buttons());
|
PaletteIndexChangeEvent ev(this, idx, mouseMsg->buttons());
|
||||||
IndexChange(ev);
|
IndexChange(ev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,8 +219,12 @@ bool PaletteView::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case kMouseUpMessage:
|
case kMouseUpMessage:
|
||||||
if (hasCapture())
|
if (hasCapture()) {
|
||||||
releaseMouse();
|
releaseMouse();
|
||||||
|
|
||||||
|
m_state = State::WAITING;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case kMouseWheelMessage: {
|
case kMouseWheelMessage: {
|
||||||
@ -318,6 +336,23 @@ void PaletteView::onPaint(ui::PaintEvent& ev)
|
|||||||
NULL, state);
|
NULL, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw drop target
|
||||||
|
if (m_state == State::DRAGGING_OUTLINE) {
|
||||||
|
if (m_hot.part == Hit::COLOR) {
|
||||||
|
gfx::Rect box = getPaletteEntryBounds(m_hot.color);
|
||||||
|
if (m_hot.after)
|
||||||
|
box.x += box.w+guiscale();
|
||||||
|
|
||||||
|
box.x -= 3*guiscale();
|
||||||
|
box.y -= 3*guiscale();
|
||||||
|
box.w = 5*guiscale();
|
||||||
|
box.h += 6*guiscale();
|
||||||
|
|
||||||
|
theme->styles.timelineDropFrameDeco()->paint(g,
|
||||||
|
box, NULL, Style::active());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaletteView::onResize(ui::ResizeEvent& ev)
|
void PaletteView::onResize(ui::ResizeEvent& ev)
|
||||||
@ -415,7 +450,7 @@ PaletteView::Hit PaletteView::hitTest(const gfx::Point& pos)
|
|||||||
int outlineWidth = theme->dimensions.paletteOutlineWidth();
|
int outlineWidth = theme->dimensions.paletteOutlineWidth();
|
||||||
Palette* palette = get_current_palette();
|
Palette* palette = get_current_palette();
|
||||||
|
|
||||||
if (!hasCapture()) {
|
if (m_state == State::WAITING) {
|
||||||
// First check if the mouse is inside the selection outline.
|
// First check if the mouse is inside the selection outline.
|
||||||
for (int i=0; i<palette->size(); ++i) {
|
for (int i=0; i<palette->size(); ++i) {
|
||||||
if (!m_selectedEntries[i])
|
if (!m_selectedEntries[i])
|
||||||
@ -431,9 +466,9 @@ PaletteView::Hit PaletteView::hitTest(const gfx::Point& pos)
|
|||||||
box.enlarge(outlineWidth);
|
box.enlarge(outlineWidth);
|
||||||
|
|
||||||
if ((!top && gfx::Rect(box.x, box.y, box.w, outlineWidth).contains(pos)) ||
|
if ((!top && gfx::Rect(box.x, box.y, box.w, outlineWidth).contains(pos)) ||
|
||||||
(!bottom && gfx::Rect(box.x, box.y+box.h-outlineWidth, box.w, outlineWidth).contains(pos)) ||
|
(!bottom && gfx::Rect(box.x, box.y+box.h-outlineWidth, box.w, outlineWidth).contains(pos)) ||
|
||||||
(!left && gfx::Rect(box.x, box.y, outlineWidth, box.h).contains(pos)) ||
|
(!left && gfx::Rect(box.x, box.y, outlineWidth, box.h).contains(pos)) ||
|
||||||
(!right && gfx::Rect(box.x+box.w-outlineWidth, box.y, outlineWidth, box.h).contains(pos)))
|
(!right && gfx::Rect(box.x+box.w-outlineWidth, box.y, outlineWidth, box.h).contains(pos)))
|
||||||
return Hit(Hit::OUTLINE, i);
|
return Hit(Hit::OUTLINE, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,8 +478,11 @@ PaletteView::Hit PaletteView::hitTest(const gfx::Point& pos)
|
|||||||
gfx::Rect box = getPaletteEntryBounds(i);
|
gfx::Rect box = getPaletteEntryBounds(i);
|
||||||
box.w += child_spacing;
|
box.w += child_spacing;
|
||||||
box.h += child_spacing;
|
box.h += child_spacing;
|
||||||
if (box.contains(pos))
|
if (box.contains(pos)) {
|
||||||
return Hit(Hit::COLOR, i);
|
Hit hit(Hit::COLOR, i);
|
||||||
|
hit.after = (pos.x > box.x+box.w/2);
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Hit(Hit::NONE);
|
return Hit(Hit::NONE);
|
||||||
|
@ -64,23 +64,31 @@ namespace app {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
WAITING,
|
||||||
|
SELECTING_COLOR,
|
||||||
|
DRAGGING_OUTLINE,
|
||||||
|
};
|
||||||
|
|
||||||
struct Hit {
|
struct Hit {
|
||||||
enum Part {
|
enum Part {
|
||||||
NONE,
|
NONE,
|
||||||
COLOR,
|
COLOR,
|
||||||
OUTLINE
|
OUTLINE
|
||||||
};
|
};
|
||||||
|
|
||||||
Part part;
|
Part part;
|
||||||
int color;
|
int color;
|
||||||
|
bool after;
|
||||||
|
|
||||||
Hit(Part part, int color = -1) : part(part), color(color) {
|
Hit(Part part, int color = -1) : part(part), color(color), after(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Hit& hit) const {
|
bool operator==(const Hit& hit) const {
|
||||||
return (part == hit.part && color == hit.color);
|
return (
|
||||||
|
part == hit.part &&
|
||||||
|
color == hit.color &&
|
||||||
|
after == hit.after);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Hit& hit) const {
|
bool operator!=(const Hit& hit) const {
|
||||||
return !operator==(hit);
|
return !operator==(hit);
|
||||||
}
|
}
|
||||||
@ -92,6 +100,7 @@ namespace app {
|
|||||||
gfx::Rect getPaletteEntryBounds(int index);
|
gfx::Rect getPaletteEntryBounds(int index);
|
||||||
Hit hitTest(const gfx::Point& pos);
|
Hit hitTest(const gfx::Point& pos);
|
||||||
|
|
||||||
|
State m_state;
|
||||||
bool m_editable;
|
bool m_editable;
|
||||||
int m_columns;
|
int m_columns;
|
||||||
int m_boxsize;
|
int m_boxsize;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user