mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-31 00:32:48 +00:00
Show new tab preview to be docked in other Tabs
This commit is contained in:
parent
5cef48c846
commit
6a56e218f2
@ -298,9 +298,9 @@ void MainWindow::onMouseOverTab(Tabs* tabs, TabView* tabView)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos)
|
||||
DropViewPreviewResult MainWindow::onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos)
|
||||
{
|
||||
m_workspace->setDropViewPreview(pos,
|
||||
return m_workspace->setDropViewPreview(pos,
|
||||
dynamic_cast<WorkspaceView*>(tabView),
|
||||
static_cast<WorkspaceTabs*>(tabs));
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ namespace app {
|
||||
void onCloseTab(Tabs* tabs, TabView* tabView) override;
|
||||
void onContextMenuTab(Tabs* tabs, TabView* tabView) override;
|
||||
void onMouseOverTab(Tabs* tabs, TabView* tabView) override;
|
||||
void onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos) override;
|
||||
DropViewPreviewResult onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos) override;
|
||||
void onDockingTab(Tabs* tabs, TabView* tabView) override;
|
||||
DropTabResult onDropTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos) override;
|
||||
|
||||
|
@ -240,15 +240,19 @@ void Tabs::setDropViewPreview(const gfx::Point& pos, TabView* view)
|
||||
else
|
||||
newIndex = 0;
|
||||
|
||||
if (m_dropNewIndex == newIndex && m_dropNewTab == view)
|
||||
return;
|
||||
bool startAni = (m_dropNewIndex != newIndex || m_dropNewTab != view);
|
||||
|
||||
m_dropNewIndex = newIndex;
|
||||
m_dropNewPosX = (pos.x - getBounds().x);
|
||||
m_dropNewTab = view;
|
||||
|
||||
resetOldPositions(animationTime());
|
||||
updateTabs();
|
||||
startAnimation(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
if (startAni) {
|
||||
resetOldPositions(animationTime());
|
||||
updateTabs();
|
||||
startAnimation(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
}
|
||||
else
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void Tabs::removeDropViewPreview()
|
||||
@ -286,19 +290,27 @@ bool Tabs::onProcessMessage(Message* msg)
|
||||
// We are drag a tab...
|
||||
else {
|
||||
TabPtr justDocked(nullptr);
|
||||
bool dockedInThisTabs = true;
|
||||
|
||||
// Floating tab (to create a new window)
|
||||
if (!getBounds().contains(mousePos) &&
|
||||
(ABS(delta.y) > 16*guiscale() ||
|
||||
mousePos.x < getBounds().x-16*guiscale() ||
|
||||
mousePos.x > getBounds().x2()+16*guiscale())) {
|
||||
if (!m_floatingOverlay)
|
||||
createFloatingTab(m_selected);
|
||||
|
||||
m_floatingOverlay->moveOverlay(mousePos - m_dragOffset);
|
||||
DropViewPreviewResult result = DropViewPreviewResult::FLOATING;
|
||||
|
||||
if (m_delegate)
|
||||
m_delegate->onFloatingTab(this, m_selected->view, mousePos);
|
||||
result = m_delegate->onFloatingTab(this, m_selected->view, mousePos);
|
||||
|
||||
if (result != DropViewPreviewResult::DROP_IN_TABS) {
|
||||
if (!m_floatingOverlay)
|
||||
createFloatingTab(m_selected);
|
||||
m_floatingOverlay->moveOverlay(mousePos - m_dragOffset);
|
||||
dockedInThisTabs = false;
|
||||
}
|
||||
else {
|
||||
destroyFloatingOverlay();
|
||||
}
|
||||
}
|
||||
else {
|
||||
justDocked = m_floatingTab;
|
||||
@ -309,7 +321,7 @@ bool Tabs::onProcessMessage(Message* msg)
|
||||
}
|
||||
|
||||
// Docked tab
|
||||
if (!m_floatingOverlay) {
|
||||
if (dockedInThisTabs) {
|
||||
m_selected->x = m_dragTabX + delta.x;
|
||||
|
||||
int i = (mousePos.x - m_border*guiscale() - getBounds().x) / m_selected->width;
|
||||
@ -474,6 +486,19 @@ void Tabs::onPaint(PaintEvent& ev)
|
||||
|
||||
drawTab(g, box, m_selected.get(), dy, (tab == m_hot), true);
|
||||
}
|
||||
|
||||
// New tab from other Tab that want to be dropped here.
|
||||
if (m_dropNewTab) {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
Tab newTab(m_dropNewTab);
|
||||
newTab.text = m_dropNewTab->getTabText();
|
||||
newTab.icon = m_dropNewTab->getTabIcon();
|
||||
newTab.width = (!m_list.empty() ? m_list[0]->width:
|
||||
theme->dimensions.tabsWidth());
|
||||
newTab.x = m_dropNewPosX - newTab.width/2;
|
||||
box = getTabBounds(&newTab);
|
||||
drawTab(g, box, &newTab, 0, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Tabs::onResize(ResizeEvent& ev)
|
||||
@ -830,10 +855,7 @@ void Tabs::createFloatingTab(TabPtr& tab)
|
||||
|
||||
void Tabs::destroyFloatingTab()
|
||||
{
|
||||
if (m_floatingOverlay) {
|
||||
OverlayManager::instance()->removeOverlay(m_floatingOverlay.get());
|
||||
m_floatingOverlay.reset();
|
||||
}
|
||||
destroyFloatingOverlay();
|
||||
|
||||
if (m_floatingTab) {
|
||||
TabPtr tab(m_floatingTab);
|
||||
@ -848,4 +870,12 @@ void Tabs::destroyFloatingTab()
|
||||
}
|
||||
}
|
||||
|
||||
void Tabs::destroyFloatingOverlay()
|
||||
{
|
||||
if (m_floatingOverlay) {
|
||||
OverlayManager::instance()->removeOverlay(m_floatingOverlay.get());
|
||||
m_floatingOverlay.reset();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -49,6 +49,12 @@ namespace app {
|
||||
DOCKED_IN_OTHER_PLACE,
|
||||
};
|
||||
|
||||
enum class DropViewPreviewResult {
|
||||
DROP_IN_PANEL,
|
||||
DROP_IN_TABS,
|
||||
FLOATING,
|
||||
};
|
||||
|
||||
// Interface used to control notifications from the Tabs widget.
|
||||
class TabsDelegate {
|
||||
public:
|
||||
@ -71,9 +77,13 @@ namespace app {
|
||||
// mouse just leave all tabs)
|
||||
virtual void onMouseOverTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
|
||||
// Called when the user is dragging a tab outside the Tabs bar.
|
||||
virtual void onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos) = 0;
|
||||
// Called when the user is dragging a tab outside the Tabs
|
||||
// bar.
|
||||
virtual DropViewPreviewResult onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos) = 0;
|
||||
|
||||
// Called when the user is dragging a tab inside the Tabs bar.
|
||||
virtual void onDockingTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
|
||||
virtual DropTabResult onDropTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos) = 0;
|
||||
};
|
||||
|
||||
@ -154,6 +164,7 @@ namespace app {
|
||||
gfx::Rect getTabBounds(Tab* tab);
|
||||
void createFloatingTab(TabPtr& tab);
|
||||
void destroyFloatingTab();
|
||||
void destroyFloatingOverlay();
|
||||
|
||||
int m_border;
|
||||
TabsList m_list;
|
||||
@ -185,6 +196,7 @@ namespace app {
|
||||
// Drop new tabs
|
||||
TabView* m_dropNewTab;
|
||||
int m_dropNewIndex;
|
||||
int m_dropNewPosX;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -130,7 +130,7 @@ void Workspace::onResize(ui::ResizeEvent& ev)
|
||||
child->setBounds(rc);
|
||||
}
|
||||
|
||||
void Workspace::setDropViewPreview(const gfx::Point& pos,
|
||||
DropViewPreviewResult Workspace::setDropViewPreview(const gfx::Point& pos,
|
||||
WorkspaceView* view, WorkspaceTabs* tabs)
|
||||
{
|
||||
TabView* tabView = dynamic_cast<TabView*>(view);
|
||||
@ -155,6 +155,13 @@ void Workspace::setDropViewPreview(const gfx::Point& pos,
|
||||
m_dropPreviewPanel->setDropViewPreview(pos, view);
|
||||
if (m_dropPreviewTabs)
|
||||
m_dropPreviewTabs->setDropViewPreview(pos, tabView);
|
||||
|
||||
if (panel)
|
||||
return DropViewPreviewResult::DROP_IN_PANEL;
|
||||
else if (newTabs)
|
||||
return DropViewPreviewResult::DROP_IN_TABS;
|
||||
else
|
||||
return DropViewPreviewResult::FLOATING;
|
||||
}
|
||||
|
||||
void Workspace::removeDropViewPreview()
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define APP_UI_WORKSPACE_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_panel.h"
|
||||
#include "base/signal.h"
|
||||
#include "ui/widget.h"
|
||||
@ -43,8 +44,9 @@ namespace app {
|
||||
void selectNextTab();
|
||||
void selectPreviousTab();
|
||||
|
||||
// Drop views into workspace
|
||||
void setDropViewPreview(const gfx::Point& pos,
|
||||
// Set the preview of what could happen if we drop the given
|
||||
// "view" at the "pos"?
|
||||
DropViewPreviewResult setDropViewPreview(const gfx::Point& pos,
|
||||
WorkspaceView* view, WorkspaceTabs* tabs);
|
||||
void removeDropViewPreview();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user