Show new tab preview to be docked in other Tabs

This commit is contained in:
David Capello 2015-04-04 16:25:57 -03:00
parent 5cef48c846
commit 6a56e218f2
6 changed files with 74 additions and 23 deletions

View File

@ -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));
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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();