Skip to content

Commit

Permalink
Re #8909. Use EmptyTile widgets to fill in empty spaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
mantid-roman committed Apr 7, 2014
1 parent 29a0c88 commit 080e0ab
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Code/Mantid/MantidPlot/CMakeLists.txt
Expand Up @@ -930,6 +930,8 @@ set ( MANTIDPLOT_TEST_PY_FILES
MantidPlotProxiesTest.py
MantidPlotPythonImportTest.py
MantidPlotFoldersTest.py
MantidPlotMdiSubWindowTest.py
MantidPlotTiledWindowTest.py
)

if ( 0 )
Expand Down
5 changes: 3 additions & 2 deletions Code/Mantid/MantidPlot/src/MdiSubWindow.h
Expand Up @@ -33,6 +33,7 @@
#include <QDockWidget>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QFrame>

#include <stdexcept>

Expand All @@ -41,12 +42,12 @@ class QCloseEvent;
class QString;
class FloatingWindow;

class MdiSubWindowParent_t: public QWidget
class MdiSubWindowParent_t: public QFrame
{
Q_OBJECT
public:
MdiSubWindowParent_t(QWidget* parent, Qt::WFlags f = 0):
QWidget(parent,f),
QFrame(parent,f),
m_widget(NULL)
{}
void setWidget(QWidget* w)
Expand Down
103 changes: 94 additions & 9 deletions Code/Mantid/MantidPlot/src/TiledWindow.cpp
Expand Up @@ -3,10 +3,30 @@

#include <QScrollArea>
#include <QGridLayout>
#include <QMessageBox>
#include <QPainter>

// constants defining the minimum size of tiles
const int minimumTileWidth = 200;
const int minimumTileHeight = 300;
const int minimumTileWidth = 100;
const int minimumTileHeight = 100;

/**
* Constructor.
*/
EmptyTile::EmptyTile(QWidget *parent):
QLabel("Empty tile",parent)
{
setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
setFrameShape( QFrame::Box );
}

/**
* Destructor.
*/
EmptyTile::~EmptyTile()
{
std::cerr << "EmptyTile deleted" << std::endl;
}

/**
* Constructor.
Expand All @@ -23,9 +43,13 @@ TiledWindow::TiledWindow(QWidget* parent, const QString& label, const QString& n

QWidget *innerWidget = new QWidget(scrollArea);
m_layout = new QGridLayout();
m_layout->setMargin(2);
m_layout->setMargin(6);
m_layout->setColumnMinimumWidth(0,minimumTileWidth);
m_layout->setRowMinimumHeight(0,minimumTileHeight);
m_layout->addWidget(new EmptyTile(this), 0, 0);
m_layout->setColumnMinimumWidth(0,minimumTileWidth);
m_layout->setRowMinimumHeight(0,minimumTileHeight);
m_layout->setColStretch(0,1);
innerWidget->setLayout( m_layout );

scrollArea->setWidget(innerWidget);
Expand Down Expand Up @@ -73,6 +97,45 @@ void TiledWindow::reshape(int rows, int cols)
{
}

/**
* If a cell contains an EmptyTile return it. If the cell contains a widget of another type
* throw an exception. If it's empty return NULL.
* @param row :: The row of the cell.
* @param col :: The column of the cell.
*/
EmptyTile *TiledWindow::getEmptyTile(int row, int col) const
{
QLayoutItem *item = m_layout->itemAtPosition( row, col );
if ( !item ) return NULL;
EmptyTile *emptyTile = dynamic_cast<EmptyTile*>( item->widget() );
if ( emptyTile )
{
return emptyTile;
}
QString msg = QString("Cell (%1,%2) is not empty.").arg(row).arg(col);
throw std::invalid_argument(msg.toStdString());
}

/**
* Tile empty cells with EmptyTiles.
*/
void TiledWindow::tileEmptyCells()
{
int nrows = rowCount();
int ncols = columnCount();
for(int row = 0; row < nrows; ++row)
{
for(int col = 0; col < ncols; ++col)
{
QLayoutItem *item = m_layout->itemAtPosition( row, col );
if ( item == NULL )
{
m_layout->addWidget( new EmptyTile(this), row, col );
}
}
}
}

/**
* Add a new sub-window at a given position in the layout.
* The row and column indices do not have to be within the current shape -
Expand All @@ -83,12 +146,29 @@ void TiledWindow::reshape(int rows, int cols)
*/
void TiledWindow::addTile(MdiSubWindow *tile, int row, int col)
{
// detach the tile from ApplicationWindow
tile->detach();
m_layout->setColumnMinimumWidth(col,minimumTileWidth);
m_layout->setRowMinimumHeight(row,minimumTileHeight);
// attach to this window
m_layout->addWidget(tile, row, col);
try
{
EmptyTile *emptyTile = getEmptyTile( row, col );
if ( emptyTile )
{
m_layout->removeWidget( emptyTile );
emptyTile->deleteLater();
}
// detach the tile from ApplicationWindow
tile->detach();
m_layout->setColumnMinimumWidth(col,minimumTileWidth);
m_layout->setRowMinimumHeight(row,minimumTileHeight);
m_layout->setColStretch(col,1);
// attach to this window
m_layout->addWidget(tile, row, col);
//tile->setFrameShape(QFrame::Box);
// fill possible empty spaces with EmptyTiles
tileEmptyCells();
}
catch(std::invalid_argument& ex)
{
QMessageBox::critical(this,"MantidPlot- Error","Cannot add a widget to a TiledWindow:\n\n" + QString::fromStdString(ex.what()));
}
}

/**
Expand All @@ -114,6 +194,8 @@ MdiSubWindow *TiledWindow::getTile(int row, int col) const

/**
* Take a tile at position (row,col), remove it and make docked.
* @param row :: The tile's row index.
* @param col :: The tile's column index.
*/
void TiledWindow::removeTileToDocked(int row, int col)
{
Expand All @@ -127,6 +209,8 @@ void TiledWindow::removeTileToDocked(int row, int col)

/**
* Take a tile at position (row,col), remove it and make floating.
* @param row :: The tile's row index.
* @param col :: The tile's column index.
*/
void TiledWindow::removeTileToFloating(int row, int col)
{
Expand All @@ -137,3 +221,4 @@ void TiledWindow::removeTileToFloating(int row, int col)
tile->undock();
}
}

12 changes: 10 additions & 2 deletions Code/Mantid/MantidPlot/src/TiledWindow.h
Expand Up @@ -3,8 +3,10 @@

#include "MdiSubWindow.h"

class QGridLayout;
#include <QLabel>

class QGridLayout;
class EmptyTile;
/**
*
* A mdi sub-window that contains other sub-windows arranged in rows and columns.
Expand Down Expand Up @@ -39,17 +41,23 @@ public slots:
void print();

private:
/// Tile empty cells with EmptyTiles
void tileEmptyCells();
/// Get an EmptyTile widget at position(row,col).
EmptyTile *getEmptyTile(int row, int col) const;

/// The layout arranging the tiles into a grid.
QGridLayout *m_layout;
};

/**
* A widget-placeholder showing an empty cell where a sub-window can be inserted.
*/
class EmptyTile: public QWidget
class EmptyTile: public QLabel
{
public:
EmptyTile(QWidget *parent);
~EmptyTile();
};

#endif // TiledWindow_H
2 changes: 1 addition & 1 deletion Code/Mantid/MantidPlot/src/qti.sip
Expand Up @@ -35,7 +35,7 @@
%Import QtGui/QtGuimod.sip
%Import mantidqt.sip

class MdiSubWindow: QWidget /PyName=MDIWindow/
class MdiSubWindow: QFrame /PyName=MDIWindow/
{
%TypeHeaderCode
#include "src/MdiSubWindow.h"
Expand Down
5 changes: 5 additions & 0 deletions Code/Mantid/MantidPlot/test/MantidPlotTiledWindowTest.py
Expand Up @@ -38,6 +38,11 @@ def test_removeTile(self):
self.assertFalse( folder.findWindow(t1.name()) is None )
tw.removeTileToFloating(0,1)
self.assertFalse( folder.findWindow(t2.name()) is None )
self.assertTrue( t1.isDocked() )
self.assertTrue( t2.isFloating() )
tw.close()
t1.close()
t2.close()

# Run the unit tests
mantidplottests.runTests(MantidPlotTiledWindowTest)

0 comments on commit 080e0ab

Please sign in to comment.