color scheme, randomizing, state saving/restore
authorSerge Ziryukin <ftrvxmtrx@gmail.com>
Fri, 2 Apr 2010 18:52:17 +0000 (21:52 +0300)
committerSerge Ziryukin <ftrvxmtrx@gmail.com>
Fri, 2 Apr 2010 18:52:17 +0000 (21:52 +0300)
colorflood/src/CMakeLists.txt
colorflood/src/colorscheme.cpp [new file with mode: 0644]
colorflood/src/colorscheme.hpp [new file with mode: 0644]
colorflood/src/field.cpp
colorflood/src/field.hpp
colorflood/src/window.cpp
colorflood/src/window.hpp

index e3d2778..719fbf0 100644 (file)
@@ -13,6 +13,7 @@ set(src
   field.cpp
   main.cpp
   window.cpp
   field.cpp
   main.cpp
   window.cpp
+  colorscheme.cpp
   )
 
 set(moc
   )
 
 set(moc
diff --git a/colorflood/src/colorscheme.cpp b/colorflood/src/colorscheme.cpp
new file mode 100644 (file)
index 0000000..c7cd4be
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+  Copyright 2010 Serge Ziryukin <ftrvxmtrx@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; version 2 of the License.
+
+  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.
+*/
+
+#include <QSettings>
+#include "colorscheme.hpp"
+
+static int currentScheme = 0;
+static QVector<QPair<QString, QVector<QBrush> > > schemes;
+
+ColorScheme::ColorScheme ()
+{
+    schemes.clear();
+
+    QVector<QBrush> s;
+
+    s << QColor(0x00, 0x00, 0xff); // blue
+    s << QColor(0xff, 0x00, 0x00); // red
+    s << QColor(0x00, 0xff, 0x00); // green
+    s << QColor(0xff, 0xff, 0x00); // yellow
+    s << QColor(0xff, 0x00, 0xff); // magenta
+    s << QColor(0x80, 0x00, 0x80); // purple
+    schemes << QPair<QString, QVector<QBrush> >(QObject::tr("Default"), s);
+
+    s.clear();
+    s << QBrush(QColor(0x00, 0x00, 0x00), Qt::SolidPattern);
+    s << QBrush(QColor(0x33, 0x33, 0x33), Qt::Dense3Pattern);
+    s << QBrush(QColor(0x66, 0x66, 0x66), Qt::Dense1Pattern);
+    s << QBrush(QColor(0x99, 0x99, 0x99), Qt::SolidPattern);
+    s << QBrush(QColor(0xcc, 0xcc, 0xcc), Qt::CrossPattern);
+    s << QBrush(QColor(0xff, 0xff, 0xff), Qt::SolidPattern);
+    schemes << QPair<QString, QVector<QBrush> >(QObject::tr("Black-and-white"), s);
+
+    QSettings settings;
+    currentScheme = settings.value("colorScheme", 0).toInt();
+
+    if (currentScheme < 0 || currentScheme > s.size())
+        currentScheme = 0;
+}
+
+ColorScheme::~ColorScheme ()
+{
+    QSettings settings;
+    settings.setValue("colorScheme", currentScheme);
+}
+
+int ColorScheme::getNumSchemes ()
+{
+    return schemes.size();
+}
+
+QString ColorScheme::getSchemeName (int scheme)
+{
+    Q_ASSERT(scheme > 0 && scheme < getNumSchemes());
+    return schemes.at(scheme).first;
+}
+
+const QVector<QBrush> &ColorScheme::getScheme (int scheme)
+{
+    Q_ASSERT(scheme > 0 && scheme < getNumSchemes());
+    return schemes.at(scheme).second;
+}
+
+QString ColorScheme::getSchemeName ()
+{
+    return schemes.at(currentScheme).first;
+}
+
+const QVector<QBrush> &ColorScheme::getScheme ()
+{
+    return schemes.at(currentScheme).second;
+}
+
+void ColorScheme::setScheme (int scheme)
+{
+    Q_ASSERT(scheme >= 0 && scheme < getNumSchemes());
+    currentScheme = scheme;
+}
diff --git a/colorflood/src/colorscheme.hpp b/colorflood/src/colorscheme.hpp
new file mode 100644 (file)
index 0000000..c366def
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+  Copyright 2010 Serge Ziryukin <ftrvxmtrx@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; version 2 of the License.
+
+  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.
+*/
+
+#ifndef _COLORSCHEME_HPP
+#define _COLORSCHEME_HPP
+
+#include <QVector>
+#include <QPair>
+#include <QBrush>
+#include <QString>
+
+class ColorScheme
+{
+public:
+    static ColorScheme & instance ()
+        {
+            static ColorScheme instance;
+            return instance;
+        }
+
+    static int getNumSchemes ();
+    static QString getSchemeName (int scheme);
+    const QVector<QBrush> &getScheme (int scheme);
+    static QString getSchemeName ();
+    const QVector<QBrush> &getScheme ();
+    static void setScheme (int scheme);
+
+private:
+    ColorScheme ();
+    ~ColorScheme ();
+    ColorScheme (const ColorScheme &);
+    ColorScheme & operator= (const ColorScheme &);
+};
+
+#endif /* !_COLORSCHEME_HPP */
index d47250a..3465e78 100644 (file)
 
 #include <QtGui>
 #include "field.hpp"
 
 #include <QtGui>
 #include "field.hpp"
+#include "colorscheme.hpp"
 
 static const int fieldWidth = 420;
 
 const int Field::rects[Field::NUM_SIZES] = { 14, 21, 28 };
 const int Field::turns[Field::NUM_SIZES] = { 25, 35, 50 };
 
 
 static const int fieldWidth = 420;
 
 const int Field::rects[Field::NUM_SIZES] = { 14, 21, 28 };
 const int Field::turns[Field::NUM_SIZES] = { 25, 35, 50 };
 
-Field::Field (QWidget *parent)
-    : QWidget (parent)
+// we declare out QVector<FieldRect> metatype
+// and stream operators to save whole field to settings
+Q_DECLARE_METATYPE(Field::RectVector);
+
+static QDataStream &operator<< (QDataStream &out, const Field::RectVector &rv)
 {
 {
-    // FIXME -- restore saved state
+    for (QVector<Field::FieldRect>::const_iterator rect = rv.begin();
+         rect != rv.end();
+         rect++)
+    {
+        out << (*rect).brush;
+        out << (*rect).flood;
+    }
+
+    return out;
 }
 
 }
 
-Field::Field (QWidget *parent, const QVector<QBrush> &brushes, FieldSize size)
+static QDataStream &operator>> (QDataStream &in, Field::RectVector &rv)
+{
+    Field::FieldRect r;
+
+    rv.clear();
+
+    for (; !in.atEnd() ;)
+    {
+        in >> r.brush >> r.flood;
+        rv << r;
+    }
+
+    rv.pop_back();
+
+    return in;
+}
+
+Field::Field (QWidget *parent)
     : QWidget (parent)
 {
     : QWidget (parent)
 {
-    init(brushes, size);
+    setFixedSize(fieldWidth, fieldWidth);
+
+    // restore field size and field itself from settings
+
+    qRegisterMetaType<RectVector>("Field::RectVector");
+    qRegisterMetaTypeStreamOperators<RectVector>("Field::RectVector");
+
+    QSettings settings;
+
+    int size = settings.value("field/fieldSize", SIZE_SMALL).toInt();
+
+    if (size < SIZE_SMALL || size >= NUM_SIZES)
+        size = SIZE_SMALL;
+
+    this->size = (FieldSize)size;
+
+    if (settings.contains("field/data"))
+        data = settings.value("field/data").value<RectVector>();
+
+    if (data.size() != rects[size] * rects[size])
+        randomize();
 }
 
 Field::~Field ()
 {
 }
 
 Field::~Field ()
 {
-    // FIXME -- save state
+    QSettings settings;
+
+    settings.setValue("field/size", size);
+
+    QVariant v;
+    v.setValue(data);
+    settings.setValue("field/data", v);
 }
 
 Field::FieldSize Field::getSize () const
 }
 
 Field::FieldSize Field::getSize () const
@@ -41,27 +96,26 @@ Field::FieldSize Field::getSize () const
     return size;
 }
 
     return size;
 }
 
-/*
-=================
-randomize
-=================
-*/
 void Field::randomize ()
 {
 void Field::randomize ()
 {
-    Field::FieldRect rect;
+    FieldRect rect;
     rect.flood = false;
 
     data.clear();
     rect.flood = false;
 
     data.clear();
-    data = QVector<FieldRect> (rects[size] * rects[size], rect);
+    data = RectVector(rects[size] * rects[size], rect);
 
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
 
     qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
 
-    for (QVector<Field::FieldRect>::iterator rect = data.begin();
+    int numBrushes = ColorScheme::instance().getScheme().size();
+
+    for (QVector<FieldRect>::iterator rect = data.begin();
          rect != data.end();
          rect++)
     {
          rect != data.end();
          rect++)
     {
-        (*rect).brush = qrand() % brushes.size();
+        (*rect).brush = qrand() % numBrushes;
     }
     }
+
+    update();
 }
 
 int Field::getNumRectsOfSize (FieldSize size)
 }
 
 int Field::getNumRectsOfSize (FieldSize size)
@@ -74,15 +128,6 @@ int Field::getNumTurnsOfSize (FieldSize size)
     return turns[size];
 }
 
     return turns[size];
 }
 
-void Field::init (const QVector<QBrush> &brushes, FieldSize size)
-{
-    this->size = size;
-    this->brushes = brushes;
-
-    setFixedSize(fieldWidth, fieldWidth);
-    randomize();
-}
-
 int Field::getRectSize (FieldSize size)
 {
     return fieldWidth / rects[size];
 int Field::getRectSize (FieldSize size)
 {
     return fieldWidth / rects[size];
@@ -95,6 +140,8 @@ void Field::paintEvent (QPaintEvent *event)
 
     QRect rect = QRect(0, 0, getRectSize(size), getRectSize(size));
 
 
     QRect rect = QRect(0, 0, getRectSize(size), getRectSize(size));
 
+    const QVector<QBrush> &scheme = ColorScheme::instance().getScheme();
+
     for (int y = 0; y < rects[size] ;y++)
     {
         int n = y * rects[size];
     for (int y = 0; y < rects[size] ;y++)
     {
         int n = y * rects[size];
@@ -104,7 +151,7 @@ void Field::paintEvent (QPaintEvent *event)
             rect.moveTo(x * rect.width(), y * rect.height());
 
             if (rect.intersects(event->rect()))
             rect.moveTo(x * rect.width(), y * rect.height());
 
             if (rect.intersects(event->rect()))
-                painter.fillRect(rect, brushes.at(data[n].brush));
+                painter.fillRect(rect, scheme.at(data[n].brush));
         }
     }
 
         }
     }
 
index 06ccf28..0d78d34 100644 (file)
@@ -33,7 +33,14 @@ public:
         NUM_SIZES
     }FieldSize;
 
         NUM_SIZES
     }FieldSize;
 
-    Field (QWidget *parent, const QVector<QBrush> &brushes, FieldSize size);
+    typedef struct
+    {
+        quint8 brush;
+        bool   flood;
+    }FieldRect;
+
+    typedef QVector<Field::FieldRect> RectVector;
+
     Field (QWidget *parent);
     ~Field ();
 
     Field (QWidget *parent);
     ~Field ();
 
@@ -44,21 +51,14 @@ public:
     static int getNumTurnsOfSize (FieldSize size);
 
 private:
     static int getNumTurnsOfSize (FieldSize size);
 
 private:
-    typedef struct
-    {
-        char brush;
-        bool flood;
-    }FieldRect;
-
     static const int rects[NUM_SIZES];
     static const int turns[NUM_SIZES];
 
     void init (const QVector<QBrush> &brushes, FieldSize size);
     static int getRectSize (FieldSize size);
 
     static const int rects[NUM_SIZES];
     static const int turns[NUM_SIZES];
 
     void init (const QVector<QBrush> &brushes, FieldSize size);
     static int getRectSize (FieldSize size);
 
-    FieldSize          size;
-    QVector<QBrush>    brushes;
-    QVector<FieldRect> data;
+    FieldSize  size;
+    RectVector data;
 
 protected:
     void paintEvent (QPaintEvent *event);
 
 protected:
     void paintEvent (QPaintEvent *event);
index 0ee5554..a189dcf 100644 (file)
 Window::Window ()
     : QWidget()
 {
 Window::Window ()
     : QWidget()
 {
-    setWindowTitle(tr("Color flood"));
-
-    setWindowState(windowState() | Qt::WindowFullScreen);
-
-    QVector<QBrush> brushes;
-
-#if 1
-    // standart color scheme
-    brushes << QBrush(QColor(0x00, 0x00, 0xff)); // blue
-    brushes << QBrush(QColor(0xff, 0x00, 0x00)); // red
-    brushes << QBrush(QColor(0x00, 0xff, 0x00)); // green
-    brushes << QBrush(QColor(0xff, 0xff, 0x00)); // yellow
-    brushes << QBrush(QColor(0xff, 0x00, 0xff)); // magenta
-    brushes << QBrush(QColor(0x80, 0x00, 0x80)); // purple
-#else
-    // color-blind color scheme
-    brushes << QBrush(QColor(0x00, 0x00, 0x00));
-    brushes << QBrush(QColor(0x31, 0x31, 0x31), Qt::Dense1Pattern);
-    brushes << QBrush(QColor(0x62, 0x62, 0x62), Qt::Dense3Pattern);
-    brushes << QBrush(QColor(0x93, 0x93, 0x93), Qt::CrossPattern);
-    brushes << QBrush(QColor(0xc4, 0xc4, 0xc4));
-    brushes << QBrush(QColor(0xff, 0xff, 0xff));
-#endif
-
-    field = new Field(this, brushes, Field::SIZE_LARGE);
+    setWindowTitle(tr("Color Flood"));
+
+    //setWindowState(windowState() | Qt::WindowFullScreen);
+
+    QPushButton *button = new QPushButton("randomize", this);
+    field = new Field(this);
+
+    QObject::connect(button, SIGNAL(pressed()), this, SLOT(randomize()));
 
     QHBoxLayout *layout = new QHBoxLayout;
 
     QHBoxLayout *layout = new QHBoxLayout;
+    layout->addWidget(button);
+    layout->setAlignment(button, Qt::AlignLeft);
     layout->addWidget(field);
     layout->setAlignment(field, Qt::AlignRight);
     setLayout(layout);
 }
     layout->addWidget(field);
     layout->setAlignment(field, Qt::AlignRight);
     setLayout(layout);
 }
+
+void Window::randomize ()
+{
+    field->randomize();
+}
index b76d9b1..808b89f 100644 (file)
@@ -25,6 +25,9 @@ class Window : public QWidget
 public:
     Window ();
 
 public:
     Window ();
 
+public slots:
+    void randomize ();
+
 private:
     Field *field;
 };
 private:
     Field *field;
 };