Add UI feedback when dragging over the timeline

This commit is contained in:
Martín Capello 2024-09-06 09:32:14 -03:00
parent 65ec2bd7b7
commit 220254158f
3 changed files with 82 additions and 2 deletions

View File

@ -54,6 +54,8 @@
#include "fmt/format.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "os/event.h"
#include "os/event_queue.h"
#include "os/surface.h"
#include "os/system.h"
#include "text/font.h"
@ -257,7 +259,7 @@ Timeline::Timeline(TooltipManager* tooltipManager)
, m_fromTimeline(false)
, m_aniControls(tooltipManager)
{
enableFlags(CTRL_RIGHT_CLICK);
enableFlags(CTRL_RIGHT_CLICK | ALLOW_DROP);
m_ctxConn1 = m_context->BeforeCommandExecution.connect(
&Timeline::onBeforeCommandExecution, this);
@ -3538,7 +3540,7 @@ Timeline::Hit Timeline::hitTest(ui::Message* msg, const gfx::Point& mousePos)
else
hit.part = PART_NOTHING;
if (!hasCapture()) {
if (!hasCapture() && msg) {
gfx::Rect outline = getPartBounds(Hit(PART_RANGE_OUTLINE));
if (outline.contains(mousePos)) {
auto mouseMsg = dynamic_cast<MouseMessage*>(msg);
@ -4460,6 +4462,60 @@ void Timeline::onCancel(Context* ctx)
invalidate();
}
void Timeline::onDragEnter(ui::DragEvent& e)
{
m_state = STATE_MOVING_RANGE;
}
void Timeline::onDragLeave(ui::DragEvent& e)
{
m_state = STATE_STANDBY;
m_range.clearRange();
invalidate();
flushRedraw();
os::Event ev;
os::System::instance()->eventQueue()->queueEvent(ev);
}
void Timeline::onDrag(ui::DragEvent& e)
{
Widget::onDrag(e);
setHot(hitTest(nullptr, e.position()));
switch (m_hot.part) {
case PART_ROW:
case PART_ROW_EYE_ICON:
case PART_ROW_CONTINUOUS_ICON:
case PART_ROW_PADLOCK_ICON:
case PART_ROW_TEXT: {
m_range.startRange(nullptr, m_frame, Range::kLayers);
break;
}
case PART_CEL:
case PART_HEADER_FRAME:
m_range.startRange(nullptr, m_frame, Range::kFrames);
break;
}
updateDropRange(e.position());
flushRedraw();
os::Event ev;
os::System::instance()->eventQueue()->queueEvent(ev);
}
void Timeline::onDrop(ui::DragEvent& e)
{
Widget::onDrop(e);
e.handled(true);
m_state = STATE_STANDBY;
m_range.clearRange();
invalidate();
flushRedraw();
os::Event ev;
os::System::instance()->eventQueue()->queueEvent(ev);
}
int Timeline::tagFramesDuration(const Tag* tag) const
{
ASSERT(m_sprite);

View File

@ -46,6 +46,7 @@ namespace doc {
namespace ui {
class Graphics;
class TooltipManager;
class DragEvent;
}
namespace app {
@ -195,6 +196,11 @@ namespace app {
bool onClear(Context* ctx) override;
void onCancel(Context* ctx) override;
void onDragEnter(ui::DragEvent& e) override;
void onDragLeave(ui::DragEvent& e) override;
void onDrag(ui::DragEvent& e) override;
void onDrop(ui::DragEvent& e) override;
private:
struct DrawCelData;

View File

@ -8,7 +8,9 @@
#define UI_DRAG_EVENT_H_INCLUDED
#pragma once
#include "base/paths.h"
#include "os/dnd.h"
#include "os/surface.h"
#include "ui/event.h"
#include "ui/widget.h"
@ -37,6 +39,22 @@ namespace ui {
const gfx::Point& position() const { return m_position; }
bool hasPaths() const {
return m_ev.dataProvider()->contains(os::DragDataItemType::Paths);
}
bool hasImage() const {
return m_ev.dataProvider()->contains(os::DragDataItemType::Image);
}
base::paths getPaths() const {
return m_ev.dataProvider()->getPaths();
}
os::SurfaceRef getImage() const {
return m_ev.dataProvider()->getImage();
}
private:
bool m_handled = false;
gfx::Point m_position;