2015-02-12 23:16:25 +08:00
|
|
|
// Aseprite
|
|
|
|
// Copyright (C) 2001-2015 David Capello
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2 as
|
|
|
|
// published by the Free Software Foundation.
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2013-01-21 05:40:37 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/workspace.h"
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/app.h"
|
|
|
|
#include "app/ui/main_window.h"
|
2015-03-05 04:23:40 +08:00
|
|
|
#include "app/ui/skin/skin_theme.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/tabs.h"
|
|
|
|
#include "app/ui/workspace_view.h"
|
2015-03-05 04:23:40 +08:00
|
|
|
#include "base/remove_from_container.h"
|
2013-01-21 05:40:37 +08:00
|
|
|
|
|
|
|
#include <algorithm>
|
2013-03-28 09:13:25 +08:00
|
|
|
#include <queue>
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
namespace app {
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
using namespace app::skin;
|
|
|
|
using namespace ui;
|
2015-02-12 23:16:25 +08:00
|
|
|
|
2013-01-21 05:40:37 +08:00
|
|
|
Workspace::Workspace()
|
2015-03-05 04:23:40 +08:00
|
|
|
: Widget(kGenericWidget)
|
2015-03-28 04:26:04 +08:00
|
|
|
, m_tabsBar(nullptr)
|
2015-03-05 04:23:40 +08:00
|
|
|
, m_activeView(nullptr)
|
2015-03-28 05:45:36 +08:00
|
|
|
, m_dropArea(0)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
|
|
|
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
2015-02-16 02:29:16 +08:00
|
|
|
setBgColor(theme->colors.workspace());
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Workspace::~Workspace()
|
|
|
|
{
|
2013-03-28 08:19:35 +08:00
|
|
|
// No views at this point.
|
|
|
|
ASSERT(m_views.empty());
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
2015-03-28 04:26:04 +08:00
|
|
|
void Workspace::setTabsBar(Tabs* tabsBar)
|
|
|
|
{
|
|
|
|
m_tabsBar = tabsBar;
|
|
|
|
}
|
|
|
|
|
2015-03-19 04:34:22 +08:00
|
|
|
void Workspace::addView(WorkspaceView* view, int pos)
|
2013-01-21 05:40:37 +08:00
|
|
|
{
|
2015-03-19 04:34:22 +08:00
|
|
|
if (pos < 0)
|
|
|
|
m_views.push_back(view);
|
|
|
|
else
|
|
|
|
m_views.insert(m_views.begin()+pos, view);
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2015-03-28 04:26:04 +08:00
|
|
|
m_tabsBar->addTab(dynamic_cast<TabView*>(view), pos);
|
2015-03-05 04:23:40 +08:00
|
|
|
setActiveView(view);
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Workspace::removeView(WorkspaceView* view)
|
|
|
|
{
|
2015-03-05 04:23:40 +08:00
|
|
|
base::remove_from_container(m_views, view);
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2015-03-05 04:23:40 +08:00
|
|
|
Widget* content = view->getContentWidget();
|
|
|
|
if (content->getParent())
|
|
|
|
content->getParent()->removeChild(content);
|
2014-01-26 22:22:23 +08:00
|
|
|
|
2015-03-28 04:26:04 +08:00
|
|
|
// Remove related tab.
|
|
|
|
m_tabsBar->removeTab(dynamic_cast<TabView*>(view));
|
2013-03-28 08:19:35 +08:00
|
|
|
|
2015-03-28 04:26:04 +08:00
|
|
|
TabView* tabView = m_tabsBar->getSelectedTab();
|
2015-03-05 04:23:40 +08:00
|
|
|
setActiveView(dynamic_cast<WorkspaceView*>(tabView));
|
2013-03-28 08:19:35 +08:00
|
|
|
}
|
|
|
|
|
2015-02-23 08:18:53 +08:00
|
|
|
bool Workspace::closeView(WorkspaceView* view)
|
|
|
|
{
|
|
|
|
return view->onCloseView(this);
|
|
|
|
}
|
|
|
|
|
2014-07-29 11:53:24 +08:00
|
|
|
WorkspaceView* Workspace::activeView()
|
2013-03-28 08:19:35 +08:00
|
|
|
{
|
2015-03-05 04:23:40 +08:00
|
|
|
return m_activeView;
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Workspace::setActiveView(WorkspaceView* view)
|
|
|
|
{
|
2015-03-05 04:23:40 +08:00
|
|
|
m_activeView = view;
|
2013-01-21 05:40:37 +08:00
|
|
|
|
2015-03-05 04:23:40 +08:00
|
|
|
removeAllChildren();
|
|
|
|
if (view)
|
|
|
|
addChild(view->getContentWidget());
|
2013-03-28 08:19:35 +08:00
|
|
|
|
|
|
|
layout();
|
|
|
|
|
|
|
|
ActiveViewChanged(); // Fire ActiveViewChanged event
|
2013-01-21 05:40:37 +08:00
|
|
|
}
|
|
|
|
|
2015-03-05 04:23:40 +08:00
|
|
|
void Workspace::onPaint(PaintEvent& ev)
|
2014-01-26 22:22:23 +08:00
|
|
|
{
|
2015-03-05 04:23:40 +08:00
|
|
|
ev.getGraphics()->fillRect(getBgColor(), getClientBounds());
|
2014-01-26 22:22:23 +08:00
|
|
|
}
|
|
|
|
|
2015-03-28 05:14:00 +08:00
|
|
|
void Workspace::onResize(ui::ResizeEvent& ev)
|
|
|
|
{
|
|
|
|
setBoundsQuietly(ev.getBounds());
|
|
|
|
|
2015-03-28 05:45:36 +08:00
|
|
|
gfx::Rect rc = getChildrenBounds();
|
2015-03-28 05:14:00 +08:00
|
|
|
|
|
|
|
// Preview to drop tabs in workspace
|
2015-03-28 05:45:36 +08:00
|
|
|
int threshold = getDropThreshold();
|
|
|
|
switch (m_dropArea) {
|
|
|
|
case JI_LEFT:
|
|
|
|
rc.x += threshold;
|
|
|
|
rc.w -= threshold;
|
|
|
|
break;
|
|
|
|
case JI_TOP:
|
|
|
|
rc.y += threshold;
|
|
|
|
rc.h -= threshold;
|
|
|
|
break;
|
|
|
|
case JI_RIGHT:
|
|
|
|
rc.w -= threshold;
|
|
|
|
break;
|
|
|
|
case JI_BOTTOM:
|
|
|
|
rc.h -= threshold;
|
|
|
|
break;
|
2015-03-28 05:14:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (Widget* child : getChildren())
|
2015-03-28 05:45:36 +08:00
|
|
|
child->setBounds(rc);
|
2015-03-28 05:14:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Workspace::setDropViewPreview(const gfx::Point& pos)
|
|
|
|
{
|
2015-03-28 05:45:36 +08:00
|
|
|
int newDropArea = calculateDropArea(pos);
|
|
|
|
if (newDropArea != m_dropArea) {
|
|
|
|
m_dropArea = newDropArea;
|
|
|
|
layout();
|
|
|
|
}
|
2015-03-28 05:14:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Workspace::removeDropViewPreview(const gfx::Point& pos)
|
|
|
|
{
|
2015-03-28 05:45:36 +08:00
|
|
|
if (m_dropArea) {
|
|
|
|
m_dropArea = 0;
|
|
|
|
layout();
|
|
|
|
}
|
2015-03-28 05:14:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Workspace::dropViewAt(const gfx::Point& pos, WorkspaceView* view)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-03-28 05:45:36 +08:00
|
|
|
int Workspace::calculateDropArea(const gfx::Point& pos) const
|
|
|
|
{
|
|
|
|
gfx::Rect rc = getChildrenBounds();
|
|
|
|
if (rc.contains(pos)) {
|
|
|
|
int left = ABS(rc.x - pos.x);
|
|
|
|
int top = ABS(rc.y - pos.y);
|
|
|
|
int right = ABS(rc.x + rc.w - pos.x);
|
|
|
|
int bottom = ABS(rc.y + rc.h - pos.y);
|
|
|
|
int threshold = getDropThreshold();
|
|
|
|
|
|
|
|
if (left < threshold && left < right && left < top && left < bottom) {
|
|
|
|
return JI_LEFT;
|
|
|
|
}
|
|
|
|
else if (top < threshold && top < left && top < right && top < bottom) {
|
|
|
|
return JI_TOP;
|
|
|
|
}
|
|
|
|
else if (right < threshold && right < left && right < top && right < bottom) {
|
|
|
|
return JI_RIGHT;
|
|
|
|
}
|
|
|
|
else if (bottom < threshold && bottom < left && bottom < top && bottom < right) {
|
|
|
|
return JI_BOTTOM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Workspace::getDropThreshold() const
|
|
|
|
{
|
|
|
|
gfx::Rect cpos = getChildrenBounds();
|
|
|
|
int threshold = 32*guiscale();
|
|
|
|
if (threshold > cpos.w/2) threshold = cpos.w/2;
|
|
|
|
if (threshold > cpos.h/2) threshold = cpos.h/2;
|
|
|
|
return threshold;
|
|
|
|
}
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
} // namespace app
|