Drag recent items outside the list to remove them

This commit is contained in:
David Capello 2018-12-22 23:59:07 -03:00
parent 0f150b249d
commit 84f540ab7f
2 changed files with 71 additions and 17 deletions

View File

@ -31,7 +31,15 @@ public:
case ui::kSetCursorMessage:
if (m_floatingOverlay) {
ui::set_mouse_cursor(ui::kMoveCursor);
const ui::MouseMessage* mouseMsg = static_cast<ui::MouseMessage*>(msg);
const gfx::Point mousePos = mouseMsg->position();
if (onCanDropItemsOutside() &&
!getParentBounds().contains(mousePos)) {
ui::set_mouse_cursor(ui::kForbiddenCursor);
}
else {
ui::set_mouse_cursor(ui::kMoveCursor);
}
return true;
}
break;
@ -64,12 +72,33 @@ public:
if (m_floatingOverlay) {
m_floatingOverlay->moveOverlay(mousePos - m_floatingOffset);
onReorderWidgets(mousePos);
bool inside = true;
if (onCanDropItemsOutside()) {
inside = getParentBounds().contains(mousePos);
if (inside) {
if (this->hasFlags(ui::HIDDEN)) {
this->disableFlags(ui::HIDDEN);
layoutParent();
}
}
else {
if (!this->hasFlags(ui::HIDDEN)) {
this->enableFlags(ui::HIDDEN);
layoutParent();
}
}
}
onReorderWidgets(mousePos, inside);
}
break;
}
case ui::kMouseUpMessage: {
const ui::MouseMessage* mouseMsg = static_cast<ui::MouseMessage*>(msg);
const gfx::Point mousePos = mouseMsg->position();
m_wasDragged = (this->hasCapture() && m_floatingOverlay);
const bool result = Base::onProcessMessage(msg);
@ -77,7 +106,7 @@ public:
if (m_floatingOverlay) {
destroyFloatingOverlay();
ASSERT(!m_createFloatingOverlay);
onFinalDrop();
onFinalDrop(getParentBounds().contains(mousePos));
}
else if (m_createFloatingOverlay)
m_createFloatingOverlay = false;
@ -134,22 +163,36 @@ private:
}
gfx::Size getFloatingOverlaySize() {
auto view = ui::View::getView(this);
if (!view)
view = ui::View::getView(this->parent());
auto view = ui::View::getView(this->parent());
if (view)
return (view->viewportBounds().offset(view->viewScroll()) & this->bounds()).size();
else
return this->size();
}
gfx::Rect getParentBounds() {
auto view = ui::View::getView(this->parent());
if (view)
return view->viewportBounds();
else
return this->parent()->bounds();
}
void layoutParent() {
this->parent()->layout();
auto view = ui::View::getView(this->parent());
if (view)
return view->updateView();
}
void drawFloatingOverlay(ui::Graphics& g) {
ui::PaintEvent ev(this, &g);
this->onPaint(ev);
}
virtual void onReorderWidgets(const gfx::Point& mousePos) { }
virtual void onFinalDrop() { }
virtual bool onCanDropItemsOutside() { return true; }
virtual void onReorderWidgets(const gfx::Point& mousePos, bool inside) { }
virtual void onFinalDrop(bool inside) { }
// True if we should create the floating overlay after leaving the
// widget bounds.

View File

@ -168,7 +168,7 @@ protected:
static_cast<RecentListBox*>(parent())->onClick(m_fullpath);
}
void onReorderWidgets(const gfx::Point& mousePos) override {
void onReorderWidgets(const gfx::Point& mousePos, bool inside) override {
auto parent = this->parent();
auto other = manager()->pick(mousePos);
if (other && other != this && other->parent() == parent) {
@ -177,21 +177,30 @@ protected:
}
}
void onFinalDrop() override {
void onFinalDrop(bool inside) override {
if (!wasDragged())
return;
// Pin all elements to keep the order
const auto& children = parent()->children();
for (auto it=children.rbegin(), end=children.rend(); it!=end; ++it) {
if (this == *it) {
for (; it!=end; ++it)
static_cast<RecentFileItem*>(*it)->pin();
break;
if (inside) {
// Pin all elements to keep the order
const auto& children = parent()->children();
for (auto it=children.rbegin(), end=children.rend(); it!=end; ++it) {
if (this == *it) {
for (; it!=end; ++it)
static_cast<RecentFileItem*>(*it)->pin();
break;
}
}
}
else {
setVisible(false);
parent()->layout();
}
saveConfig();
if (!inside)
deferDelete();
}
private:
@ -254,6 +263,8 @@ void RecentListBox::updateRecentListFromUIItems()
base::paths recentPaths;
for (auto item : children()) {
auto fi = static_cast<RecentFileItem*>(item);
if (fi->hasFlags(ui::HIDDEN))
continue;
if (fi->pinned())
pinnedPaths.push_back(fi->fullpath());
else