mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-16 10:20:50 +00:00
Add possibility to move tabs between different WorkspaceTabs widgets
This commit is contained in:
parent
294ff0e4f6
commit
e24c03f929
@ -51,8 +51,8 @@
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/toolbar.h"
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/boundary.h"
|
||||
#include "app/webserver.h"
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -32,10 +32,10 @@
|
||||
#include "app/ui/skin/skin_property.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/timeline.h"
|
||||
#include "app/ui/toolbar.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/splitter.h"
|
||||
@ -60,13 +60,14 @@ MainWindow::MainWindow()
|
||||
m_statusBar = new StatusBar();
|
||||
m_colorBar = new ColorBar(colorBarPlaceholder()->getAlign());
|
||||
m_toolBar = new ToolBar();
|
||||
m_tabsBar = new Tabs(this);
|
||||
m_tabsBar = new WorkspaceTabs(this);
|
||||
m_workspace = new Workspace();
|
||||
m_workspace->setTabsBar(m_tabsBar);
|
||||
m_workspace->ActiveViewChanged.connect(&MainWindow::onActiveViewChange, this);
|
||||
m_previewEditor = new PreviewEditorWindow();
|
||||
m_timeline = new Timeline();
|
||||
|
||||
m_workspace->setTabsBar(m_tabsBar);
|
||||
m_workspace->ActiveViewChanged.connect(&MainWindow::onActiveViewChange, this);
|
||||
|
||||
// configure all widgets to expansives
|
||||
m_menuBar->setExpansive(true);
|
||||
m_contextBar->setExpansive(true);
|
||||
@ -299,7 +300,9 @@ void MainWindow::onMouseOverTab(Tabs* tabs, TabView* tabView)
|
||||
|
||||
void MainWindow::onFloatingTab(Tabs* tabs, TabView* tabView, const gfx::Point& pos)
|
||||
{
|
||||
m_workspace->setDropViewPreview(pos);
|
||||
m_workspace->setDropViewPreview(pos,
|
||||
dynamic_cast<WorkspaceView*>(tabView),
|
||||
static_cast<WorkspaceTabs*>(tabs));
|
||||
}
|
||||
|
||||
void MainWindow::onDockingTab(Tabs* tabs, TabView* tabView)
|
||||
|
@ -34,9 +34,9 @@ namespace app {
|
||||
class Notifications;
|
||||
class PreviewEditorWindow;
|
||||
class StatusBar;
|
||||
class Tabs;
|
||||
class Timeline;
|
||||
class Workspace;
|
||||
class WorkspaceTabs;
|
||||
|
||||
class MainWindow : public app::gen::MainWindow
|
||||
, public TabsDelegate {
|
||||
@ -52,7 +52,7 @@ namespace app {
|
||||
|
||||
MainMenuBar* getMenuBar() { return m_menuBar; }
|
||||
ContextBar* getContextBar() { return m_contextBar; }
|
||||
Tabs* getTabsBar() { return m_tabsBar; }
|
||||
WorkspaceTabs* getTabsBar() { return m_tabsBar; }
|
||||
Timeline* getTimeline() { return m_timeline; }
|
||||
Workspace* getWorkspace() { return m_workspace; }
|
||||
PreviewEditorWindow* getPreviewEditor() { return m_previewEditor; }
|
||||
@ -98,7 +98,7 @@ namespace app {
|
||||
StatusBar* m_statusBar;
|
||||
ColorBar* m_colorBar;
|
||||
ui::Widget* m_toolBar;
|
||||
Tabs* m_tabsBar;
|
||||
WorkspaceTabs* m_tabsBar;
|
||||
Mode m_mode;
|
||||
Timeline* m_timeline;
|
||||
Workspace* m_workspace;
|
||||
|
@ -36,7 +36,7 @@ namespace app {
|
||||
using namespace app::skin;
|
||||
using namespace ui;
|
||||
|
||||
static WidgetType tabs_type()
|
||||
WidgetType Tabs::Type()
|
||||
{
|
||||
static WidgetType type = kGenericWidget;
|
||||
if (type == kGenericWidget)
|
||||
@ -45,7 +45,7 @@ static WidgetType tabs_type()
|
||||
}
|
||||
|
||||
Tabs::Tabs(TabsDelegate* delegate)
|
||||
: Widget(tabs_type())
|
||||
: Widget(Tabs::Type())
|
||||
, m_border(2)
|
||||
, m_hot(nullptr)
|
||||
, m_hotCloseButton(false)
|
||||
@ -57,6 +57,7 @@ Tabs::Tabs(TabsDelegate* delegate)
|
||||
, m_isDragging(false)
|
||||
, m_floatingTab(nullptr)
|
||||
, m_floatingOverlay(nullptr)
|
||||
, m_dropNewTab(nullptr)
|
||||
{
|
||||
setDoubleBuffered(true);
|
||||
initTheme();
|
||||
@ -144,16 +145,31 @@ void Tabs::updateTabs()
|
||||
tabWidth = MAX(4*ui::guiscale(), tabWidth);
|
||||
}
|
||||
double x = 0.0;
|
||||
int i = 0;
|
||||
|
||||
if (m_dropNewTab)
|
||||
m_dropNewIndex = -1;
|
||||
|
||||
for (auto& tab : m_list) {
|
||||
if (tab == m_floatingTab)
|
||||
if (tab == m_floatingTab) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_dropNewTab) {
|
||||
int dropX = m_dropNewPos.x - getBounds().x;
|
||||
if (dropX >= x-tabWidth/2 && dropX < x+tabWidth/2) {
|
||||
x += tabWidth;
|
||||
m_dropNewIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
tab->text = tab->view->getTabText();
|
||||
tab->icon = tab->view->getTabIcon();
|
||||
tab->x = int(x);
|
||||
tab->width = int(x+tabWidth) - int(x);
|
||||
x += tabWidth;
|
||||
++i;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
@ -220,6 +236,25 @@ void Tabs::setDockedStyle()
|
||||
setBgColor(theme->colors.workspace());
|
||||
}
|
||||
|
||||
void Tabs::setDropViewPreview(const gfx::Point& pos, TabView* view)
|
||||
{
|
||||
m_dropNewPos = pos;
|
||||
m_dropNewTab = view;
|
||||
|
||||
resetOldPositions(animationTime());
|
||||
updateTabs();
|
||||
startAnimation(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
}
|
||||
|
||||
void Tabs::removeDropViewPreview()
|
||||
{
|
||||
m_dropNewTab = nullptr;
|
||||
|
||||
resetOldPositions(animationTime());
|
||||
updateTabs();
|
||||
startAnimation(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
}
|
||||
|
||||
bool Tabs::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
@ -718,7 +753,7 @@ void Tabs::stopDrag(DropTabResult result)
|
||||
m_removedTab.reset(nullptr);
|
||||
destroyFloatingTab();
|
||||
|
||||
ASSERT(tab);
|
||||
//ASSERT(tab); // TODO check this state
|
||||
if (tab)
|
||||
removeTab(tab->view, false);
|
||||
break;
|
||||
|
@ -105,6 +105,8 @@ namespace app {
|
||||
};
|
||||
|
||||
public:
|
||||
static ui::WidgetType Type();
|
||||
|
||||
Tabs(TabsDelegate* delegate);
|
||||
~Tabs();
|
||||
|
||||
@ -121,6 +123,11 @@ namespace app {
|
||||
|
||||
void setDockedStyle();
|
||||
|
||||
// Drop TabViews into this Tabs widget
|
||||
void setDropViewPreview(const gfx::Point& pos, TabView* view);
|
||||
void removeDropViewPreview();
|
||||
int getDropTabIndex() const { return m_dropNewIndex; }
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
@ -174,6 +181,11 @@ namespace app {
|
||||
int m_dragTabIndex;
|
||||
TabPtr m_floatingTab;
|
||||
base::UniquePtr<ui::Overlay> m_floatingOverlay;
|
||||
|
||||
// Drop new tabs
|
||||
gfx::Point m_dropNewPos;
|
||||
TabView* m_dropNewTab;
|
||||
int m_dropNewIndex;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "app/ui/workspace.h"
|
||||
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
#include "app/ui/workspace_view.h"
|
||||
#include "base/remove_from_container.h"
|
||||
#include "ui/paint_event.h"
|
||||
@ -38,6 +38,7 @@ Workspace::Workspace()
|
||||
, m_tabs(nullptr)
|
||||
, m_activePanel(&m_mainPanel)
|
||||
, m_dropPreviewPanel(nullptr)
|
||||
, m_dropPreviewTabs(nullptr)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
setBgColor(theme->colors.workspace());
|
||||
@ -51,7 +52,7 @@ Workspace::~Workspace()
|
||||
ASSERT(m_views.empty());
|
||||
}
|
||||
|
||||
void Workspace::setTabsBar(Tabs* tabs)
|
||||
void Workspace::setTabsBar(WorkspaceTabs* tabs)
|
||||
{
|
||||
m_tabs = tabs;
|
||||
m_mainPanel.setTabsBar(tabs);
|
||||
@ -59,11 +60,7 @@ void Workspace::setTabsBar(Tabs* tabs)
|
||||
|
||||
void Workspace::addView(WorkspaceView* view, int pos)
|
||||
{
|
||||
m_mainPanel.addView(view, pos);
|
||||
m_activePanel = &m_mainPanel;
|
||||
m_views.push_back(view);
|
||||
|
||||
setActiveView(view);
|
||||
addViewToPanel(&m_mainPanel, view, pos);
|
||||
}
|
||||
|
||||
void Workspace::removeView(WorkspaceView* view)
|
||||
@ -122,31 +119,69 @@ void Workspace::onResize(ui::ResizeEvent& ev)
|
||||
child->setBounds(rc);
|
||||
}
|
||||
|
||||
void Workspace::setDropViewPreview(const gfx::Point& pos)
|
||||
void Workspace::setDropViewPreview(const gfx::Point& pos,
|
||||
WorkspaceView* view, WorkspaceTabs* tabs)
|
||||
{
|
||||
TabView* tabView = dynamic_cast<TabView*>(view);
|
||||
WorkspaceTabs* newTabs = nullptr;
|
||||
WorkspacePanel* panel = getPanelAt(pos);
|
||||
if (!newTabs) {
|
||||
newTabs = getTabsAt(pos);
|
||||
// Drop preview is only to drop tabs from a different WorkspaceTabs.
|
||||
if (newTabs == tabs)
|
||||
newTabs = nullptr;
|
||||
}
|
||||
|
||||
if (m_dropPreviewPanel && m_dropPreviewPanel != panel)
|
||||
m_dropPreviewPanel->removeDropViewPreview();
|
||||
if (m_dropPreviewTabs && m_dropPreviewTabs != newTabs)
|
||||
m_dropPreviewTabs->removeDropViewPreview();
|
||||
|
||||
m_dropPreviewPanel = panel;
|
||||
m_dropPreviewTabs = newTabs;
|
||||
|
||||
if (m_dropPreviewPanel)
|
||||
m_dropPreviewPanel->setDropViewPreview(pos);
|
||||
m_dropPreviewPanel->setDropViewPreview(pos, view);
|
||||
if (m_dropPreviewTabs)
|
||||
m_dropPreviewTabs->setDropViewPreview(pos, tabView);
|
||||
}
|
||||
|
||||
void Workspace::removeDropViewPreview()
|
||||
{
|
||||
if (m_dropPreviewPanel)
|
||||
m_dropPreviewPanel->removeDropViewPreview();
|
||||
|
||||
if (m_dropPreviewTabs)
|
||||
m_dropPreviewTabs->removeDropViewPreview();
|
||||
}
|
||||
|
||||
bool Workspace::dropViewAt(const gfx::Point& pos, WorkspaceView* view)
|
||||
{
|
||||
if (!m_dropPreviewPanel)
|
||||
return false;
|
||||
if (m_dropPreviewPanel)
|
||||
return m_dropPreviewPanel->dropViewAt(pos, getViewPanel(view), view);
|
||||
else if (m_dropPreviewTabs) {
|
||||
WorkspacePanel* dropPanel = m_dropPreviewTabs->panel();
|
||||
ASSERT(dropPanel);
|
||||
|
||||
return m_dropPreviewPanel->dropViewAt(pos, getViewPanel(view), view);
|
||||
int pos = m_dropPreviewTabs->getDropTabIndex();
|
||||
m_dropPreviewTabs->removeDropViewPreview();
|
||||
|
||||
removeView(view);
|
||||
addViewToPanel(dropPanel, view, pos);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Workspace::addViewToPanel(WorkspacePanel* panel, WorkspaceView* view, int pos)
|
||||
{
|
||||
panel->addView(view, pos);
|
||||
|
||||
m_activePanel = panel;
|
||||
m_views.push_back(view);
|
||||
|
||||
setActiveView(view);
|
||||
}
|
||||
|
||||
WorkspacePanel* Workspace::getViewPanel(WorkspaceView* view)
|
||||
@ -173,4 +208,16 @@ WorkspacePanel* Workspace::getPanelAt(const gfx::Point& pos)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorkspaceTabs* Workspace::getTabsAt(const gfx::Point& pos)
|
||||
{
|
||||
Widget* widget = getManager()->pick(pos);
|
||||
while (widget) {
|
||||
if (widget->getType() == Tabs::Type())
|
||||
return static_cast<WorkspaceTabs*>(widget);
|
||||
|
||||
widget = widget->getParent();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "ui/widget.h"
|
||||
|
||||
namespace app {
|
||||
class Tabs;
|
||||
class WorkspaceTabs;
|
||||
|
||||
class Workspace : public ui::Widget {
|
||||
public:
|
||||
@ -25,7 +25,7 @@ namespace app {
|
||||
Workspace();
|
||||
~Workspace();
|
||||
|
||||
void setTabsBar(Tabs* tabs);
|
||||
void setTabsBar(WorkspaceTabs* tabs);
|
||||
|
||||
iterator begin() { return m_views.begin(); }
|
||||
iterator end() { return m_views.end(); }
|
||||
@ -42,7 +42,8 @@ namespace app {
|
||||
void setMainPanelAsActive();
|
||||
|
||||
// Drop views into workspace
|
||||
void setDropViewPreview(const gfx::Point& pos);
|
||||
void setDropViewPreview(const gfx::Point& pos,
|
||||
WorkspaceView* view, WorkspaceTabs* tabs);
|
||||
void removeDropViewPreview();
|
||||
|
||||
// Returns true if the view was docked inside the workspace.
|
||||
@ -55,17 +56,17 @@ namespace app {
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
|
||||
private:
|
||||
int calculateDropArea(const gfx::Point& pos) const;
|
||||
int getDropThreshold() const;
|
||||
void adjustTime(int& time, int flag);
|
||||
void addViewToPanel(WorkspacePanel* panel, WorkspaceView* view, int pos);
|
||||
WorkspacePanel* getViewPanel(WorkspaceView* view);
|
||||
WorkspacePanel* getPanelAt(const gfx::Point& pos);
|
||||
WorkspaceTabs* getTabsAt(const gfx::Point& pos);
|
||||
|
||||
WorkspacePanel m_mainPanel;
|
||||
Tabs* m_tabs;
|
||||
WorkspaceTabs* m_tabs;
|
||||
WorkspaceViews m_views;
|
||||
WorkspacePanel* m_activePanel;
|
||||
WorkspacePanel* m_dropPreviewPanel;
|
||||
WorkspaceTabs* m_dropPreviewTabs;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "app/ui/workspace_panel.h"
|
||||
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
#include "app/ui/workspace_view.h"
|
||||
@ -59,9 +58,10 @@ WorkspacePanel::~WorkspacePanel()
|
||||
ASSERT(m_views.empty());
|
||||
}
|
||||
|
||||
void WorkspacePanel::setTabsBar(Tabs* tabs)
|
||||
void WorkspacePanel::setTabsBar(WorkspaceTabs* tabs)
|
||||
{
|
||||
m_tabs = tabs;
|
||||
m_tabs->setPanel(this);
|
||||
}
|
||||
|
||||
void WorkspacePanel::addView(WorkspaceView* view, int pos)
|
||||
@ -181,7 +181,7 @@ void WorkspacePanel::adjustActiveViewBounds()
|
||||
child->setBounds(rc);
|
||||
}
|
||||
|
||||
void WorkspacePanel::setDropViewPreview(const gfx::Point& pos)
|
||||
void WorkspacePanel::setDropViewPreview(const gfx::Point& pos, WorkspaceView* view)
|
||||
{
|
||||
int newDropArea = calculateDropArea(pos);
|
||||
if (newDropArea != m_dropArea) {
|
||||
@ -246,6 +246,7 @@ bool WorkspacePanel::dropViewAt(const gfx::Point& pos, WorkspacePanel* from, Wor
|
||||
|
||||
WorkspaceTabs* newTabs = new WorkspaceTabs(m_tabs->getDelegate());
|
||||
WorkspacePanel* newPanel = new WorkspacePanel(SUB_PANEL);
|
||||
newTabs->setDockedStyle();
|
||||
newPanel->setTabsBar(newTabs);
|
||||
newPanel->setExpansive(true);
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
class Tabs;
|
||||
class Workspace;
|
||||
class WorkspaceTabs;
|
||||
|
||||
class WorkspacePanel : public ui::Widget
|
||||
, public AnimatedWidget {
|
||||
@ -41,7 +41,7 @@ namespace app {
|
||||
WorkspacePanel(PanelType panelType);
|
||||
~WorkspacePanel();
|
||||
|
||||
void setTabsBar(Tabs* tabs);
|
||||
void setTabsBar(WorkspaceTabs* tabs);
|
||||
|
||||
iterator begin() { return m_views.begin(); }
|
||||
iterator end() { return m_views.end(); }
|
||||
@ -55,7 +55,7 @@ namespace app {
|
||||
void setActiveView(WorkspaceView* view);
|
||||
|
||||
// Drop views into workspace
|
||||
void setDropViewPreview(const gfx::Point& pos);
|
||||
void setDropViewPreview(const gfx::Point& pos, WorkspaceView* view);
|
||||
void removeDropViewPreview();
|
||||
|
||||
// Returns true if the view was docked inside the panel.
|
||||
@ -75,7 +75,7 @@ namespace app {
|
||||
Workspace* getWorkspace();
|
||||
|
||||
PanelType m_panelType;
|
||||
Tabs* m_tabs;
|
||||
WorkspaceTabs* m_tabs;
|
||||
WorkspaceViews m_views;
|
||||
WorkspaceView* m_activeView;
|
||||
int m_dropArea;
|
||||
|
@ -17,12 +17,18 @@ using namespace ui;
|
||||
|
||||
WorkspaceTabs::WorkspaceTabs(TabsDelegate* tabsDelegate)
|
||||
: Tabs(tabsDelegate)
|
||||
, m_panel(nullptr)
|
||||
{
|
||||
setDockedStyle();
|
||||
}
|
||||
|
||||
WorkspaceTabs::~WorkspaceTabs()
|
||||
{
|
||||
}
|
||||
|
||||
void WorkspaceTabs::setPanel(WorkspacePanel* panel)
|
||||
{
|
||||
ASSERT(!m_panel);
|
||||
m_panel = panel;
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -12,12 +12,20 @@
|
||||
#include "app/ui/tabs.h"
|
||||
|
||||
namespace app {
|
||||
class Tabs;
|
||||
class WorkspacePanel;
|
||||
|
||||
class WorkspaceTabs : public Tabs {
|
||||
public:
|
||||
ui::WidgetType Type();
|
||||
|
||||
WorkspaceTabs(TabsDelegate* tabsDelegate);
|
||||
~WorkspaceTabs();
|
||||
|
||||
WorkspacePanel* panel() const { return m_panel; }
|
||||
void setPanel(WorkspacePanel* panel);
|
||||
|
||||
private:
|
||||
WorkspacePanel* m_panel;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -20,9 +20,9 @@
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/preview_editor.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/timeline.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/mutex.h"
|
||||
#include "doc/sprite.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user