New bag widget, showing the remaining tiles. Not used for real yet.

This commit is contained in:
Olivier Teulière 2010-11-01 17:49:55 +00:00
parent 1374304ff9
commit af37443fc0
8 changed files with 301 additions and 23 deletions

View file

@ -57,13 +57,14 @@ EXTRA_DIST = \
eliot_SOURCES = \
qtcommon.h qtcommon.cpp \
coord_model.h coord_model.cpp \
tile_widget.cpp tile_widget.h \
tile_layout.cpp tile_layout.h \
bag_widget.cpp bag_widget.h \
bag_widget2.cpp bag_widget2.h \
dic_tools_widget.cpp dic_tools_widget.h \
new_game.cpp new_game.h \
score_widget.cpp score_widget.h \
dic_wizard.cpp dic_wizard.h \
tile_widget.cpp tile_widget.h \
board_widget.cpp board_widget.h \
history_widget.cpp history_widget.h \
play_word_mediator.cpp play_word_mediator.h \
@ -86,13 +87,14 @@ nodist_eliot_SOURCES = \
ui/dic_wizard_letters_def_page.ui.h \
ui/dic_wizard_conclusion_page.ui.h \
coord_model.moc.cpp \
tile_widget.moc.cpp \
tile_layout.moc.cpp \
new_game.moc.cpp \
dic_tools_widget.moc.cpp \
bag_widget.moc.cpp \
bag_widget2.moc.cpp \
score_widget.moc.cpp \
dic_wizard.moc.cpp \
tile_widget.moc.cpp \
board_widget.moc.cpp \
history_widget.moc.cpp \
play_word_mediator.moc.cpp \

100
qt/bag_widget2.cpp Normal file
View file

@ -0,0 +1,100 @@
/*****************************************************************************
* Eliot
* Copyright (C) 2010 Olivier Teulière
* Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#include <boost/foreach.hpp>
#include <vector>
#include "bag_widget2.h"
#include "tile_layout.h"
#include "tile_widget.h"
#include "qtcommon.h"
#include "public_game.h"
#include "dic.h"
#include "tile.h"
#include "bag.h"
using namespace std;
BagWidget2::BagWidget2(QWidget *parent)
: QWidget(parent), m_game(NULL)
{
TileLayout *layout = new TileLayout(0, 5);
setLayout(layout);
}
void BagWidget2::setGame(const PublicGame *iGame)
{
bool needToPopulate = (m_game != iGame && iGame != NULL);
m_game = iGame;
if (needToPopulate)
{
TileLayout *layout = (TileLayout*) this->layout();
layout->clear();
BOOST_FOREACH(const Tile &tile, m_game->getDic().getAllTiles())
{
for (unsigned i = 0; i < tile.maxNumber(); ++i)
{
TileWidget *tileWidget = new TileWidget(this, TileWidget::NONE, 0, 0);
TileWidgetDecorator *decoWidget = new TileWidgetDecorator(this, *tileWidget);
decoWidget->tileChanged(tile, false, TileWidget::NORMAL);
layout->addWidget(decoWidget);
}
}
}
refresh();
}
void BagWidget2::refresh()
{
if (m_game == NULL)
return;
int index = 0;
const Bag &bag = m_game->getBag();
BOOST_FOREACH(const Tile &tile, m_game->getDic().getAllTiles())
{
unsigned int nbInBag = bag.in(tile);
for (unsigned i = 0; i < nbInBag; ++i)
{
TileWidget *tileWidget = (TileWidget*) layout()->itemAt(index)->widget();
tileWidget->tileChanged(tile, false, TileWidget::NORMAL);
++index;
}
for (unsigned i = nbInBag; i < tile.maxNumber(); ++i)
{
TileWidget *tileWidget = (TileWidget*) layout()->itemAt(index)->widget();
tileWidget->tileChanged(tile, false, TileWidget::PLAYED);
++index;
}
}
}
QSize BagWidget2::sizeHint() const
{
return QSize(160, 300);
}

50
qt/bag_widget2.h Normal file
View file

@ -0,0 +1,50 @@
/*****************************************************************************
* Eliot
* Copyright (C) 2010 Olivier Teulière
* Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#ifndef BAG_WIDGET2_H_
#define BAG_WIDGET2_H_
#include <QtGui/QWidget>
class PublicGame;
class BagWidget2: public QWidget
{
Q_OBJECT;
public:
explicit BagWidget2(QWidget *parent = 0);
public slots:
void setGame(const PublicGame *iGame);
void refresh();
protected:
/// Define a default size
virtual QSize sizeHint() const;
private:
/// Encapsulated game, can be NULL
const PublicGame *m_game;
};
#endif

View file

@ -134,7 +134,7 @@ void BoardWidget::refresh()
m_widgetsMatrix[row][col]->tileChanged(
board.getTile(row, col),
board.isJoker(row, col),
board.isTestChar(row, col));
board.isTestChar(row, col) ? TileWidget::PREVIEW : TileWidget::NORMAL);
}
}
}
@ -172,7 +172,6 @@ void BoardWidget::paintEvent(QPaintEvent *)
}
void BoardWidget::tileClicked(int row, int col, QMouseEvent *iEvent)
{
if (m_game == NULL)

View file

@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#include <cmath>
// XXX: tmp
#include <iostream>
#include "tile_layout.h"
#include "tile_widget.h"
@ -25,13 +29,19 @@ using namespace std;
TileLayout::TileLayout(int nbCols, int spacing)
: m_nbCols(nbCols), m_space(spacing)
: m_dynamic(nbCols == 0), m_nbCols(nbCols), m_nbRows(nbCols), m_space(spacing)
{
setContentsMargins(0, 0, 0, 0);
}
TileLayout::~TileLayout()
{
clear();
}
void TileLayout::clear()
{
QLayoutItem *item;
while ((item = takeAt(0)))
@ -82,12 +92,54 @@ void TileLayout::setGeometry(const QRect &rect)
void TileLayout::doLayout(const QRect &rect)
{
int size = std::min(rect.width(), rect.height());
int squareSize = size / m_nbCols - m_space;
QLayoutItem *item;
const int width = rect.width() + m_space;
const int height = rect.height() + m_space;
if (m_dynamic)
{
// Dynamic number of columns. The square size is the biggest one
// allowing to place all the tiles in the given rect without scrolling.
// This determines the number of columns.
const int tilesCount = m_items.size();
int bestNbCols = 0;
int bestSquareSize = 0;
for (int nbCols = 1; nbCols <= tilesCount; ++nbCols)
{
const int nbRows = (tilesCount - 1) / nbCols + 1;
int squareSize = std::min(width / nbCols, height / nbRows);
if (squareSize >= bestSquareSize)
{
bestNbCols = nbCols;
bestSquareSize = squareSize;
}
else
{
// Maximum reached
break;
}
}
if (bestNbCols == 0)
{
m_nbCols = (int) sqrt(tilesCount);
m_nbRows = m_nbCols;
}
else
{
m_nbCols = bestNbCols;
m_nbRows = (tilesCount - 1) / m_nbCols + 1;
}
}
if (m_nbCols == 0)
return;
// Now the number of columns and rows are defined.
// Use that to draw the tiles.
const int squareSize = std::min(width / m_nbCols, height / m_nbRows) - m_space;
int x = 0;
int y = 0;
int nbInRow = 1;
QLayoutItem *item;
foreach (item, m_items)
{
QRect itemRect(QPoint(x, y), QSize(squareSize, squareSize));

View file

@ -22,7 +22,6 @@
#define TILE_LAYOUT_H_
#include <QtGui/QLayout>
//#include <QtGui/QList>
class TileLayout : public QLayout
@ -33,6 +32,8 @@ public:
TileLayout(int nbCols, int spacing);
virtual ~TileLayout();
void clear();
QRect getBoardRect() const;
int getSquareSize() const;
@ -51,7 +52,9 @@ public:
private:
QList<QLayoutItem *> m_items;
bool m_dynamic;
int m_nbCols;
int m_nbRows;
int m_space;
void doLayout(const QRect &rect);

View file

@ -38,6 +38,7 @@ const QColor TileWidget::W2Colour(255, 147, 196);
const QColor TileWidget::W3Colour(240, 80, 94);
const QColor TileWidget::TileColour(255, 235, 205);
const QColor TileWidget::PreviewColour(183, 183, 123);
const QColor TileWidget::PlayedColour(Qt::white);
const QColor TileWidget::NormalColour(0, 0, 0);
const QColor TileWidget::JokerColour(255, 0, 0);
const QColor TileWidget::ArrowColour(10, 10, 10);
@ -79,12 +80,13 @@ void BasicTileWidget::paintEvent(QPaintEvent *)
painter.drawText(1, 1, squareSize, squareSize, Qt::AlignCenter, m_text);
}
// --------------
TileWidget::TileWidget(QWidget *parent, Multiplier multiplier,
int row, int col)
: BasicTileWidget(parent), m_multiplier(multiplier),
m_row(row), m_col(col), m_isJoker(false),
m_isPreview(false), m_showArrow(false), m_horizontalArrow(true)
m_state(NORMAL), m_showArrow(false), m_horizontalArrow(true)
{
QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
policy.setHeightForWidth(true);
@ -92,11 +94,11 @@ TileWidget::TileWidget(QWidget *parent, Multiplier multiplier,
}
void TileWidget::tileChanged(const Tile &iTile, bool isJoker, bool isPreview)
void TileWidget::tileChanged(const Tile &iTile, bool isJoker, State state)
{
m_tile = iTile;
m_isJoker = isJoker;
m_isPreview = isPreview;
m_state = state;
update();
}
@ -128,8 +130,10 @@ void TileWidget::paintEvent(QPaintEvent *)
QColor color;
if (!m_tile.isEmpty())
{
if (m_isPreview)
if (m_state == PREVIEW)
color = PreviewColour;
else if (m_state == PLAYED)
color = PlayedColour;
else
color = TileColour;
}
@ -163,7 +167,7 @@ void TileWidget::paintEvent(QPaintEvent *)
const bool showPoints = qs.value(PrefsDialog::kINTF_SHOW_TILES_POINTS, true).toBool();
// Draw the points of the tile
if (showPoints && !m_isJoker)
if (showPoints && !m_isJoker && !m_tile.isJoker())
{
painter.setFont(pointsFont);
painter.drawText(0,
@ -199,6 +203,11 @@ void TileWidget::paintEvent(QPaintEvent *)
painter.setPen(QPen());
painter.setBrush(NormalColour);
}
if (m_state == PLAYED)
{
painter.drawLine(QLine(0, 0, squareSize, squareSize));
painter.drawLine(QLine(0, squareSize, squareSize, 0));
}
}
@ -207,3 +216,35 @@ void TileWidget::mousePressEvent(QMouseEvent *iEvent)
emit mousePressed(m_row, m_col, iEvent);
}
// --------------
TileWidgetDecorator::TileWidgetDecorator(QWidget *parent, TileWidget &wrapped)
: TileWidget(parent), m_wrapped(wrapped)
{
QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins(1, 1, 1, 1);
layout->addWidget(&m_wrapped);
setLayout(layout);
QObject::connect(&m_wrapped, SIGNAL(mousePressed(int, int, QMouseEvent*)),
this, SIGNAL(mousePressed(int, int, QMouseEvent*)));
}
void TileWidgetDecorator::tileChanged(const Tile &iTile, bool isJoker, State state)
{
m_wrapped.tileChanged(iTile, isJoker, state);
}
void TileWidgetDecorator::arrowChanged(bool showArrow, bool horizontalArrow)
{
m_wrapped.arrowChanged(showArrow, horizontalArrow);
}
void TileWidgetDecorator::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawRect(0, 0, width() - 1, height() - 1);
}

View file

@ -58,19 +58,27 @@ class TileWidget: public BasicTileWidget
public:
enum Multiplier
{
NONE = 0,
LETTER_DOUBLE = 1,
LETTER_TRIPLE = 2,
WORD_DOUBLE = 3,
WORD_TRIPLE = 4
NONE,
LETTER_DOUBLE,
LETTER_TRIPLE,
WORD_DOUBLE,
WORD_TRIPLE
};
enum State
{
NORMAL,
PREVIEW,
PLAYED,
IN_RACK
};
explicit TileWidget(QWidget *parent = 0, Multiplier multiplier = NONE,
int row = 0, int col = 0);
public slots:
void tileChanged(const Tile &iTile, bool isJoker, bool isPreview);
void arrowChanged(bool showArrow, bool horizontalArrow);
virtual void tileChanged(const Tile &iTile, bool isJoker, State state);
virtual void arrowChanged(bool showArrow, bool horizontalArrow);
signals:
void mousePressed(int row, int col, QMouseEvent *iEvent);
@ -96,8 +104,8 @@ private:
/// Whether the tile is a joker
bool m_isJoker;
/// Whether the tile is used as a preview
bool m_isPreview;
/// State of the tile
State m_state;
/// Whether we should show the arrow
bool m_showArrow;
@ -114,11 +122,34 @@ private:
static const QColor W3Colour;
static const QColor TileColour;
static const QColor PreviewColour;
static const QColor PlayedColour;
static const QColor NormalColour;
static const QColor JokerColour;
static const QColor ArrowColour;
//@}
};
class TileWidgetDecorator : public TileWidget
{
Q_OBJECT;
public:
TileWidgetDecorator(QWidget *parent, TileWidget &wrapped);
public slots:
virtual void tileChanged(const Tile &iTile, bool isJoker, State state);
virtual void arrowChanged(bool showArrow, bool horizontalArrow);
signals:
void mousePressed(int row, int col, QMouseEvent *iEvent);
protected:
/// Paint the square
virtual void paintEvent(QPaintEvent *iEvent);
private:
TileWidget & m_wrapped;
};
#endif