|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "docklayout.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <assert.h></assert.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <math.h></math.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <algorithm></algorithm>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <qtextstream></qtextstream>
|
|
Toshihiro Shimizu |
890ddd |
#include <qapplication></qapplication>
|
|
Toshihiro Shimizu |
890ddd |
#include <qdesktopwidget></qdesktopwidget>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// TO DO:
|
|
Toshihiro Shimizu |
890ddd |
// * Usa la macro QWIDGETSIZE_MAX per max grandezza settabile per una widget
|
|
Shinya Kitaoka |
120a6e |
// => Dopodiche', basterebbe troncare tutte le somme che eccedono quel
|
|
Shinya Kitaoka |
120a6e |
// valore... Comunque...
|
|
Shinya Kitaoka |
120a6e |
// * Il ricalcolo delle extremal sizes e' inutile nei resize events... Cerca di
|
|
Shinya Kitaoka |
120a6e |
// tagliare cose di questo tipo - ottimizza!
|
|
Shinya Kitaoka |
120a6e |
// => Pero' e' sensato in generale che redistribute possa ricalcolarle -
|
|
Shinya Kitaoka |
120a6e |
// forse si potrebbe fare una redistribute
|
|
Shinya Kitaoka |
120a6e |
// con un bool di ingresso. Se l'operazione contenitrice non puo'
|
|
Shinya Kitaoka |
120a6e |
// cambiare le extremal sizes, allora metti false..
|
|
Toshihiro Shimizu |
890ddd |
// * Implementa gli stretch factors
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// * Nascondere le finestre dockate...? Molto rognoso...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// * Una dock widget potrebbe non avere i soli stati docked e floating... Che
|
|
Shinya Kitaoka |
120a6e |
// succede se e' una subwindow
|
|
Toshihiro Shimizu |
890ddd |
// non dockata in un dockLayout??
|
|
Toshihiro Shimizu |
890ddd |
// * Spezzare tdockwindows.h in tmainwindow.h e tdockwidget.h, come in Qt?
|
|
Shinya Kitaoka |
120a6e |
// * Muovere o fare operazioni su una dockWidget allo stato attuale non e'
|
|
Shinya Kitaoka |
120a6e |
// sicuro se quella non e' assegnata ad
|
|
Shinya Kitaoka |
120a6e |
// un DockLayout!! Comunque, si puo' assumere che il parente di una
|
|
Shinya Kitaoka |
120a6e |
// DockWidget non sia nemmeno una QWidget
|
|
Shinya Kitaoka |
120a6e |
// che implementa un DockLayout. Questa cosa puo' venire meno in
|
|
Shinya Kitaoka |
120a6e |
// un'implementazione specifica come TDockWidget?
|
|
Shinya Kitaoka |
120a6e |
// Esempio: vedi calculateDockPlaceholders ad un drag, viene lanciato
|
|
Shinya Kitaoka |
120a6e |
// comunque...
|
|
Shinya Kitaoka |
120a6e |
// * Ha senso mettere DockLayout e DockWidget nella DVAPI? Forse se definissi
|
|
Shinya Kitaoka |
120a6e |
// delle inline opportune in TDockWidget...
|
|
Shinya Kitaoka |
120a6e |
// * Quanto contenuto in DockSeparator::mousePress e mouseMove dovrebbe essere
|
|
Shinya Kitaoka |
120a6e |
// reso pubblico. Anche la geometria
|
|
Shinya Kitaoka |
120a6e |
// delle regioni potrebbe essere editabile dall'utente... ma prima si
|
|
Shinya Kitaoka |
120a6e |
// dovrebbero fare gli stretch factors!!
|
|
Shinya Kitaoka |
120a6e |
// > Ossia: se si vuole esplicitamente settare la geometria di una regione,
|
|
Shinya Kitaoka |
120a6e |
// si potrebbe fare che quella
|
|
Toshihiro Shimizu |
890ddd |
// si prende stretch factor infinito (o quasi), e gli altri 1...
|
|
Shinya Kitaoka |
120a6e |
// * Dovrebbe esistere un modo per specificare la posizione dei separatori da
|
|
Shinya Kitaoka |
120a6e |
// codice?
|
|
Shinya Kitaoka |
120a6e |
// Rognoso. Comunque, ora basta specificare la geometria delle widget prima
|
|
Shinya Kitaoka |
120a6e |
// del dock;
|
|
Toshihiro Shimizu |
890ddd |
// la redistribute cerca di adattarsi.
|
|
Shinya Kitaoka |
120a6e |
// * Capita spesso di considerare l'ipotetica nuova radice della struttura.
|
|
Shinya Kitaoka |
120a6e |
// Perche' non metterla direttamente??
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// X Non e' possibile coprire tutte le possibilita' di docking con il sistema
|
|
Shinya Kitaoka |
120a6e |
// attuale, anche se e' comunque piu'
|
|
Toshihiro Shimizu |
890ddd |
// esteso di quello di Qt.
|
|
Toshihiro Shimizu |
890ddd |
// Esempio: |
|
|
Toshihiro Shimizu |
890ddd |
// -----|
|
|
Toshihiro Shimizu |
890ddd |
// | | => !!
|
|
Toshihiro Shimizu |
890ddd |
// |-----
|
|
Toshihiro Shimizu |
890ddd |
// |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------
|
|
Toshihiro Shimizu |
890ddd |
// Geometry inlines
|
|
Toshihiro Shimizu |
890ddd |
//------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// QRectF::toRect seems to work in the commented way inside the following
|
|
Shinya Kitaoka |
120a6e |
// function.
|
|
Shinya Kitaoka |
120a6e |
// Of course that way the rect borders are *not* approximated to the nearest
|
|
Shinya Kitaoka |
120a6e |
// integer
|
|
Shinya Kitaoka |
120a6e |
// coordinates:
|
|
Shinya Kitaoka |
120a6e |
// e.g.: topLeft= (1/3, 1/3); width= 4/3, height= 4/3 => left= top= right=
|
|
Shinya Kitaoka |
120a6e |
// bottom= 0.
|
|
Shinya Kitaoka |
120a6e |
inline QRect toRect(const QRectF &rect) {
|
|
Shinya Kitaoka |
120a6e |
// return QRect(qRound(rect.left()), qRound(rect.top()), qRound(rect.width()),
|
|
Shinya Kitaoka |
120a6e |
// qRound(rect.height()));
|
|
Shinya Kitaoka |
120a6e |
return QRect(rect.topLeft().toPoint(),
|
|
Shinya Kitaoka |
120a6e |
rect.bottomRight().toPoint() -= QPoint(1, 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------
|
|
Toshihiro Shimizu |
890ddd |
// Dock Layout
|
|
Toshihiro Shimizu |
890ddd |
//-----------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DockLayout::DockLayout()
|
|
Shinya Kitaoka |
120a6e |
: m_maximizedDock(0), m_decoAllocator(new DockDecoAllocator()) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DockLayout::~DockLayout() {
|
|
Shinya Kitaoka |
120a6e |
// Deleting Regions (separators are Widgets with parent, so they are
|
|
Shinya Kitaoka |
120a6e |
// recursively deleted)
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i) delete m_regions[i];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Deleting dockWidgets
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_items.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
// delete m_items[i]->widget();
|
|
Shinya Kitaoka |
120a6e |
delete m_items[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Delete deco allocator
|
|
Shinya Kitaoka |
120a6e |
delete m_decoAllocator;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
int DockLayout::count() const { return m_items.size(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
void DockLayout::addItem(QLayoutItem *item) {
|
|
Shinya Kitaoka |
120a6e |
DockWidget *addedItem = dynamic_cast<dockwidget *="">(item->widget());</dockwidget>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Ensure that added item is effectively a DockWidget type;
|
|
Shinya Kitaoka |
120a6e |
assert(addedItem);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Check if item is already under layout's control. If so, quit.
|
|
Shinya Kitaoka |
120a6e |
if (find(addedItem)) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Force reparentation. This is required in order to ensure that all items
|
|
Shinya Kitaoka |
120a6e |
// possess
|
|
Shinya Kitaoka |
120a6e |
// the same geometry() reference. Also store parentLayout for convenience.
|
|
Shinya Kitaoka |
120a6e |
addedItem->m_parentLayout = this;
|
|
Shinya Kitaoka |
120a6e |
addedItem->setParent(parentWidget());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Remember that reparenting a widget produces a window flags reset if the new
|
|
Shinya Kitaoka |
120a6e |
// parent is not the current one (see Qt's manual). So, first reassign
|
|
Shinya Kitaoka |
120a6e |
// standard
|
|
Shinya Kitaoka |
120a6e |
// floating flags, then call for custom appearance (which may eventually
|
|
Shinya Kitaoka |
120a6e |
// reassign the flags).
|
|
Shinya Kitaoka |
120a6e |
addedItem->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
|
Shinya Kitaoka |
120a6e |
addedItem->setFloatingAppearance();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_items.push_back(item);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
QLayoutItem *DockLayout::takeAt(int idx) {
|
|
Shinya Kitaoka |
120a6e |
if (idx < 0 || idx >= (int)m_items.size()) return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QLayoutItem *item = m_items[idx];
|
|
Shinya Kitaoka |
120a6e |
DockWidget *dw = static_cast<dockwidget *="">(item->widget());</dockwidget>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// If docked, undock item
|
|
Shinya Kitaoka |
120a6e |
if (!dw->isFloating()) undockItem(dw);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Reset item's parentLayout
|
|
Shinya Kitaoka |
120a6e |
dw->m_parentLayout = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_items.erase(m_items.begin() + idx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return item;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
QLayoutItem *DockLayout::itemAt(int idx) const {
|
|
Shinya Kitaoka |
120a6e |
if (idx >= (int)m_items.size()) return 0;
|
|
Shinya Kitaoka |
120a6e |
return m_items[idx];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QWidget *DockLayout::widgetAt(int idx) const { return itemAt(idx)->widget(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
QSize DockLayout::minimumSize() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_regions.empty()) {
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_regions.front();
|
|
Shinya Kitaoka |
120a6e |
r->calculateExtremalSizes();
|
|
Shinya Kitaoka |
120a6e |
return QSize(r->m_minimumSize[0], r->m_minimumSize[1]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return QSize(0, 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
QSize DockLayout::maximumSize() const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_regions.empty()) {
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_regions.front();
|
|
Shinya Kitaoka |
120a6e |
r->calculateExtremalSizes();
|
|
Shinya Kitaoka |
120a6e |
return QSize(r->m_maximumSize[0], r->m_maximumSize[1]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
QSize DockLayout::sizeHint() const {
|
|
Shinya Kitaoka |
120a6e |
QSize s(0, 0);
|
|
Shinya Kitaoka |
120a6e |
int n = m_items.size();
|
|
Shinya Kitaoka |
120a6e |
if (n > 0) s = QSize(100, 70); // start with a nice default size
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
while (i < n) {
|
|
Shinya Kitaoka |
120a6e |
QLayoutItem *o = m_items[i];
|
|
Shinya Kitaoka |
120a6e |
s = s.expandedTo(o->sizeHint());
|
|
Shinya Kitaoka |
120a6e |
++i;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return s + n * QSize(spacing(), spacing());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// return QSize(0,0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------
|
|
Toshihiro Shimizu |
890ddd |
// Custom methods
|
|
Toshihiro Shimizu |
890ddd |
//----------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QWidget *DockLayout::containerOf(QPoint point) const {
|
|
Shinya Kitaoka |
120a6e |
// Search among regions, from leaf regions to root.
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
unsigned int j;
|
|
Shinya Kitaoka |
120a6e |
for (i = m_regions.size() - 1; i >= 0; --i) {
|
|
Shinya Kitaoka |
120a6e |
Region *currRegion = m_regions[i];
|
|
Shinya Kitaoka |
120a6e |
DockWidget *item = currRegion->getItem();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First check if item contains it
|
|
Shinya Kitaoka |
120a6e |
if (item && item->geometry().contains(point)) return currRegion->getItem();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Then, search among separators
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < currRegion->separators().size(); ++j)
|
|
Shinya Kitaoka |
120a6e |
if (currRegion->separator(j)->geometry().contains(point))
|
|
Shinya Kitaoka |
120a6e |
return currRegion->separator(j);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
void DockLayout::setMaximized(DockWidget *item, bool state) {
|
|
Shinya Kitaoka |
120a6e |
if (item && state != item->m_maximized) {
|
|
Shinya Kitaoka |
120a6e |
if (state) {
|
|
Shinya Kitaoka |
120a6e |
// Maximize
|
|
Shinya Kitaoka |
120a6e |
if (m_maximizedDock) {
|
|
Shinya Kitaoka |
120a6e |
// If maximized already exists, normalize it
|
|
Shinya Kitaoka |
120a6e |
Region *r = find(m_maximizedDock);
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock->setGeometry(toRect(r->getGeometry()));
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock->m_maximized = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now, attempt requested item maximization
|
|
Shinya Kitaoka |
120a6e |
QSize minimumSize = item->minimumSize();
|
|
Shinya Kitaoka |
120a6e |
QSize maximumSize = item->maximumSize();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (contentsRect().width() > minimumSize.width() &&
|
|
Shinya Kitaoka |
120a6e |
contentsRect().height() > minimumSize.height() &&
|
|
Shinya Kitaoka |
120a6e |
contentsRect().width() < maximumSize.width() &&
|
|
Shinya Kitaoka |
120a6e |
contentsRect().height() < maximumSize.height()) {
|
|
Shinya Kitaoka |
120a6e |
// Maximization succeeds
|
|
Shinya Kitaoka |
120a6e |
item->setGeometry(contentsRect());
|
|
Shinya Kitaoka |
120a6e |
item->raise();
|
|
Shinya Kitaoka |
120a6e |
item->m_maximized = true;
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock = item;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Hide all the other docked widgets (no need to update them. Moreover,
|
|
Shinya Kitaoka |
120a6e |
// doing so
|
|
Shinya Kitaoka |
120a6e |
// could eventually result in painting over the newly maximized widget)
|
|
Shinya Kitaoka |
120a6e |
DockWidget *currWidget;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
currWidget = (DockWidget *)itemAt(i)->widget();
|
|
Shinya Kitaoka |
120a6e |
if (currWidget != item && !currWidget->isFloating())
|
|
Shinya Kitaoka |
120a6e |
currWidget->hide();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Normalize
|
|
Shinya Kitaoka |
120a6e |
Region *r = find(m_maximizedDock);
|
|
Shinya Kitaoka |
120a6e |
if (r) m_maximizedDock->setGeometry(toRect(r->getGeometry()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock->m_maximized = false;
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Show all other docked widgets
|
|
Shinya Kitaoka |
120a6e |
DockWidget *currWidget;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
currWidget = (DockWidget *)itemAt(i)->widget();
|
|
Shinya Kitaoka |
120a6e |
if (currWidget != item && !currWidget->isFloating()) currWidget->show();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//======================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//======================================
|
|
Toshihiro Shimizu |
890ddd |
// Layout Geometry Handler
|
|
Toshihiro Shimizu |
890ddd |
//======================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! NOTE: This method is currently unused by DockLayout implementation...
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::setGeometry(const QRect &rect) {
|
|
Shinya Kitaoka |
120a6e |
// Just pass the info to the widget (it's somehow necessary...)
|
|
Shinya Kitaoka |
120a6e |
QLayout::setGeometry(rect);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Defines cursors for separators of the layout: if it is not possible to
|
|
Shinya Kitaoka |
120a6e |
//! move a separator, its cursor must be an arrow.
|
|
Shinya Kitaoka |
d1f6c4 |
void DockLayout::updateSeparatorCursors() {
|
|
Shinya Kitaoka |
120a6e |
Region *r, *child;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int i, j;
|
|
Shinya Kitaoka |
120a6e |
int k, jInt;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
r = m_regions[i];
|
|
Shinya Kitaoka |
120a6e |
bool orientation = r->getOrientation();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If region geometry is minimal or maximal, its separators are blocked
|
|
Shinya Kitaoka |
120a6e |
// NOTE: If this update follows only from a dock/undock, this should be
|
|
Shinya Kitaoka |
120a6e |
// disabled 'til 'Otherwise'
|
|
Shinya Kitaoka |
120a6e |
QSize size = toRect(r->getGeometry()).size();
|
|
Shinya Kitaoka |
120a6e |
bool isExtremeSize =
|
|
Shinya Kitaoka |
120a6e |
(orientation == Region::horizontal)
|
|
Shinya Kitaoka |
120a6e |
? size.width() == r->getMinimumSize(Region::horizontal) ||
|
|
Shinya Kitaoka |
120a6e |
size.width() == r->getMaximumSize(Region::horizontal)
|
|
Shinya Kitaoka |
120a6e |
: size.height() == r->getMinimumSize(Region::vertical) ||
|
|
Shinya Kitaoka |
120a6e |
size.height() == r->getMaximumSize(Region::vertical);
|
|
Shinya Kitaoka |
120a6e |
if (isExtremeSize) {
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < r->separators().size(); ++j)
|
|
Shinya Kitaoka |
120a6e |
r->separator(j)->setCursor(Qt::ArrowCursor);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Otherwise...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Arrowize all separators as long as the preceding region has equal
|
|
Shinya Kitaoka |
120a6e |
// maximum and minimum sizes
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < r->getChildList().size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
child = r->childRegion(j);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (child->getMaximumSize(orientation) ==
|
|
Shinya Kitaoka |
120a6e |
child->getMinimumSize(orientation))
|
|
Shinya Kitaoka |
120a6e |
r->separator(j)->setCursor(Qt::ArrowCursor);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
jInt = j;
|
|
Shinya Kitaoka |
120a6e |
// The same as above in reverse order
|
|
Shinya Kitaoka |
120a6e |
for (k = r->getChildList().size() - 1; k > jInt; --k) {
|
|
Shinya Kitaoka |
120a6e |
child = r->childRegion(k);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (child->getMaximumSize(orientation) ==
|
|
Shinya Kitaoka |
120a6e |
child->getMinimumSize(orientation))
|
|
Shinya Kitaoka |
120a6e |
r->separator(k - 1)->setCursor(Qt::ArrowCursor);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Middle separators have a split cursor
|
|
Shinya Kitaoka |
120a6e |
Qt::CursorShape shape = (orientation == Region::horizontal)
|
|
Shinya Kitaoka |
120a6e |
? Qt::SplitHCursor
|
|
Shinya Kitaoka |
120a6e |
: Qt::SplitVCursor;
|
|
Shinya Kitaoka |
120a6e |
for (; jInt < k; ++jInt) r->separator(jInt)->setCursor(shape);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Applies Regions geometry to dock widgets and separators.
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::applyGeometry() {
|
|
Shinya Kitaoka |
120a6e |
// Update docked window's geometries
|
|
Shinya Kitaoka |
120a6e |
unsigned int i, j;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_regions[i];
|
|
Shinya Kitaoka |
120a6e |
const std::deque<region *=""> &childList = r->getChildList();</region>
|
|
Shinya Kitaoka |
120a6e |
std::deque<dockseparator *=""> &sepList = r->m_separators;</dockseparator>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_regions[i]->getItem()) {
|
|
Shinya Kitaoka |
120a6e |
m_regions[i]->getItem()->setGeometry(toRect(m_regions[i]->getGeometry()));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < sepList.size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
QRect leftAdjRect = toRect(childList[j]->getGeometry());
|
|
Shinya Kitaoka |
120a6e |
if (r->getOrientation() == Region::horizontal) {
|
|
Shinya Kitaoka |
120a6e |
leftAdjRect.adjust(0, 0, 1, 0); // Take adjacent-to topRight pixel
|
|
Shinya Kitaoka |
120a6e |
sepList[j]->setGeometry(QRect(
|
|
Shinya Kitaoka |
120a6e |
leftAdjRect.topRight(), QSize(spacing(), leftAdjRect.height())));
|
|
Shinya Kitaoka |
120a6e |
sepList[j]->m_index = j;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
leftAdjRect.adjust(0, 0, 0, 1);
|
|
Shinya Kitaoka |
120a6e |
sepList[j]->setGeometry(QRect(leftAdjRect.bottomLeft(),
|
|
Shinya Kitaoka |
120a6e |
QSize(leftAdjRect.width(), spacing())));
|
|
Shinya Kitaoka |
120a6e |
sepList[j]->m_index = j;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If there is a maximized widget, reset its geometry to that of the main
|
|
Shinya Kitaoka |
120a6e |
// region
|
|
Shinya Kitaoka |
120a6e |
if (m_maximizedDock) {
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock->setGeometry(toRect(m_regions[0]->getGeometry()));
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock->raise();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, update separator cursors.
|
|
Shinya Kitaoka |
120a6e |
updateSeparatorCursors();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::applyTransform(const QTransform &transform) {
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
m_regions[i]->setGeometry(transform.mapRect(m_regions[i]->getGeometry()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::redistribute() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_regions.empty()) {
|
|
Shinya Kitaoka |
120a6e |
// Recompute extremal region sizes
|
|
Shinya Kitaoka |
120a6e |
// NOTA: Sarebbe da fare solo se un certo flag lo richiede; altrimenti tipo
|
|
Shinya Kitaoka |
120a6e |
// per resize events e' inutile...
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->calculateExtremalSizes();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int parentWidth = contentsRect().width();
|
|
Shinya Kitaoka |
120a6e |
int parentHeight = contentsRect().height();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Always check main window consistency before effective redistribution. DO
|
|
Shinya Kitaoka |
120a6e |
// NOT ERASE or crashes may occur...
|
|
Shinya Kitaoka |
120a6e |
if (m_regions.front()->getMinimumSize(Region::horizontal) > parentWidth ||
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->getMinimumSize(Region::vertical) > parentHeight ||
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->getMaximumSize(Region::horizontal) < parentWidth ||
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->getMaximumSize(Region::vertical) < parentHeight)
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Recompute Layout geometry
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->setGeometry(contentsRect());
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->redistribute();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, apply Region geometries found
|
|
Shinya Kitaoka |
120a6e |
applyGeometry();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//======================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================
|
|
Toshihiro Shimizu |
890ddd |
// Region implementation
|
|
Toshihiro Shimizu |
890ddd |
//=============================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Region::~Region() {
|
|
Shinya Kitaoka |
120a6e |
// Delete separators
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_separators.size(); ++i) delete m_separators[i];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Inserts DockSeparator \b sep in \b this Region
|
|
Shinya Kitaoka |
d1f6c4 |
void Region::insertSeparator(DockSeparator *sep) {
|
|
Shinya Kitaoka |
120a6e |
m_separators.push_back(sep);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Removes a DockSeparator from \b this Region
|
|
Shinya Kitaoka |
d1f6c4 |
void Region::removeSeparator() {
|
|
Shinya Kitaoka |
120a6e |
delete m_separators.back();
|
|
Shinya Kitaoka |
120a6e |
m_separators.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
void Region::insertSubRegion(Region *subRegion, int idx) {
|
|
Shinya Kitaoka |
120a6e |
m_childList.insert(m_childList.begin() + idx, subRegion);
|
|
Shinya Kitaoka |
120a6e |
subRegion->m_parent = this;
|
|
Shinya Kitaoka |
120a6e |
subRegion->m_orientation = !m_orientation;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Inserts input \b item before position \b idx. Returns associated new region.
|
|
Shinya Kitaoka |
d1f6c4 |
Region *Region::insertItem(DockWidget *item, int idx) {
|
|
Shinya Kitaoka |
120a6e |
Region *newRegion = new Region(m_owner, item);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (this) insertSubRegion(newRegion, idx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return newRegion;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
unsigned int Region::find(const Region *subRegion) const {
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
if (m_childList[i] == subRegion) return i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Region *DockLayout::find(DockWidget *item) const {
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
if (m_regions[i]->getItem() == item) return m_regions[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Calculates possible docking solutions for \b this
|
|
Shinya Kitaoka |
120a6e |
//! dock widget. They are stored into the dock widget.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b NOTE: Placeholders are here calculated by decreasing importance;
|
|
Shinya Kitaoka |
120a6e |
//! in other words, if two rects are part of the layout, and the first
|
|
Shinya Kitaoka |
120a6e |
//! contains the second, placeholders of the first are found before
|
|
Shinya Kitaoka |
120a6e |
//! those of the second. This fact may be exploited when selecting an
|
|
Shinya Kitaoka |
120a6e |
//! appropriate placeholder for docking.
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::calculateDockPlaceholders(DockWidget *item) {
|
|
Shinya Kitaoka |
120a6e |
assert(item);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If the DockLayout's owner widget is hidden, avoid
|
|
Shinya Kitaoka |
120a6e |
if (!parentWidget()->isVisible()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_regions.size()) {
|
|
Shinya Kitaoka |
120a6e |
if (isPossibleInsertion(item, 0, 0)) {
|
|
Shinya Kitaoka |
120a6e |
// Then insert a root placeholder only
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, 0, 0, DockPlaceholder::root));
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// For all regions (and for all insertion index), check if
|
|
Shinya Kitaoka |
120a6e |
// insertion may succeed.
|
|
Shinya Kitaoka |
120a6e |
// NOTE: Insertion chance is just the same for all indexes in a given
|
|
Shinya Kitaoka |
120a6e |
// parent region...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First check parentRegion=0 (under a new Root - External cases)
|
|
Shinya Kitaoka |
120a6e |
if (isPossibleInsertion(item, 0, 0)) {
|
|
Shinya Kitaoka |
120a6e |
QRect contRect = contentsRect();
|
|
Shinya Kitaoka |
120a6e |
if (m_regions.front()->getOrientation() == Region::horizontal) {
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, 0, 0, DockPlaceholder::top));
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, 0, 1, DockPlaceholder::bottom));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, 0, 0, DockPlaceholder::left));
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, 0, 1, DockPlaceholder::right));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_regions[i];
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isPossibleInsertion(item, r, 0)) {
|
|
Shinya Kitaoka |
120a6e |
unsigned int j;
|
|
Shinya Kitaoka |
120a6e |
QRect cellRect;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// For all indices, insert a placeholder
|
|
Shinya Kitaoka |
120a6e |
if (r->getOrientation() == Region::horizontal) {
|
|
Shinya Kitaoka |
120a6e |
// Left side
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, r, 0, DockPlaceholder::left));
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.push_back(item->m_placeholders.back());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Separators
|
|
Shinya Kitaoka |
120a6e |
for (j = 1; j < r->getChildList().size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, r, j, DockPlaceholder::sepVert));
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.push_back(item->m_placeholders.back());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Right side
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, r, j, DockPlaceholder::right));
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.push_back(item->m_placeholders.back());
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Top side
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, r, 0, DockPlaceholder::top));
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.push_back(item->m_placeholders.back());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (j = 1; j < r->getChildList().size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, r, j, DockPlaceholder::sepHor));
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.push_back(item->m_placeholders.back());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Bottom side
|
|
Shinya Kitaoka |
120a6e |
item->m_placeholders.push_back(item->m_decoAllocator->newPlaceBuilt(
|
|
Shinya Kitaoka |
120a6e |
item, r, j, DockPlaceholder::bottom));
|
|
Shinya Kitaoka |
120a6e |
r->m_placeholders.push_back(item->m_placeholders.back());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Disable all placeholders
|
|
Shinya Kitaoka |
120a6e |
// for(i=0; i<item->m_placeholders.size(); ++i)</item->
|
|
Shinya Kitaoka |
120a6e |
// item->m_placeholders[i]->setDisabled(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Docks input \b item before position \b idx of region \b r. Deals with
|
|
Shinya Kitaoka |
120a6e |
//! overall region hierarchy.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b NOTE: Docked items are forcedly shown.
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::dockItem(DockWidget *item, DockPlaceholder *place) {
|
|
Shinya Kitaoka |
120a6e |
place->hide();
|
|
Shinya Kitaoka |
120a6e |
item->hide();
|
|
Shinya Kitaoka |
120a6e |
dockItemPrivate(item, place->m_region, place->m_idx);
|
|
Shinya Kitaoka |
120a6e |
redistribute();
|
|
Shinya Kitaoka |
120a6e |
parentWidget()->repaint();
|
|
Shinya Kitaoka |
120a6e |
item->setWindowFlags(Qt::SubWindow);
|
|
Shinya Kitaoka |
120a6e |
item->show();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Docks input \b item at side \b regionside of \b target dock widget.
|
|
Shinya Kitaoka |
120a6e |
//! RegionSide can be Region::left, right, top or bottom.
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::dockItem(DockWidget *item, DockWidget *target,
|
|
Shinya Kitaoka |
120a6e |
int regionSide) {
|
|
Shinya Kitaoka |
120a6e |
Region *targetRegion = find(target);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
short var = regionSide >> 2 * (int)targetRegion->getOrientation();
|
|
Shinya Kitaoka |
120a6e |
bool pos = regionSide & 0xa;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item->setWindowFlags(Qt::SubWindow);
|
|
Shinya Kitaoka |
120a6e |
item->show();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (var & 0x3) {
|
|
Shinya Kitaoka |
120a6e |
// Side is coherent with orientation => Direct insertion at position 0 or 1
|
|
Shinya Kitaoka |
120a6e |
dockItemPrivate(item, targetRegion, pos);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Side is not coherent - have to find target's index in parent region
|
|
Shinya Kitaoka |
120a6e |
Region *parentRegion = targetRegion->getParent();
|
|
Shinya Kitaoka |
120a6e |
unsigned int idx =
|
|
Shinya Kitaoka |
120a6e |
parentRegion ? parentRegion->find(targetRegion) + pos : pos;
|
|
Shinya Kitaoka |
120a6e |
dockItemPrivate(item, parentRegion, idx);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Docks input \b item into Region \b r, at position \b idx; returns region
|
|
Shinya Kitaoka |
120a6e |
//! corresponding to
|
|
Shinya Kitaoka |
120a6e |
//! newly inserted item.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b NOTE: Unlike dockItem(DockWidget*,DockPlaceholder*) and undockItem, this
|
|
Shinya Kitaoka |
120a6e |
//! method is supposedly called directly into application code; therefore, no \b
|
|
Shinya Kitaoka |
120a6e |
//! redistribution
|
|
Shinya Kitaoka |
120a6e |
//! is done after a single dock - you are supposed to manually call
|
|
Shinya Kitaoka |
120a6e |
//! redistribute() after
|
|
Shinya Kitaoka |
120a6e |
//! all widgets have been docked.
|
|
Shinya Kitaoka |
120a6e |
Region *DockLayout::dockItem(DockWidget *item, Region *r, int idx) {
|
|
Shinya Kitaoka |
120a6e |
item->setWindowFlags(Qt::SubWindow);
|
|
Shinya Kitaoka |
120a6e |
item->show();
|
|
Shinya Kitaoka |
120a6e |
return dockItemPrivate(item, r, idx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Internal docking function. Contains raw docking code, excluded reparenting
|
|
Shinya Kitaoka |
120a6e |
// (setWindowFlags)
|
|
Shinya Kitaoka |
120a6e |
// which may slow down a bit - should be done only after a redistribute() and a
|
|
Shinya Kitaoka |
120a6e |
// repaint() on
|
|
Shinya Kitaoka |
120a6e |
// real-time docking.
|
|
Shinya Kitaoka |
d1f6c4 |
Region *DockLayout::dockItemPrivate(DockWidget *item, Region *r,
|
|
Shinya Kitaoka |
120a6e |
int idx) {
|
|
Shinya Kitaoka |
120a6e |
// hide minimize button in FlipboolPanel
|
|
Shinya Kitaoka |
120a6e |
item->onDock(true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item->setDockedAppearance();
|
|
Shinya Kitaoka |
120a6e |
item->m_floating = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!r) {
|
|
Shinya Kitaoka |
120a6e |
// Insert new root region
|
|
Shinya Kitaoka |
120a6e |
Region *newRoot = new Region(this);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_regions.push_front(newRoot);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
newRoot->setSize(item->size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_regions.size() == 1) {
|
|
Shinya Kitaoka |
120a6e |
newRoot->setItem(item);
|
|
Shinya Kitaoka |
120a6e |
return newRoot;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
newRoot->setOrientation(!m_regions[1]->getOrientation());
|
|
Shinya Kitaoka |
120a6e |
newRoot->insertSubRegion(m_regions[1], 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
r = newRoot;
|
|
Shinya Kitaoka |
120a6e |
} else if (r->getItem()) {
|
|
Shinya Kitaoka |
120a6e |
// Then the Layout gets further subdived - r's item has to be moved
|
|
Shinya Kitaoka |
120a6e |
Region *regionForOldItem = r->insertItem(r->getItem(), 0);
|
|
Shinya Kitaoka |
120a6e |
regionForOldItem->setSize(r->getItem()->size());
|
|
Shinya Kitaoka |
120a6e |
// regionForOldItem->setSize(r->getItem()->frameSize());
|
|
Shinya Kitaoka |
120a6e |
r->setItem(0);
|
|
Shinya Kitaoka |
120a6e |
m_regions.push_back(regionForOldItem);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Region *newRegion = r->insertItem(item, idx);
|
|
Shinya Kitaoka |
120a6e |
m_regions.push_back(newRegion);
|
|
Shinya Kitaoka |
120a6e |
// Temporarily setting suggested size for newly inserted region
|
|
Shinya Kitaoka |
120a6e |
newRegion->setSize(item->size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, insert a new DockSeparator in parent region r.
|
|
Shinya Kitaoka |
120a6e |
r->insertSeparator(
|
|
Shinya Kitaoka |
120a6e |
m_decoAllocator->newSeparator(this, r->getOrientation(), r));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return newRegion;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! A region is empty, if contains no item and no children.
|
|
Shinya Kitaoka |
d1f6c4 |
bool isEmptyRegion(Region *r) {
|
|
Shinya Kitaoka |
120a6e |
if ((!r->getItem()) && (r->getChildList().size() == 0)) {
|
|
Shinya Kitaoka |
120a6e |
delete r; // Be', e' un po' improprio, ma funziona...
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Removes input item from region
|
|
Shinya Kitaoka |
d1f6c4 |
void Region::removeItem(DockWidget *item) {
|
|
Shinya Kitaoka |
120a6e |
if (item == 0) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
if (item == m_childList[i]->getItem()) {
|
|
Shinya Kitaoka |
120a6e |
m_childList.erase(m_childList.begin() + i);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
removeSeparator();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// parent Region may collapse; then move item back to parent and update
|
|
Shinya Kitaoka |
120a6e |
// its parent
|
|
Shinya Kitaoka |
120a6e |
if (m_childList.size() == 1) {
|
|
Shinya Kitaoka |
120a6e |
Region *parent = getParent();
|
|
Shinya Kitaoka |
120a6e |
if (parent) {
|
|
Shinya Kitaoka |
120a6e |
Region *remainingSon = m_childList[0];
|
|
Shinya Kitaoka |
120a6e |
if (!remainingSon->m_childList.size()) {
|
|
Shinya Kitaoka |
120a6e |
// remainingSon is a leaf: better keep this and move son's item and
|
|
Shinya Kitaoka |
120a6e |
// childList
|
|
Shinya Kitaoka |
120a6e |
setItem(remainingSon->getItem());
|
|
Shinya Kitaoka |
120a6e |
remainingSon->setItem(0);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// remainingSon is a branch: append remainingSon childList to parent
|
|
Shinya Kitaoka |
120a6e |
// one and
|
|
Shinya Kitaoka |
120a6e |
// sign this and remainingSon nodes for destruction.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First find this position in parent
|
|
Shinya Kitaoka |
120a6e |
unsigned int j = parent->find(this);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
parent->m_childList.erase(parent->m_childList.begin() + j);
|
|
Shinya Kitaoka |
120a6e |
parent->m_childList.insert(parent->m_childList.begin() + j,
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_childList.begin(),
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_childList.end());
|
|
Shinya Kitaoka |
120a6e |
parent->m_separators.insert(parent->m_separators.begin() + j,
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_separators.begin(),
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_separators.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Update remainingSon children's and DockSeparator's parent
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < remainingSon->m_childList.size(); ++j)
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_childList[j]->m_parent = parent;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < remainingSon->m_separators.size(); ++j)
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_separators[j]->m_parentRegion = parent;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_childList.clear();
|
|
Shinya Kitaoka |
120a6e |
remainingSon->m_separators.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Root case; better keep the remaining child
|
|
Shinya Kitaoka |
120a6e |
m_childList[0]->setParent(0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_childList.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Undocks \b item and updates geometry.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//!\b NOTE: Window flags are resetted to floating appearance (thus hiding the
|
|
Shinya Kitaoka |
38fd86 |
//! widget). Since the geometry
|
|
Shinya Kitaoka |
120a6e |
//! reference changes a geometry() update may be needed - so item's show() is
|
|
Shinya Kitaoka |
120a6e |
//! not forced here. You should
|
|
Shinya Kitaoka |
120a6e |
//! eventually remember to call it manually after this.
|
|
Shinya Kitaoka |
120a6e |
bool DockLayout::undockItem(DockWidget *item) {
|
|
Shinya Kitaoka |
120a6e |
// Find item's region index in m_regions
|
|
Shinya Kitaoka |
120a6e |
Region *itemCarrier = find(item);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Region *parent = itemCarrier->getParent();
|
|
Shinya Kitaoka |
120a6e |
if (parent) {
|
|
Shinya Kitaoka |
120a6e |
int removalIdx = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Find removal index in parent's childList
|
|
Shinya Kitaoka |
120a6e |
unsigned int j;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < parent->getChildList().size(); ++j)
|
|
Shinya Kitaoka |
120a6e |
if (parent->getChildList()[j]->getItem() == item) break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (isPossibleRemoval(item, parent, removalIdx))
|
|
Shinya Kitaoka |
120a6e |
parent->removeItem(item);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Remove region in regions list
|
|
Shinya Kitaoka |
120a6e |
// m_regions.erase(i); //Don't - m_regions is cleaned before the end by
|
|
Shinya Kitaoka |
120a6e |
// remove_if
|
|
Shinya Kitaoka |
120a6e |
itemCarrier->setItem(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::deque<region *="">::iterator j;</region>
|
|
Shinya Kitaoka |
120a6e |
j = std::remove_if(m_regions.begin(), m_regions.end(), isEmptyRegion);
|
|
Shinya Kitaoka |
120a6e |
m_regions.resize(j - m_regions.begin());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Update status
|
|
Shinya Kitaoka |
120a6e |
// qDebug("Undock");
|
|
Shinya Kitaoka |
120a6e |
item->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
|
Shinya Kitaoka |
120a6e |
// NOTA: Usando la flag Qt::Window il focus viene automaticamente riassegnato,
|
|
Shinya Kitaoka |
120a6e |
// con un po' di ritardo.
|
|
Shinya Kitaoka |
120a6e |
// Usando Tool questo non accade. In questo caso, i placeholder devono essere
|
|
Shinya Kitaoka |
120a6e |
// disattivati...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
item->setFloatingAppearance();
|
|
Shinya Kitaoka |
120a6e |
item->m_floating = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// show minimize button in FlipbookPanel
|
|
Shinya Kitaoka |
120a6e |
item->onDock(false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setMaximized(item, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
redistribute();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Search for the \b nearest n-ple from a \b target one, under conditions:
|
|
Shinya Kitaoka |
120a6e |
//!\b 1) nearest elements belong to \b fixed \b intervals; \b 2) their \b sum is
|
|
Shinya Kitaoka |
120a6e |
//!\b fixed too.
|
|
Shinya Kitaoka |
d1f6c4 |
void calculateNearest(std::vector<double> target,</double>
|
|
Shinya Kitaoka |
d1f6c4 |
std::vector<double> &nearest,</double>
|
|
Shinya Kitaoka |
d1f6c4 |
std::vector<std::pair<int, int="">> intervals,</std::pair<int,>
|
|
Shinya Kitaoka |
d1f6c4 |
double sum) {
|
|
Shinya Kitaoka |
120a6e |
// Solving a small Lagrange multipliers problem to find solution on constraint
|
|
Shinya Kitaoka |
120a6e |
// (2)
|
|
Shinya Kitaoka |
120a6e |
assert(target.size() == intervals.size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double targetSum = 0;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < target.size(); ++i) targetSum += target[i];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double multiplier = (sum - targetSum) / (double)target.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
nearest.resize(target.size());
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < target.size(); ++i) nearest[i] = target[i] + multiplier;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now, constraint (1) is not met; however, satisfying also (2) yields a
|
|
Shinya Kitaoka |
120a6e |
// hyperRect
|
|
Shinya Kitaoka |
120a6e |
// on which we must find the nearest point to our above partial solution. In
|
|
Shinya Kitaoka |
120a6e |
// particular,
|
|
Shinya Kitaoka |
120a6e |
// it can be demonstrated that at least one coordinate of the current partial
|
|
Shinya Kitaoka |
120a6e |
// solution is related
|
|
Shinya Kitaoka |
120a6e |
// to the final one (...). This mean that we may have to solve sub-problems of
|
|
Shinya Kitaoka |
120a6e |
// this same kind,
|
|
Shinya Kitaoka |
120a6e |
// with less variable coordinates.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int max;
|
|
Shinya Kitaoka |
120a6e |
double distance, maxDistance = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < target.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (nearest[i] < intervals[i].first || nearest[i] > intervals[i].second) {
|
|
Shinya Kitaoka |
120a6e |
distance = nearest[i] < intervals[i].first
|
|
Shinya Kitaoka |
120a6e |
? intervals[i].first - nearest[i]
|
|
Shinya Kitaoka |
120a6e |
: nearest[i] - intervals[i].second;
|
|
Shinya Kitaoka |
120a6e |
nearest[i] = nearest[i] < intervals[i].first ? intervals[i].first
|
|
Shinya Kitaoka |
120a6e |
: intervals[i].second;
|
|
Shinya Kitaoka |
120a6e |
if (maxDistance < distance) {
|
|
Shinya Kitaoka |
120a6e |
maxDistance = distance;
|
|
Shinya Kitaoka |
120a6e |
max = i;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> newTarget = target;</double>
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> newNearest;</double>
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<int, int="">> newIntervals = intervals;</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (maxDistance) {
|
|
Shinya Kitaoka |
120a6e |
newTarget.erase(newTarget.begin() + max);
|
|
Shinya Kitaoka |
120a6e |
newIntervals.erase(newIntervals.begin() + max);
|
|
Shinya Kitaoka |
120a6e |
sum -= nearest[max];
|
|
Shinya Kitaoka |
120a6e |
calculateNearest(newTarget, newNearest, newIntervals, sum);
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < max; ++i) nearest[i] = newNearest[i];
|
|
Shinya Kitaoka |
120a6e |
for (i = max + 1; i < nearest.size(); ++i) nearest[i] = newNearest[i - 1];
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Equally redistribute separators and children regions' internal geometry
|
|
Shinya Kitaoka |
120a6e |
//! according to current subregion sizes.
|
|
Shinya Kitaoka |
120a6e |
void Region::redistribute() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_childList.size()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool expansion = m_minimumSize[Region::horizontal] > m_rect.width() ||
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[Region::vertical] > m_rect.height();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double regionSize[2];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If there is no need to expand this region, maintain current geometry;
|
|
Shinya Kitaoka |
120a6e |
// otherwise, expand at minimum.
|
|
Shinya Kitaoka |
120a6e |
regionSize[Region::horizontal] =
|
|
Shinya Kitaoka |
120a6e |
expansion ? m_minimumSize[Region::horizontal] : m_rect.width();
|
|
Shinya Kitaoka |
120a6e |
regionSize[Region::vertical] =
|
|
Shinya Kitaoka |
120a6e |
expansion ? m_minimumSize[Region::vertical] : m_rect.height();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// However, expansion in the oriented direction has to take care of parent's
|
|
Shinya Kitaoka |
120a6e |
// consense.
|
|
Shinya Kitaoka |
120a6e |
if (m_parent != 0)
|
|
Shinya Kitaoka |
120a6e |
regionSize[m_orientation] =
|
|
Shinya Kitaoka |
120a6e |
std::min((double)m_parent->m_maximumSize[m_orientation],
|
|
Shinya Kitaoka |
120a6e |
regionSize[m_orientation]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now find nearest-to-preferred window sizes, according to size constraints.
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First build target sizes vector
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> targetSizes(m_childList.size());</double>
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
// Assuming preferred sizes are those already present before redistribution.
|
|
Shinya Kitaoka |
120a6e |
targetSizes[i] = (m_orientation == Region::horizontal)
|
|
Shinya Kitaoka |
120a6e |
? m_childList[i]->m_rect.width()
|
|
Shinya Kitaoka |
120a6e |
: m_childList[i]->m_rect.height();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build minimum and maximum size constraints
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<int, int="">> sizeIntervals(m_childList.size());</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
sizeIntervals[i].first = m_childList[i]->m_minimumSize[m_orientation];
|
|
Shinya Kitaoka |
120a6e |
sizeIntervals[i].second = m_childList[i]->m_maximumSize[m_orientation];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build width sum
|
|
Shinya Kitaoka |
120a6e |
int separatorWidth = m_owner->spacing();
|
|
Shinya Kitaoka |
120a6e |
double sum =
|
|
Shinya Kitaoka |
120a6e |
regionSize[m_orientation] - (m_childList.size() - 1) * separatorWidth;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> nearestSizes;</double>
|
|
Shinya Kitaoka |
120a6e |
calculateNearest(targetSizes, nearestSizes, sizeIntervals, sum);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// NearestSizes stores optimal subregion sizes; calculate their geometries and
|
|
Shinya Kitaoka |
120a6e |
// assign them.
|
|
Shinya Kitaoka |
120a6e |
QPointF topLeftCorner = m_rect.topLeft();
|
|
Shinya Kitaoka |
120a6e |
if (m_orientation == horizontal) {
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
QSizeF currSize = QSizeF(nearestSizes[i], regionSize[vertical]);
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->setGeometry(QRectF(topLeftCorner, currSize));
|
|
Shinya Kitaoka |
120a6e |
topLeftCorner =
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->getGeometry().topRight() + QPointF(separatorWidth, 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
QSizeF currSize = QSizeF(regionSize[horizontal], nearestSizes[i]);
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->setGeometry(QRectF(topLeftCorner, currSize));
|
|
Shinya Kitaoka |
120a6e |
topLeftCorner = m_childList[i]->getGeometry().bottomLeft() +
|
|
Shinya Kitaoka |
120a6e |
QPointF(0, separatorWidth);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, redistribute region's children
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) m_childList[i]->redistribute();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Calculates maximum and minimum sizes for each sub-region.
|
|
Shinya Kitaoka |
120a6e |
void Region::calculateExtremalSizes() {
|
|
Shinya Kitaoka |
120a6e |
calculateMinimumSize(horizontal, true);
|
|
Shinya Kitaoka |
120a6e |
calculateMinimumSize(vertical, true);
|
|
Shinya Kitaoka |
120a6e |
calculateMaximumSize(horizontal, true);
|
|
Shinya Kitaoka |
120a6e |
calculateMaximumSize(vertical, true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Calculates minimum occupiable space in \b this region on given \b direction.
|
|
Shinya Kitaoka |
120a6e |
//! Also stores cache for it.
|
|
Shinya Kitaoka |
120a6e |
int Region::calculateMinimumSize(bool direction, bool recalcChildren) {
|
|
Shinya Kitaoka |
120a6e |
int sumMinSizes = 0, maxMinSizes = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_item) {
|
|
Shinya Kitaoka |
120a6e |
sumMinSizes = maxMinSizes = (direction == horizontal)
|
|
Shinya Kitaoka |
120a6e |
? m_item->minimumSize().width()
|
|
Shinya Kitaoka |
120a6e |
: m_item->minimumSize().height();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
int currMinSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If required, recalculate children sizes along our direction.
|
|
Shinya Kitaoka |
120a6e |
if (recalcChildren) {
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->calculateMinimumSize(direction, true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
sumMinSizes += currMinSize = m_childList[i]->getMinimumSize(direction);
|
|
Shinya Kitaoka |
120a6e |
if (maxMinSizes < currMinSize) maxMinSizes = currMinSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add separators width
|
|
Shinya Kitaoka |
120a6e |
sumMinSizes += m_separators.size() * m_owner->spacing();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If m_orientation is coherent with input direction, minimum occupied space
|
|
Shinya Kitaoka |
120a6e |
// is the sum
|
|
Shinya Kitaoka |
120a6e |
// of childs' minimumSizes. Otherwise, the maximum is taken.
|
|
Shinya Kitaoka |
120a6e |
if (m_orientation == direction) {
|
|
Shinya Kitaoka |
120a6e |
return m_minimumSize[direction] = sumMinSizes;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
return m_minimumSize[direction] = maxMinSizes;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Calculates maximum occupiable space in \b this region on given \b direction.
|
|
Shinya Kitaoka |
120a6e |
//! Also stores cache for it.
|
|
Shinya Kitaoka |
120a6e |
// NOTE: Effectively the dual of calculateMinimumSize(int).
|
|
Shinya Kitaoka |
120a6e |
int Region::calculateMaximumSize(bool direction, bool recalcChildren) {
|
|
Shinya Kitaoka |
120a6e |
const int inf = 1000000;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int sumMaxSizes = 0, minMaxSizes = inf;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_item) {
|
|
Shinya Kitaoka |
120a6e |
sumMaxSizes = minMaxSizes = (direction == horizontal)
|
|
Shinya Kitaoka |
120a6e |
? m_item->maximumSize().width()
|
|
Shinya Kitaoka |
120a6e |
: m_item->maximumSize().height();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
int currMaxSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If required, recalculate children sizes along our direction.
|
|
Shinya Kitaoka |
120a6e |
if (recalcChildren) {
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->calculateMaximumSize(direction, true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
sumMaxSizes += currMaxSize = m_childList[i]->getMaximumSize(direction);
|
|
Shinya Kitaoka |
120a6e |
if (minMaxSizes > currMaxSize) minMaxSizes = currMaxSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add separators width
|
|
Shinya Kitaoka |
120a6e |
sumMaxSizes += m_separators.size() * m_owner->spacing();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If m_orientation is coherent with input direction, maximum occupied space
|
|
Shinya Kitaoka |
120a6e |
// is the sum
|
|
Shinya Kitaoka |
120a6e |
// of childs' maximumSizes. Otherwise, the minimum is taken.
|
|
Shinya Kitaoka |
120a6e |
if (m_orientation == direction) {
|
|
Shinya Kitaoka |
120a6e |
return m_maximumSize[direction] = sumMaxSizes;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
return m_maximumSize[direction] = minMaxSizes;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
bool Region::addItemSize(DockWidget *item) {
|
|
Shinya Kitaoka |
120a6e |
int sepWidth = m_owner->spacing();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_orientation == horizontal) {
|
|
Shinya Kitaoka |
120a6e |
// Add minimum and maximum horizontal sizes
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[horizontal] +=
|
|
Shinya Kitaoka |
120a6e |
item->getDockedMinimumSize().width() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[horizontal] +=
|
|
Shinya Kitaoka |
120a6e |
item->getDockedMaximumSize().width() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Make max and min with vertical extremal sizes
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical] = std::max(m_minimumSize[vertical],
|
|
Shinya Kitaoka |
120a6e |
item->getDockedMinimumSize().height());
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[vertical] = std::min(m_maximumSize[vertical],
|
|
Shinya Kitaoka |
120a6e |
item->getDockedMaximumSize().height());
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Viceversa
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical] += item->getDockedMinimumSize().height() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[vertical] += item->getDockedMaximumSize().height() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[horizontal] = std::max(m_minimumSize[horizontal],
|
|
Shinya Kitaoka |
120a6e |
item->getDockedMinimumSize().width());
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[horizontal] = std::min(m_maximumSize[horizontal],
|
|
Shinya Kitaoka |
120a6e |
item->getDockedMaximumSize().width());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_minimumSize[horizontal] > m_maximumSize[horizontal] ||
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical] > m_maximumSize[vertical])
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now, climb parent hierarchy and update extremal sizes. If minSizes get >
|
|
Shinya Kitaoka |
120a6e |
// maxSizes, return failed insertion
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_parent;
|
|
Shinya Kitaoka |
120a6e |
while (r) {
|
|
Shinya Kitaoka |
120a6e |
r->calculateMinimumSize(horizontal, false);
|
|
Shinya Kitaoka |
120a6e |
r->calculateMinimumSize(vertical, false);
|
|
Shinya Kitaoka |
120a6e |
r->calculateMaximumSize(horizontal, false);
|
|
Shinya Kitaoka |
120a6e |
r->calculateMaximumSize(vertical, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (r->getMinimumSize(horizontal) > r->getMaximumSize(horizontal) ||
|
|
Shinya Kitaoka |
120a6e |
r->getMinimumSize(vertical) > r->getMaximumSize(vertical))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
r = r->m_parent;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
bool Region::subItemSize(DockWidget *item) {
|
|
Shinya Kitaoka |
120a6e |
int sepWidth = m_owner->spacing();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_orientation == horizontal) {
|
|
Shinya Kitaoka |
120a6e |
// Subtract minimum and maximum horizontal sizes
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[horizontal] -= item->minimumSize().width() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[horizontal] -= item->maximumSize().width() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Recalculate opposite extremal sizes (without considering item)
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
if (m_childList[i]->getItem() != item) {
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical] = std::max(
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical], m_childList[i]->getMinimumSize(vertical));
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[vertical] = std::min(
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[vertical], m_childList[i]->getMaximumSize(vertical));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Viceversa
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical] -= item->minimumSize().height() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[vertical] -= item->maximumSize().height() + sepWidth;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Recalculate opposite extremal sizes (without considering item)
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
if (m_childList[i]->getItem() != item) {
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[horizontal] =
|
|
Shinya Kitaoka |
120a6e |
std::max(m_minimumSize[horizontal],
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->getMinimumSize(horizontal));
|
|
Shinya Kitaoka |
120a6e |
m_maximumSize[horizontal] =
|
|
Shinya Kitaoka |
120a6e |
std::min(m_maximumSize[horizontal],
|
|
Shinya Kitaoka |
120a6e |
m_childList[i]->getMaximumSize(horizontal));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_minimumSize[horizontal] > m_maximumSize[horizontal] ||
|
|
Shinya Kitaoka |
120a6e |
m_minimumSize[vertical] > m_maximumSize[vertical])
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now, climb parent hierarchy and update extremal sizes. If minSizes get >
|
|
Shinya Kitaoka |
120a6e |
// maxSizes, return failed insertion
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_parent;
|
|
Shinya Kitaoka |
120a6e |
while (r) {
|
|
Shinya Kitaoka |
120a6e |
r->calculateMinimumSize(horizontal, false);
|
|
Shinya Kitaoka |
120a6e |
r->calculateMinimumSize(vertical, false);
|
|
Shinya Kitaoka |
120a6e |
r->calculateMaximumSize(horizontal, false);
|
|
Shinya Kitaoka |
120a6e |
r->calculateMaximumSize(vertical, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (r->getMinimumSize(horizontal) > r->getMaximumSize(horizontal) ||
|
|
Shinya Kitaoka |
120a6e |
r->getMinimumSize(vertical) > r->getMaximumSize(vertical))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
r = r->m_parent;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Checks insertion validity of \b item inside \b parentRegion at position \b
|
|
Shinya Kitaoka |
120a6e |
//! insertionIdx.
|
|
Shinya Kitaoka |
d1f6c4 |
bool DockLayout::isPossibleInsertion(DockWidget *item,
|
|
Shinya Kitaoka |
d1f6c4 |
Region *parentRegion,
|
|
Shinya Kitaoka |
d1f6c4 |
int insertionIdx) {
|
|
Shinya Kitaoka |
120a6e |
const int inf = 1000000;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int mainWindowWidth = contentsRect().width();
|
|
Shinya Kitaoka |
120a6e |
int mainWindowHeight = contentsRect().height();
|
|
Shinya Kitaoka |
120a6e |
std::deque<region *="">::iterator i;</region>
|
|
Shinya Kitaoka |
120a6e |
bool result = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_regions.size()) {
|
|
Shinya Kitaoka |
120a6e |
// Calculate original extremal sizes
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->calculateExtremalSizes();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (parentRegion) // Common case
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// And update parent region extremal size after hypothetic insertion took
|
|
Shinya Kitaoka |
120a6e |
// place
|
|
Shinya Kitaoka |
120a6e |
result &= parentRegion->addItemSize(item);
|
|
Shinya Kitaoka |
120a6e |
} else // With root insertion
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// Insertion under new root: simulated by adding with m_regions.front() on
|
|
Shinya Kitaoka |
120a6e |
// its opposite direction;
|
|
Shinya Kitaoka |
120a6e |
bool frontOrientation = m_regions.front()->getOrientation();
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->setOrientation(!frontOrientation);
|
|
Shinya Kitaoka |
120a6e |
result &= m_regions.front()->addItemSize(item);
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->setOrientation(frontOrientation);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QSize rootMinSize;
|
|
Shinya Kitaoka |
120a6e |
QSize rootMaxSize;
|
|
Shinya Kitaoka |
120a6e |
if (m_regions.size()) {
|
|
Shinya Kitaoka |
120a6e |
rootMinSize = QSize(m_regions[0]->getMinimumSize(Region::horizontal),
|
|
Shinya Kitaoka |
120a6e |
m_regions[0]->getMinimumSize(Region::vertical));
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize = QSize(m_regions[0]->getMaximumSize(Region::horizontal),
|
|
Shinya Kitaoka |
120a6e |
m_regions[0]->getMaximumSize(Region::vertical));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// New Root
|
|
Shinya Kitaoka |
120a6e |
rootMinSize = item->minimumSize();
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize = item->maximumSize();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, check updated root against main window sizes
|
|
Shinya Kitaoka |
120a6e |
if (rootMinSize.width() > mainWindowWidth ||
|
|
Shinya Kitaoka |
120a6e |
rootMinSize.height() > mainWindowHeight ||
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize.width() < mainWindowWidth ||
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize.height() < mainWindowHeight) {
|
|
Shinya Kitaoka |
120a6e |
result = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Checks insertion validity of \b item inside \b parentRegion at position \b
|
|
Shinya Kitaoka |
120a6e |
//! insertionIdx.
|
|
Shinya Kitaoka |
d1f6c4 |
bool DockLayout::isPossibleRemoval(DockWidget *item,
|
|
Shinya Kitaoka |
d1f6c4 |
Region *parentRegion,
|
|
Shinya Kitaoka |
d1f6c4 |
int removalIdx) {
|
|
Shinya Kitaoka |
120a6e |
// NOTE: parentRegion is necessarily !=0 or there's no need to check anything
|
|
Shinya Kitaoka |
120a6e |
if (!parentRegion) return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const int inf = 1000000;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int mainWindowWidth = contentsRect().width();
|
|
Shinya Kitaoka |
120a6e |
int mainWindowHeight = contentsRect().height();
|
|
Shinya Kitaoka |
120a6e |
std::deque<region *="">::iterator i;</region>
|
|
Shinya Kitaoka |
120a6e |
bool result = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Calculate original extremal sizes
|
|
Shinya Kitaoka |
120a6e |
m_regions.front()->calculateExtremalSizes();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// And update parent region extremal size after hypothetic insertion took
|
|
Shinya Kitaoka |
120a6e |
// place
|
|
Shinya Kitaoka |
120a6e |
result &= parentRegion->subItemSize(item);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QSize rootMinSize;
|
|
Shinya Kitaoka |
120a6e |
QSize rootMaxSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rootMinSize = QSize(m_regions[0]->getMinimumSize(Region::horizontal),
|
|
Shinya Kitaoka |
120a6e |
m_regions[0]->getMinimumSize(Region::vertical));
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize = QSize(m_regions[0]->getMaximumSize(Region::horizontal),
|
|
Shinya Kitaoka |
120a6e |
m_regions[0]->getMaximumSize(Region::vertical));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, check updated root against main window sizes
|
|
Shinya Kitaoka |
120a6e |
if (rootMinSize.width() > mainWindowWidth ||
|
|
Shinya Kitaoka |
120a6e |
rootMinSize.height() > mainWindowHeight ||
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize.width() < mainWindowWidth ||
|
|
Shinya Kitaoka |
120a6e |
rootMaxSize.height() < mainWindowHeight) {
|
|
Shinya Kitaoka |
120a6e |
result = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================
|
|
Toshihiro Shimizu |
890ddd |
// Save & Load
|
|
Toshihiro Shimizu |
890ddd |
//===================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Returns the current \b State of the layout. A State is a typedef
|
|
Shinya Kitaoka |
120a6e |
//! for a pair containing the (normal) geometries of all layout items,
|
|
Shinya Kitaoka |
120a6e |
//! and a string indicating their hierarchycal structure.
|
|
Shinya Kitaoka |
120a6e |
DockLayout::State DockLayout::saveState() {
|
|
Shinya Kitaoka |
120a6e |
QString hierarchy;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Set save indices so we don't need to find anything
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); ++i) m_regions[i]->m_saveIndex = i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DockWidget *item;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_items.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
item = static_cast<dockwidget *="">(m_items[i]->widget());</dockwidget>
|
|
Shinya Kitaoka |
120a6e |
item->m_saveIndex = i;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Write item geometries
|
|
Shinya Kitaoka |
120a6e |
std::vector<qrect> geometries;</qrect>
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_items.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
geometries.push_back(m_items[i]->geometry());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QTextStream stream(&hierarchy, QIODevice::WriteOnly);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Save maximimized Dock index and geometry
|
|
Shinya Kitaoka |
120a6e |
stream << QString::number(m_maximizedDock ? m_maximizedDock->m_saveIndex : -1)
|
|
Shinya Kitaoka |
120a6e |
<< " ";
|
|
Shinya Kitaoka |
120a6e |
if (m_maximizedDock) {
|
|
Shinya Kitaoka |
120a6e |
Region *r = find(m_maximizedDock);
|
|
Shinya Kitaoka |
120a6e |
geometries[m_maximizedDock->m_saveIndex] = toRect(r->getGeometry());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Save regions
|
|
Shinya Kitaoka |
120a6e |
Region *r = rootRegion();
|
|
Shinya Kitaoka |
120a6e |
if (r) {
|
|
Shinya Kitaoka |
120a6e |
stream << QString::number(r->getOrientation()) << " ";
|
|
Shinya Kitaoka |
120a6e |
writeRegion(r, hierarchy);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return std::pair<std::vector<qrect>, QString>(geometries, hierarchy);</std::vector<qrect>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::writeRegion(Region *r, QString &hierarchy) {
|
|
Shinya Kitaoka |
120a6e |
DockWidget *item = static_cast<dockwidget *="">(r->getItem());</dockwidget>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// If Region has item, write it.
|
|
Shinya Kitaoka |
120a6e |
if (item) {
|
|
Shinya Kitaoka |
120a6e |
hierarchy.append(QString::number(item->m_saveIndex) + " ");
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
hierarchy.append("[ ");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Scan childList
|
|
Shinya Kitaoka |
120a6e |
unsigned int i, size = r->getChildList().size();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < size; ++i) {
|
|
Shinya Kitaoka |
120a6e |
writeRegion(r->childRegion(i), hierarchy);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
hierarchy.append("] ");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Restores the given internal structure of the layout.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! This method is intended to restore the
|
|
Shinya Kitaoka |
120a6e |
//! geometry of a set of items that was handled by the layout
|
|
Shinya Kitaoka |
120a6e |
//! at the time the state was saved. Input are the geometries of
|
|
Shinya Kitaoka |
120a6e |
//! the items involved and the dock hierarchy in form of a string.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b IMPORTANT \b NOTE: No check is performed on the item themselves,
|
|
Shinya Kitaoka |
120a6e |
//! except for the consistency of their geometrical constraints
|
|
Shinya Kitaoka |
120a6e |
//! inside the layout. Furthermore, this method does not ensure the
|
|
Shinya Kitaoka |
120a6e |
//! identity of the items involved, assuming that the set of dock
|
|
Shinya Kitaoka |
120a6e |
//! widget has ever been left unchanged or completely restored
|
|
Shinya Kitaoka |
120a6e |
//! as it were when saved. In particular, their ordering must be preserved.
|
|
Shinya Kitaoka |
120a6e |
bool DockLayout::restoreState(const State &state) {
|
|
Shinya Kitaoka |
120a6e |
QStringList vars = state.second.split(" ", QString::SkipEmptyParts);
|
|
Shinya Kitaoka |
120a6e |
if (vars.size() < 1) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Check number of items
|
|
Shinya Kitaoka |
120a6e |
unsigned int count = state.first.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_items.size() != count) return false; // Items list is not coherent
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Initialize new Regions hierarchy
|
|
Shinya Kitaoka |
120a6e |
std::deque<region *=""> newHierarchy;</region>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Load it
|
|
Shinya Kitaoka |
120a6e |
int maximizedItem = vars[0].toInt();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (vars.size() > 1) {
|
|
Shinya Kitaoka |
120a6e |
// Scan hierarchy
|
|
Shinya Kitaoka |
120a6e |
Region *r = 0, *newRegion;
|
|
Shinya Kitaoka |
120a6e |
int orientation = !vars[1].toInt();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 2; i < vars.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (vars[i] == "]") {
|
|
Shinya Kitaoka |
120a6e |
// End region and get parent
|
|
Shinya Kitaoka |
120a6e |
r = r->getParent();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Allocate new Region
|
|
Shinya Kitaoka |
120a6e |
newRegion = new Region(this);
|
|
Shinya Kitaoka |
120a6e |
newHierarchy.push_back(newRegion);
|
|
Shinya Kitaoka |
120a6e |
newRegion->m_orientation = !orientation;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (r) r->insertSubRegion(newRegion, r->getChildList().size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (vars[i] == "[") {
|
|
Shinya Kitaoka |
120a6e |
// Current region has children
|
|
Shinya Kitaoka |
120a6e |
r = newRegion;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// newRegion has item
|
|
Shinya Kitaoka |
120a6e |
newRegion->m_item =
|
|
Shinya Kitaoka |
120a6e |
static_cast<dockwidget *="">(m_items[vars[i].toInt()]->widget());</dockwidget>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Check if size constraints are satisfied
|
|
Shinya Kitaoka |
120a6e |
newHierarchy[0]->calculateExtremalSizes();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int j;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < newHierarchy.size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
// Check if their extremal sizes are valid
|
|
Shinya Kitaoka |
120a6e |
Region *r = newHierarchy[j];
|
|
Shinya Kitaoka |
120a6e |
if (r->getMinimumSize(Region::horizontal) >
|
|
Shinya Kitaoka |
120a6e |
r->getMaximumSize(Region::horizontal) ||
|
|
Shinya Kitaoka |
120a6e |
r->getMinimumSize(Region::vertical) >
|
|
Shinya Kitaoka |
120a6e |
r->getMaximumSize(Region::vertical)) {
|
|
Shinya Kitaoka |
120a6e |
// If not, deallocate attempted hierarchy and quit
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < newHierarchy.size(); ++j) delete newHierarchy[j];
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Else, deallocate old regions and substitute with new ones
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < m_regions.size(); ++j) delete m_regions[j];
|
|
Shinya Kitaoka |
120a6e |
m_regions = newHierarchy;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now re-initialize dock widgets' infos.
|
|
Shinya Kitaoka |
120a6e |
const std::vector<qrect> &geoms = state.first;</qrect>
|
|
Shinya Kitaoka |
120a6e |
DockWidget *item;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < m_items.size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
item = static_cast<dockwidget *="">(m_items[j]->widget());</dockwidget>
|
|
Shinya Kitaoka |
120a6e |
item->setGeometry(geoms[j]);
|
|
Shinya Kitaoka |
120a6e |
item->m_maximized = false;
|
|
Shinya Kitaoka |
120a6e |
item->m_saveIndex = j;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Docked widgets are found in hierarchy
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < m_regions.size(); ++j)
|
|
Shinya Kitaoka |
120a6e |
if ((item = m_regions[j]->m_item)) {
|
|
Shinya Kitaoka |
120a6e |
item->setWindowFlags(Qt::SubWindow);
|
|
Shinya Kitaoka |
120a6e |
item->setDockedAppearance();
|
|
Shinya Kitaoka |
120a6e |
item->m_floating = false;
|
|
Shinya Kitaoka |
120a6e |
item->m_saveIndex = -1;
|
|
Shinya Kitaoka |
120a6e |
item->show();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Recover available geometry infos
|
|
Shinya Kitaoka |
120a6e |
// QRect availableRect= QApplication::desktop()->availableGeometry();
|
|
Shinya Kitaoka |
120a6e |
int recoverX = 0, recoverY = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Deal with floating panels
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < m_items.size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
item = static_cast<dockwidget *="">(m_items[j]->widget());</dockwidget>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (item->m_saveIndex > 0) {
|
|
Shinya Kitaoka |
120a6e |
// Ensure that floating panels are not placed in
|
|
Shinya Kitaoka |
120a6e |
// unavailable positions
|
|
Shinya Kitaoka |
120a6e |
if ((geoms[j] & QApplication::desktop()->availableGeometry(item))
|
|
Shinya Kitaoka |
120a6e |
.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
item->move(recoverX += 50, recoverY += 50);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Set floating appearances
|
|
Shinya Kitaoka |
120a6e |
item->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
|
Shinya Kitaoka |
120a6e |
item->setFloatingAppearance();
|
|
Shinya Kitaoka |
120a6e |
item->m_floating = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Allocate region separators
|
|
Shinya Kitaoka |
120a6e |
unsigned int k;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < m_regions.size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
Region *r = m_regions[j];
|
|
Shinya Kitaoka |
120a6e |
for (k = 1; k < r->m_childList.size(); ++k) {
|
|
Shinya Kitaoka |
120a6e |
r->insertSeparator(
|
|
Shinya Kitaoka |
120a6e |
m_decoAllocator->newSeparator(this, r->getOrientation(), r));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Calculate regions' geometry starting from leaves (items)
|
|
Shinya Kitaoka |
120a6e |
if (m_regions.size()) m_regions[0]->restoreGeometry();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Then, ensure the result is correctly fitting the contents rect
|
|
Shinya Kitaoka |
120a6e |
// redistribute();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: The previous might be tempting to ensure all is right -
|
|
Shinya Kitaoka |
120a6e |
// unfortunately, it may
|
|
Shinya Kitaoka |
120a6e |
// be that the main window's content rect is not yet defined before it is
|
|
Shinya Kitaoka |
120a6e |
// shown the first
|
|
Shinya Kitaoka |
120a6e |
// time (like on MAC), and that is needed to redistribute. Se we force the
|
|
Shinya Kitaoka |
120a6e |
// saved values
|
|
Shinya Kitaoka |
120a6e |
//(assuming they are right)...
|
|
Shinya Kitaoka |
120a6e |
applyGeometry();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, set maximized dock widget
|
|
Shinya Kitaoka |
120a6e |
if (maximizedItem != -1) {
|
|
Shinya Kitaoka |
120a6e |
item = static_cast<dockwidget *="">(m_items[maximizedItem]->widget());</dockwidget>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Problema: Puo' essere, in fase di caricamento dati, che la contentsRect
|
|
Shinya Kitaoka |
120a6e |
// del layout
|
|
Shinya Kitaoka |
120a6e |
// venga sballata! (vv. lo ctor di TMainWindow) Allora, evitiamo il
|
|
Shinya Kitaoka |
120a6e |
// controllo fatto
|
|
Shinya Kitaoka |
120a6e |
// in setMazimized, e assumiamo sia per forza corretto...
|
|
Shinya Kitaoka |
120a6e |
// setMaximized(item, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_maximizedDock = item;
|
|
Shinya Kitaoka |
120a6e |
item->m_maximized = true;
|
|
Shinya Kitaoka |
120a6e |
item->raise();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Hide all other widgets
|
|
Shinya Kitaoka |
120a6e |
QWidget *currWidget;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < this->count(); ++i)
|
|
Shinya Kitaoka |
120a6e |
if ((currWidget = itemAt(i)->widget()) != item) currWidget->hide();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Recalculates the geometry of \b this Region and of its branches,
|
|
Shinya Kitaoka |
120a6e |
//! assuming those of 'leaf items' are correct.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//! Regions always tend to keep their geometry by default. However,
|
|
Shinya Kitaoka |
120a6e |
//! it may be useful (for example, when restoring the state of a DockLayout)
|
|
Shinya Kitaoka |
120a6e |
//! the possibility of recalculating its current geometry directly from the
|
|
Shinya Kitaoka |
120a6e |
//! items that are contained in the branches.
|
|
Shinya Kitaoka |
120a6e |
void Region::restoreGeometry() {
|
|
Shinya Kitaoka |
120a6e |
// Applying a head-recursive algorithm to update the geometry of a Region
|
|
Shinya Kitaoka |
120a6e |
// after those of its children have been updated
|
|
Shinya Kitaoka |
120a6e |
if (m_item) {
|
|
Shinya Kitaoka |
120a6e |
// Place item's geometry
|
|
Shinya Kitaoka |
120a6e |
setGeometry(m_item->geometry());
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First do children
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_childList.size(); ++i) m_childList[i]->restoreGeometry();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Then, update this one: just take the edges of its children.
|
|
Shinya Kitaoka |
120a6e |
unsigned int last = m_childList.size() - 1;
|
|
Shinya Kitaoka |
120a6e |
QPoint topLeft(m_childList[0]->getGeometry().left(),
|
|
Shinya Kitaoka |
120a6e |
m_childList[0]->getGeometry().top());
|
|
Shinya Kitaoka |
120a6e |
QPoint bottomRight(m_childList[last]->getGeometry().right(),
|
|
Shinya Kitaoka |
120a6e |
m_childList[last]->getGeometry().bottom());
|
|
Shinya Kitaoka |
120a6e |
setGeometry(QRect(topLeft, bottomRight));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------
|
|
Toshihiro Shimizu |
890ddd |
// Dock Deco Allocator
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Allocates a new DockSeparator with input parameters. This function can be
|
|
Shinya Kitaoka |
120a6e |
//! re-implemented
|
|
Shinya Kitaoka |
120a6e |
//! to allocate derived DockSeparator classes.
|
|
Shinya Kitaoka |
d1f6c4 |
DockSeparator *DockDecoAllocator::newSeparator(DockLayout *owner,
|
|
Shinya Kitaoka |
d1f6c4 |
bool orientation,
|
|
Shinya Kitaoka |
d1f6c4 |
Region *parentRegion) {
|
|
Shinya Kitaoka |
120a6e |
return new DockSeparator(owner, orientation, parentRegion);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! When inheriting a DockLayout class, new custom placeholders gets allocated
|
|
Shinya Kitaoka |
120a6e |
//! by this method.
|
|
Shinya Kitaoka |
d1f6c4 |
DockPlaceholder *DockDecoAllocator::newPlaceholder(DockWidget *owner,
|
|
Shinya Kitaoka |
d1f6c4 |
Region *r, int idx,
|
|
Shinya Kitaoka |
d1f6c4 |
int attributes) {
|
|
Shinya Kitaoka |
120a6e |
return new DockPlaceholder(owner, r, idx, attributes);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// BuildGeometry() method should not be called inside the base contructor -
|
|
Shinya Kitaoka |
120a6e |
// because it's a virtual method.
|
|
Shinya Kitaoka |
120a6e |
// So we provide this little inline...
|
|
Shinya Kitaoka |
d1f6c4 |
DockPlaceholder *DockDecoAllocator::newPlaceBuilt(DockWidget *owner,
|
|
Shinya Kitaoka |
d1f6c4 |
Region *r, int idx,
|
|
Shinya Kitaoka |
d1f6c4 |
int attributes) {
|
|
Shinya Kitaoka |
120a6e |
DockPlaceholder *res = newPlaceholder(owner, r, idx, attributes);
|
|
Shinya Kitaoka |
120a6e |
res->buildGeometry();
|
|
Shinya Kitaoka |
120a6e |
return res;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Sets current deco allocator to decoAllocator. A default deco allocator
|
|
Shinya Kitaoka |
120a6e |
//! is already provided at construction.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b NOTE: DockLayout takes ownership of the allocator.
|
|
Shinya Kitaoka |
120a6e |
void DockLayout::setDecoAllocator(DockDecoAllocator *decoAllocator) {
|
|
Shinya Kitaoka |
120a6e |
// Delete old one
|
|
Shinya Kitaoka |
120a6e |
if (m_decoAllocator) delete m_decoAllocator;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Place new one
|
|
Shinya Kitaoka |
120a6e |
m_decoAllocator = decoAllocator;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Sets current deco allocator to decoAllocator. A default deco allocator
|
|
Shinya Kitaoka |
120a6e |
//! is already provided at construction.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b NOTE: DockWidget takes ownership of the allocator.
|
|
Shinya Kitaoka |
120a6e |
void DockWidget::setDecoAllocator(DockDecoAllocator *decoAllocator) {
|
|
Shinya Kitaoka |
120a6e |
// Delete old one
|
|
Shinya Kitaoka |
120a6e |
if (m_decoAllocator) delete m_decoAllocator;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Place a copy of new one
|
|
Shinya Kitaoka |
120a6e |
m_decoAllocator = decoAllocator;
|
|
Toshihiro Shimizu |
890ddd |
}
|