annotate view/PaneStack.cpp @ 789:9fd1bdf214dd tonioni

Play pointer: when user drags pane during playback such that the pointer is no longer visible, accept that and stop trying to track it until pointer naturally comes back within visible area
author Chris Cannam
date Thu, 12 Jun 2014 12:48:11 +0100
parents b6dc57688c72
children 4c8ca536b54f
rev   line source
Chris@127 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@127 2
Chris@127 3 /*
Chris@127 4 Sonic Visualiser
Chris@127 5 An audio file viewer and annotation editor.
Chris@127 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@127 8
Chris@127 9 This program is free software; you can redistribute it and/or
Chris@127 10 modify it under the terms of the GNU General Public License as
Chris@127 11 published by the Free Software Foundation; either version 2 of the
Chris@127 12 License, or (at your option) any later version. See the file
Chris@127 13 COPYING included with this distribution for more information.
Chris@127 14 */
Chris@127 15
Chris@127 16 #include "PaneStack.h"
Chris@127 17
Chris@128 18 #include "Pane.h"
Chris@127 19 #include "widgets/PropertyStack.h"
Chris@323 20 #include "widgets/IconLoader.h"
Chris@500 21 #include "widgets/ClickableLabel.h"
Chris@128 22 #include "layer/Layer.h"
Chris@128 23 #include "ViewManager.h"
Chris@127 24
Chris@127 25 #include <QApplication>
Chris@127 26 #include <QHBoxLayout>
Chris@323 27 #include <QVBoxLayout>
Chris@127 28 #include <QPainter>
Chris@127 29 #include <QPalette>
Chris@127 30 #include <QLabel>
Chris@323 31 #include <QPushButton>
Chris@127 32 #include <QSplitter>
Chris@127 33 #include <QStackedWidget>
Chris@127 34
Chris@127 35 #include <iostream>
Chris@127 36
Chris@247 37 //#define DEBUG_PANE_STACK 1
Chris@247 38
Chris@127 39 PaneStack::PaneStack(QWidget *parent, ViewManager *viewManager) :
Chris@127 40 QFrame(parent),
Chris@127 41 m_currentPane(0),
Chris@712 42 m_showAccessories(true),
Chris@127 43 m_splitter(new QSplitter),
Chris@127 44 m_propertyStackStack(new QStackedWidget),
Chris@127 45 m_viewManager(viewManager),
Chris@615 46 m_propertyStackMinWidth(100),
Chris@127 47 m_layoutStyle(PropertyStackPerPaneLayout)
Chris@127 48 {
Chris@127 49 QHBoxLayout *layout = new QHBoxLayout;
Chris@127 50 layout->setMargin(0);
Chris@127 51 layout->setSpacing(0);
Chris@127 52
Chris@127 53 m_splitter->setOrientation(Qt::Vertical);
Chris@127 54 m_splitter->setOpaqueResize(false);
Chris@127 55
Chris@127 56 layout->addWidget(m_splitter);
Chris@127 57 layout->setStretchFactor(m_splitter, 1);
Chris@127 58 layout->addWidget(m_propertyStackStack);
Chris@127 59 m_propertyStackStack->hide();
Chris@127 60
Chris@127 61 setLayout(layout);
Chris@127 62 }
Chris@127 63
Chris@712 64 void
Chris@712 65 PaneStack::setShowPaneAccessories(bool show)
Chris@712 66 {
Chris@712 67 m_showAccessories = show;
Chris@712 68 }
Chris@712 69
Chris@127 70 Pane *
Chris@127 71 PaneStack::addPane(bool suppressPropertyBox)
Chris@127 72 {
Chris@539 73 return insertPane(getPaneCount(), suppressPropertyBox);
Chris@539 74 }
Chris@539 75
Chris@539 76 Pane *
Chris@539 77 PaneStack::insertPane(int index, bool suppressPropertyBox)
Chris@539 78 {
Chris@127 79 QFrame *frame = new QFrame;
Chris@495 80
Chris@495 81 QGridLayout *layout = new QGridLayout;
Chris@127 82 layout->setMargin(0);
Chris@127 83 layout->setSpacing(2);
Chris@127 84
Chris@323 85 QPushButton *xButton = new QPushButton(frame);
Chris@323 86 xButton->setIcon(IconLoader().load("cross"));
Chris@323 87 xButton->setFixedSize(QSize(16, 16));
Chris@497 88 xButton->setFlat(true);
Chris@712 89 xButton->setVisible(m_showAccessories);
Chris@495 90 layout->addWidget(xButton, 0, 0);
Chris@323 91 connect(xButton, SIGNAL(clicked()), this, SLOT(paneDeleteButtonClicked()));
Chris@323 92
Chris@500 93 ClickableLabel *currentIndicator = new ClickableLabel(frame);
Chris@500 94 connect(currentIndicator, SIGNAL(clicked()), this, SLOT(indicatorClicked()));
Chris@495 95 layout->addWidget(currentIndicator, 1, 0);
Chris@495 96 layout->setRowStretch(1, 20);
Chris@497 97 currentIndicator->setMinimumWidth(8);
Chris@127 98 currentIndicator->setScaledContents(true);
Chris@712 99 currentIndicator->setVisible(m_showAccessories);
Chris@127 100
Chris@516 101 long initialCentreFrame = -1;
Chris@516 102 for (int i = 0; i < m_panes.size(); ++i) {
Chris@516 103 long f = m_panes[i].pane->getCentreFrame();
Chris@516 104 initialCentreFrame = f;
Chris@516 105 break;
Chris@516 106 }
Chris@516 107
Chris@127 108 Pane *pane = new Pane(frame);
Chris@516 109 if (initialCentreFrame >= 0) {
Chris@516 110 pane->setViewManager(m_viewManager, initialCentreFrame);
Chris@516 111 } else {
Chris@516 112 pane->setViewManager(m_viewManager);
Chris@516 113 }
Chris@495 114 layout->addWidget(pane, 0, 1, 2, 1);
Chris@495 115 layout->setColumnStretch(1, 20);
Chris@127 116
Chris@127 117 QWidget *properties = 0;
Chris@127 118 if (suppressPropertyBox) {
Chris@127 119 properties = new QFrame();
Chris@127 120 } else {
Chris@127 121 properties = new PropertyStack(frame, pane);
Chris@127 122 connect(properties, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
Chris@127 123 this, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
Chris@190 124 connect(properties, SIGNAL(viewSelected(View *)),
Chris@190 125 this, SLOT(viewSelected(View *)));
Chris@189 126 connect(properties, SIGNAL(contextHelpChanged(const QString &)),
Chris@189 127 this, SIGNAL(contextHelpChanged(const QString &)));
Chris@127 128 }
Chris@127 129 if (m_layoutStyle == PropertyStackPerPaneLayout) {
Chris@495 130 layout->addWidget(properties, 0, 2, 2, 1);
Chris@127 131 } else {
Chris@127 132 properties->setParent(m_propertyStackStack);
Chris@127 133 m_propertyStackStack->addWidget(properties);
Chris@127 134 }
Chris@606 135 layout->setColumnStretch(2, 0);
Chris@127 136
Chris@127 137 PaneRec rec;
Chris@127 138 rec.pane = pane;
Chris@127 139 rec.propertyStack = properties;
Chris@605 140 rec.xButton = xButton;
Chris@127 141 rec.currentIndicator = currentIndicator;
Chris@127 142 rec.frame = frame;
Chris@127 143 rec.layout = layout;
Chris@127 144 m_panes.push_back(rec);
Chris@127 145
Chris@127 146 frame->setLayout(layout);
Chris@539 147 m_splitter->insertWidget(index, frame);
Chris@127 148
Chris@127 149 connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@127 150 this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@127 151 connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@127 152 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@127 153 connect(pane, SIGNAL(paneInteractedWith()),
Chris@127 154 this, SLOT(paneInteractedWith()));
Chris@127 155 connect(pane, SIGNAL(rightButtonMenuRequested(QPoint)),
Chris@127 156 this, SLOT(rightButtonMenuRequested(QPoint)));
Chris@312 157 connect(pane, SIGNAL(dropAccepted(QStringList)),
Chris@312 158 this, SLOT(paneDropAccepted(QStringList)));
Chris@312 159 connect(pane, SIGNAL(dropAccepted(QString)),
Chris@312 160 this, SLOT(paneDropAccepted(QString)));
Chris@716 161 connect(pane, SIGNAL(doubleClickSelectInvoked(size_t)),
Chris@716 162 this, SIGNAL(doubleClickSelectInvoked(size_t)));
Chris@127 163
Chris@271 164 emit paneAdded(pane);
Chris@271 165 emit paneAdded();
Chris@271 166
Chris@127 167 if (!m_currentPane) {
Chris@127 168 setCurrentPane(pane);
Chris@127 169 }
Chris@127 170
Chris@605 171 showOrHidePaneAccessories();
Chris@605 172
Chris@127 173 return pane;
Chris@127 174 }
Chris@127 175
Chris@127 176 void
Chris@235 177 PaneStack::setPropertyStackMinWidth(int mw)
Chris@235 178 {
Chris@235 179 for (std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@235 180 i != m_panes.end(); ++i) {
Chris@235 181 i->propertyStack->setMinimumWidth(mw);
Chris@235 182 }
Chris@235 183 m_propertyStackMinWidth = mw;
Chris@235 184 }
Chris@235 185
Chris@235 186 void
Chris@127 187 PaneStack::setLayoutStyle(LayoutStyle style)
Chris@127 188 {
Chris@127 189 if (style == m_layoutStyle) return;
Chris@127 190 m_layoutStyle = style;
Chris@127 191
Chris@127 192 std::vector<PaneRec>::iterator i;
Chris@127 193
Chris@127 194 switch (style) {
Chris@127 195
Chris@179 196 case NoPropertyStacks:
Chris@127 197 case SinglePropertyStackLayout:
Chris@127 198
Chris@127 199 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@127 200 i->layout->removeWidget(i->propertyStack);
Chris@127 201 i->propertyStack->setParent(m_propertyStackStack);
Chris@127 202 m_propertyStackStack->addWidget(i->propertyStack);
Chris@127 203 }
Chris@179 204 m_propertyStackStack->setVisible(style != NoPropertyStacks);
Chris@127 205 break;
Chris@127 206
Chris@127 207 case PropertyStackPerPaneLayout:
Chris@127 208
Chris@127 209 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@127 210 m_propertyStackStack->removeWidget(i->propertyStack);
Chris@127 211 i->propertyStack->setParent(i->frame);
Chris@495 212 i->layout->addWidget(i->propertyStack, 0, 2, 2, 1);
Chris@127 213 i->propertyStack->show();
Chris@127 214 }
Chris@127 215 m_propertyStackStack->hide();
Chris@127 216 break;
Chris@127 217 }
Chris@127 218 }
Chris@127 219
Chris@127 220 Pane *
Chris@127 221 PaneStack::getPane(int n)
Chris@127 222 {
Chris@277 223 if (n < m_panes.size()) {
Chris@277 224 return m_panes[n].pane;
Chris@277 225 } else {
Chris@277 226 return 0;
Chris@277 227 }
Chris@277 228 }
Chris@277 229
Chris@277 230 int
Chris@277 231 PaneStack::getPaneIndex(Pane *pane)
Chris@277 232 {
Chris@277 233 for (int i = 0; i < getPaneCount(); ++i) {
Chris@277 234 if (pane == getPane(i)) {
Chris@277 235 return i;
Chris@277 236 }
Chris@277 237 }
Chris@277 238 return -1;
Chris@127 239 }
Chris@127 240
Chris@127 241 Pane *
Chris@127 242 PaneStack::getHiddenPane(int n)
Chris@127 243 {
Chris@127 244 return m_hiddenPanes[n].pane;
Chris@127 245 }
Chris@127 246
Chris@127 247 void
Chris@127 248 PaneStack::deletePane(Pane *pane)
Chris@127 249 {
Chris@729 250 cerr << "PaneStack::deletePane(" << pane << ")" << endl;
Chris@729 251
Chris@127 252 std::vector<PaneRec>::iterator i;
Chris@127 253 bool found = false;
Chris@127 254
Chris@729 255 QWidget *stack = 0;
Chris@729 256
Chris@127 257 for (i = m_panes.begin(); i != m_panes.end(); ++i) {
Chris@127 258 if (i->pane == pane) {
Chris@729 259 stack = i->propertyStack;
Chris@127 260 m_panes.erase(i);
Chris@127 261 found = true;
Chris@127 262 break;
Chris@127 263 }
Chris@127 264 }
Chris@127 265
Chris@127 266 if (!found) {
Chris@127 267
Chris@127 268 for (i = m_hiddenPanes.begin(); i != m_hiddenPanes.end(); ++i) {
Chris@127 269 if (i->pane == pane) {
Chris@729 270 stack = i->propertyStack;
Chris@127 271 m_hiddenPanes.erase(i);
Chris@127 272 found = true;
Chris@127 273 break;
Chris@127 274 }
Chris@127 275 }
Chris@127 276
Chris@127 277 if (!found) {
Chris@682 278 cerr << "WARNING: PaneStack::deletePane(" << pane << "): Pane not found in visible or hidden panes, not deleting" << endl;
Chris@127 279 return;
Chris@127 280 }
Chris@127 281 }
Chris@127 282
Chris@271 283 emit paneAboutToBeDeleted(pane);
Chris@271 284
Chris@729 285 cerr << "PaneStack::deletePane: about to delete parent " << pane->parent() << " of pane " << pane << endl;
Chris@729 286
Chris@729 287 // The property stack associated with the parent was initially
Chris@729 288 // created with the same parent as it, so it would be deleted when
Chris@729 289 // we delete the pane's parent in a moment -- but it may have been
Chris@729 290 // reparented depending on the layout. We'd better delete it
Chris@729 291 // separately first. (This fixes a crash on opening a new layer
Chris@729 292 // with a new unit type in it, when a long-defunct property box
Chris@729 293 // could be signalled from the unit database to tell it that a new
Chris@729 294 // unit had appeared.)
Chris@729 295 delete stack;
Chris@729 296
Chris@127 297 delete pane->parent();
Chris@127 298
Chris@127 299 if (m_currentPane == pane) {
Chris@127 300 if (m_panes.size() > 0) {
Chris@127 301 setCurrentPane(m_panes[0].pane);
Chris@127 302 } else {
Chris@127 303 setCurrentPane(0);
Chris@127 304 }
Chris@127 305 }
Chris@271 306
Chris@605 307 showOrHidePaneAccessories();
Chris@605 308
Chris@271 309 emit paneDeleted();
Chris@127 310 }
Chris@127 311
Chris@605 312 void
Chris@605 313 PaneStack::showOrHidePaneAccessories()
Chris@605 314 {
Chris@682 315 cerr << "PaneStack::showOrHidePaneAccessories: count == " << getPaneCount() << endl;
Chris@605 316
Chris@605 317 bool multi = (getPaneCount() > 1);
Chris@605 318 for (std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@605 319 i != m_panes.end(); ++i) {
Chris@712 320 i->xButton->setVisible(multi && m_showAccessories);
Chris@712 321 i->currentIndicator->setVisible(multi && m_showAccessories);
Chris@605 322 }
Chris@605 323 }
Chris@605 324
Chris@127 325 int
Chris@127 326 PaneStack::getPaneCount() const
Chris@127 327 {
Chris@127 328 return m_panes.size();
Chris@127 329 }
Chris@127 330
Chris@127 331 int
Chris@127 332 PaneStack::getHiddenPaneCount() const
Chris@127 333 {
Chris@127 334 return m_hiddenPanes.size();
Chris@127 335 }
Chris@127 336
Chris@127 337 void
Chris@127 338 PaneStack::hidePane(Pane *pane)
Chris@127 339 {
Chris@127 340 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 341
Chris@127 342 while (i != m_panes.end()) {
Chris@127 343 if (i->pane == pane) {
Chris@127 344
Chris@127 345 m_hiddenPanes.push_back(*i);
Chris@127 346 m_panes.erase(i);
Chris@127 347
Chris@127 348 QWidget *pw = dynamic_cast<QWidget *>(pane->parent());
Chris@127 349 if (pw) pw->hide();
Chris@127 350
Chris@127 351 if (m_currentPane == pane) {
Chris@127 352 if (m_panes.size() > 0) {
Chris@127 353 setCurrentPane(m_panes[0].pane);
Chris@127 354 } else {
Chris@127 355 setCurrentPane(0);
Chris@127 356 }
Chris@127 357 }
Chris@127 358
Chris@605 359 showOrHidePaneAccessories();
Chris@605 360 emit paneHidden(pane);
Chris@605 361 emit paneHidden();
Chris@127 362 return;
Chris@127 363 }
Chris@127 364 ++i;
Chris@127 365 }
Chris@127 366
Chris@682 367 cerr << "WARNING: PaneStack::hidePane(" << pane << "): Pane not found in visible panes" << endl;
Chris@127 368 }
Chris@127 369
Chris@127 370 void
Chris@127 371 PaneStack::showPane(Pane *pane)
Chris@127 372 {
Chris@127 373 std::vector<PaneRec>::iterator i = m_hiddenPanes.begin();
Chris@127 374
Chris@127 375 while (i != m_hiddenPanes.end()) {
Chris@127 376 if (i->pane == pane) {
Chris@127 377 m_panes.push_back(*i);
Chris@127 378 m_hiddenPanes.erase(i);
Chris@127 379 QWidget *pw = dynamic_cast<QWidget *>(pane->parent());
Chris@127 380 if (pw) pw->show();
Chris@127 381
Chris@127 382 //!!! update current pane
Chris@127 383
Chris@605 384 showOrHidePaneAccessories();
Chris@605 385
Chris@127 386 return;
Chris@127 387 }
Chris@127 388 ++i;
Chris@127 389 }
Chris@127 390
Chris@682 391 cerr << "WARNING: PaneStack::showPane(" << pane << "): Pane not found in hidden panes" << endl;
Chris@127 392 }
Chris@127 393
Chris@127 394 void
Chris@127 395 PaneStack::setCurrentPane(Pane *pane) // may be null
Chris@127 396 {
Chris@127 397 if (m_currentPane == pane) return;
Chris@127 398
Chris@127 399 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 400
Chris@127 401 // We used to do this by setting the foreground and background
Chris@127 402 // role, but it seems the background role is ignored and the
Chris@127 403 // background drawn transparent in Qt 4.1 -- I can't quite see why
Chris@127 404
Chris@127 405 QPixmap selectedMap(1, 1);
Chris@127 406 selectedMap.fill(QApplication::palette().color(QPalette::Foreground));
Chris@127 407
Chris@127 408 QPixmap unselectedMap(1, 1);
Chris@127 409 unselectedMap.fill(QApplication::palette().color(QPalette::Background));
Chris@127 410
Chris@127 411 bool found = false;
Chris@127 412
Chris@127 413 while (i != m_panes.end()) {
Chris@127 414 if (i->pane == pane) {
Chris@127 415 i->currentIndicator->setPixmap(selectedMap);
Chris@179 416 if (m_layoutStyle != PropertyStackPerPaneLayout) {
Chris@127 417 m_propertyStackStack->setCurrentWidget(i->propertyStack);
Chris@127 418 }
Chris@127 419 found = true;
Chris@127 420 } else {
Chris@127 421 i->currentIndicator->setPixmap(unselectedMap);
Chris@127 422 }
Chris@127 423 ++i;
Chris@127 424 }
Chris@127 425
Chris@127 426 if (found || pane == 0) {
Chris@127 427 m_currentPane = pane;
Chris@127 428 emit currentPaneChanged(m_currentPane);
Chris@127 429 } else {
Chris@682 430 cerr << "WARNING: PaneStack::setCurrentPane(" << pane << "): pane is not a visible pane in this stack" << endl;
Chris@127 431 }
Chris@127 432 }
Chris@127 433
Chris@127 434 void
Chris@127 435 PaneStack::setCurrentLayer(Pane *pane, Layer *layer) // may be null
Chris@127 436 {
Chris@127 437 setCurrentPane(pane);
Chris@127 438
Chris@127 439 if (m_currentPane) {
Chris@127 440
Chris@127 441 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 442
Chris@127 443 while (i != m_panes.end()) {
Chris@127 444
Chris@127 445 if (i->pane == pane) {
Chris@127 446 PropertyStack *stack = dynamic_cast<PropertyStack *>
Chris@127 447 (i->propertyStack);
Chris@127 448 if (stack) {
Chris@127 449 if (stack->containsContainer(layer)) {
Chris@127 450 stack->setCurrentIndex(stack->getContainerIndex(layer));
Chris@127 451 emit currentLayerChanged(pane, layer);
Chris@127 452 } else {
Chris@127 453 stack->setCurrentIndex
Chris@127 454 (stack->getContainerIndex
Chris@127 455 (pane->getPropertyContainer(0)));
Chris@127 456 emit currentLayerChanged(pane, 0);
Chris@127 457 }
Chris@127 458 }
Chris@127 459 break;
Chris@127 460 }
Chris@127 461 ++i;
Chris@127 462 }
Chris@127 463 }
Chris@127 464 }
Chris@127 465
Chris@127 466 Pane *
Chris@127 467 PaneStack::getCurrentPane()
Chris@127 468 {
Chris@127 469 return m_currentPane;
Chris@127 470 }
Chris@127 471
Chris@127 472 void
Chris@127 473 PaneStack::propertyContainerAdded(PropertyContainer *)
Chris@127 474 {
Chris@127 475 sizePropertyStacks();
Chris@127 476 }
Chris@127 477
Chris@127 478 void
Chris@127 479 PaneStack::propertyContainerRemoved(PropertyContainer *)
Chris@127 480 {
Chris@127 481 sizePropertyStacks();
Chris@127 482 }
Chris@127 483
Chris@127 484 void
Chris@127 485 PaneStack::propertyContainerSelected(View *client, PropertyContainer *pc)
Chris@127 486 {
Chris@127 487 std::vector<PaneRec>::iterator i = m_panes.begin();
Chris@127 488
Chris@127 489 while (i != m_panes.end()) {
Chris@127 490 PropertyStack *stack = dynamic_cast<PropertyStack *>(i->propertyStack);
Chris@127 491 if (stack &&
Chris@127 492 stack->getClient() == client &&
Chris@127 493 stack->containsContainer(pc)) {
Chris@127 494 setCurrentPane(i->pane);
Chris@127 495 break;
Chris@127 496 }
Chris@127 497 ++i;
Chris@127 498 }
Chris@127 499
Chris@127 500 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@127 501 if (layer) emit currentLayerChanged(m_currentPane, layer);
Chris@127 502 else emit currentLayerChanged(m_currentPane, 0);
Chris@127 503 }
Chris@127 504
Chris@127 505 void
Chris@190 506 PaneStack::viewSelected(View *v)
Chris@190 507 {
Chris@190 508 Pane *p = dynamic_cast<Pane *>(v);
Chris@190 509 if (p) setCurrentPane(p);
Chris@190 510 }
Chris@190 511
Chris@190 512 void
Chris@127 513 PaneStack::paneInteractedWith()
Chris@127 514 {
Chris@127 515 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@127 516 if (!pane) return;
Chris@127 517 setCurrentPane(pane);
Chris@127 518 }
Chris@127 519
Chris@127 520 void
Chris@127 521 PaneStack::rightButtonMenuRequested(QPoint position)
Chris@127 522 {
Chris@127 523 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@127 524 if (!pane) return;
Chris@127 525 emit rightButtonMenuRequested(pane, position);
Chris@127 526 }
Chris@127 527
Chris@127 528 void
Chris@127 529 PaneStack::sizePropertyStacks()
Chris@127 530 {
Chris@127 531 int maxMinWidth = 0;
Chris@127 532
Chris@235 533 if (m_propertyStackMinWidth > 0) maxMinWidth = m_propertyStackMinWidth;
Chris@235 534
Chris@127 535 for (size_t i = 0; i < m_panes.size(); ++i) {
Chris@127 536 if (!m_panes[i].propertyStack) continue;
Chris@247 537 #ifdef DEBUG_PANE_STACK
Chris@587 538 SVDEBUG << "PaneStack::sizePropertyStacks: " << i << ": min "
Chris@243 539 << m_panes[i].propertyStack->minimumSizeHint().width() << ", hint "
Chris@243 540 << m_panes[i].propertyStack->sizeHint().width() << ", current "
Chris@585 541 << m_panes[i].propertyStack->width() << endl;
Chris@247 542 #endif
Chris@127 543
Chris@246 544 if (m_panes[i].propertyStack->sizeHint().width() > maxMinWidth) {
Chris@246 545 maxMinWidth = m_panes[i].propertyStack->sizeHint().width();
Chris@127 546 }
Chris@127 547 }
Chris@127 548
Chris@247 549 #ifdef DEBUG_PANE_STACK
Chris@587 550 SVDEBUG << "PaneStack::sizePropertyStacks: max min width " << maxMinWidth << endl;
Chris@247 551 #endif
Chris@127 552
Chris@127 553 int setWidth = maxMinWidth;
Chris@127 554
Chris@127 555 m_propertyStackStack->setMaximumWidth(setWidth + 10);
Chris@127 556
Chris@127 557 for (size_t i = 0; i < m_panes.size(); ++i) {
Chris@127 558 if (!m_panes[i].propertyStack) continue;
Chris@127 559 m_panes[i].propertyStack->setMinimumWidth(setWidth);
Chris@127 560 }
Chris@180 561
Chris@363 562 emit propertyStacksResized(setWidth);
Chris@180 563 emit propertyStacksResized();
Chris@127 564 }
Chris@127 565
Chris@312 566 void
Chris@312 567 PaneStack::paneDropAccepted(QStringList uriList)
Chris@312 568 {
Chris@312 569 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@312 570 emit dropAccepted(pane, uriList);
Chris@312 571 }
Chris@312 572
Chris@312 573 void
Chris@312 574 PaneStack::paneDropAccepted(QString text)
Chris@312 575 {
Chris@312 576 Pane *pane = dynamic_cast<Pane *>(sender());
Chris@312 577 emit dropAccepted(pane, text);
Chris@312 578 }
Chris@127 579
Chris@320 580 void
Chris@323 581 PaneStack::paneDeleteButtonClicked()
Chris@323 582 {
Chris@323 583 QObject *s = sender();
Chris@605 584 for (size_t i = 0; i < m_panes.size(); ++i) {
Chris@605 585 if (m_panes[i].xButton == s) {
Chris@605 586 emit paneDeleteButtonClicked(m_panes[i].pane);
Chris@323 587 }
Chris@323 588 }
Chris@323 589 }
Chris@323 590
Chris@323 591 void
Chris@500 592 PaneStack::indicatorClicked()
Chris@500 593 {
Chris@500 594 QObject *s = sender();
Chris@500 595
Chris@500 596 for (size_t i = 0; i < m_panes.size(); ++i) {
Chris@500 597 if (m_panes[i].currentIndicator == s) {
Chris@500 598 setCurrentPane(m_panes[i].pane);
Chris@500 599 return;
Chris@500 600 }
Chris@500 601 }
Chris@500 602 }
Chris@500 603
Chris@500 604 void
Chris@320 605 PaneStack::sizePanesEqually()
Chris@320 606 {
Chris@320 607 QList<int> sizes = m_splitter->sizes();
Chris@320 608 if (sizes.empty()) return;
Chris@320 609
Chris@320 610 int count = sizes.size();
Chris@320 611
Chris@687 612 int fixed = 0, variable = 0, total = 0;
Chris@687 613 int varicount = 0;
Chris@687 614
Chris@320 615 for (int i = 0; i < count; ++i) {
Chris@320 616 total += sizes[i];
Chris@320 617 }
Chris@320 618
Chris@687 619 variable = total;
Chris@687 620
Chris@687 621 for (int i = 0; i < count; ++i) {
Chris@687 622 int minh = m_panes[i].pane->minimumSize().height();
Chris@687 623 if (minh == m_panes[i].pane->maximumSize().height()) {
Chris@687 624 fixed += minh;
Chris@687 625 variable -= minh;
Chris@687 626 } else {
Chris@687 627 varicount++;
Chris@687 628 }
Chris@687 629 }
Chris@687 630
Chris@320 631 if (total == 0) return;
Chris@320 632
Chris@320 633 sizes.clear();
Chris@320 634
Chris@687 635 int each = (varicount > 0 ? (variable / varicount) : 0);
Chris@320 636 int remaining = total;
Chris@320 637
Chris@320 638 for (int i = 0; i < count; ++i) {
Chris@320 639 if (i == count - 1) {
Chris@320 640 sizes.push_back(remaining);
Chris@320 641 } else {
Chris@687 642 int minh = m_panes[i].pane->minimumSize().height();
Chris@687 643 if (minh == m_panes[i].pane->maximumSize().height()) {
Chris@687 644 sizes.push_back(minh);
Chris@687 645 remaining -= minh;
Chris@687 646 } else {
Chris@687 647 sizes.push_back(each);
Chris@687 648 remaining -= each;
Chris@687 649 }
Chris@320 650 }
Chris@320 651 }
Chris@320 652
Chris@320 653 /*
Chris@682 654 cerr << "sizes: ";
Chris@320 655 for (int i = 0; i < sizes.size(); ++i) {
Chris@682 656 cerr << sizes[i] << " ";
Chris@320 657 }
Chris@682 658 cerr << endl;
Chris@320 659 */
Chris@320 660
Chris@320 661 m_splitter->setSizes(sizes);
Chris@320 662 }
Chris@320 663