File indexing completed on 2024-05-12 04:05:54

0001 /***************************************************************************
0002  *   Copyright 2007      Johannes Bergmeier <johannes.bergmeier@gmx.net>   *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0018  ***************************************************************************/
0019 
0020 #include "valuelistwidget.h"
0021 
0022 
0023 
0024 #include <QGraphicsSimpleTextItem>
0025 #include <QWheelEvent>
0026 
0027 #include <KColorScheme>
0028 
0029 #include "renderer.h"
0030 
0031 namespace ksudoku {
0032 
0033 class SymbolItem : public QGraphicsPixmapItem {
0034 public:
0035     SymbolItem(int value, int maxValue, ValueListWidget* widget);
0036 public:
0037     int value() const;
0038     int maxValue() const;
0039     void setSize(double size);
0040     void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
0041 private:
0042     int m_value;
0043     int m_maxValue;
0044     double m_size;
0045     ValueListWidget* m_widget;
0046 };
0047 
0048 
0049 SymbolItem::SymbolItem(int value, int maxValue, ValueListWidget* widget)
0050     : m_widget(widget)
0051 {
0052     setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
0053     m_value = value;
0054     m_maxValue = maxValue;
0055 }
0056 
0057 int SymbolItem::value() const {
0058     return m_value;
0059 }
0060 
0061 void SymbolItem::setSize(double size) {
0062     QPixmap pic = Renderer::instance()->renderSpecial(SpecialListItem, size);
0063     pic = Renderer::instance()->renderSymbolOn(pic, m_value, 0, m_maxValue, SymbolPreset);
0064 
0065     hide();
0066     setPixmap(pic);
0067     setOffset(-size*0.5, -size*0.5);
0068     setPos(0, (m_value-1)*size);
0069     show();
0070 }
0071 
0072 void SymbolItem::mousePressEvent(QGraphicsSceneMouseEvent*) {
0073     m_widget->selectValueItem(value());
0074 }
0075 
0076 
0077 
0078 class SelectionItem : public QGraphicsPixmapItem {
0079 public:
0080     SelectionItem();
0081 public:
0082     void setSize(double size);
0083     int selectedValue() const;
0084     void selectValue(int value);
0085 public:
0086     double m_size;
0087     int m_value;
0088 };
0089 
0090 SelectionItem::SelectionItem() {
0091     m_value = 0;
0092     setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
0093 }
0094 
0095 void SelectionItem::setSize(double size) {
0096     QPixmap pic = Renderer::instance()->renderSpecial(SpecialListCursor, size);
0097     m_size = size;
0098 
0099     hide();
0100     setPixmap(pic);
0101     setOffset(-size*0.5, -size*0.5);
0102     setPos(0, (m_value-1) * m_size);
0103     show();
0104 }
0105 
0106 int SelectionItem::selectedValue() const {
0107     return m_value;
0108 }
0109 
0110 void SelectionItem::selectValue(int value) {
0111     m_value = value;
0112     setPos(0, (m_value-1) * m_size);
0113 }
0114 
0115 
0116 ValueListWidget::ValueListWidget(QWidget* parent)
0117     : QGraphicsView(parent)
0118 {
0119     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0120     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0121     setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0122     
0123     m_scene = new QGraphicsScene(this);
0124     setScene(m_scene);
0125     
0126     m_selectionItem = new SelectionItem();
0127     m_scene->addItem(m_selectionItem);
0128     
0129     setMaxValue(1); // Make SymbolItem list non-empty, in case of a resize.
0130     m_selectedValue = 1;
0131 }
0132 
0133 ValueListWidget::~ValueListWidget() {
0134 }
0135 
0136 void ValueListWidget::setMaxValue(int maxValue) {
0137     m_maxValue = maxValue;
0138 
0139     SymbolItem* item;
0140     QList<SymbolItem*>::iterator it;
0141     for(it = m_symbols.begin(); it != m_symbols.end(); ++it) {
0142         delete *it;
0143     }
0144     m_symbols.clear();
0145     
0146     for(int i = 0; i < maxValue; ++i) {
0147         item = new SymbolItem(i+1, maxValue, this);
0148         item->setSize(20);
0149         item->setPos(0, (i+0.5)*20);
0150         m_scene->addItem(item);
0151         m_symbols.append(item);
0152     }
0153     
0154     if(m_selectedValue > m_maxValue) m_selectedValue = 1;
0155 
0156     resizeEvent(nullptr);
0157 }
0158 
0159 void ValueListWidget::resizeEvent(QResizeEvent*)
0160 {
0161     QSize s = size();
0162     // Allow 4 as a margin and to avoid problems with the border.
0163     int size = qMin((s.width() - 4), (s.height() - 4)/m_maxValue);
0164     size = (size < 4) ? 4 : size;   // NB. Negative size --> painter errors.
0165     for(int i = 0; i < m_maxValue; ++i) {
0166         m_symbols[i]->setSize(size);
0167     }
0168     m_scene->setSceneRect(-size/2, -size/2, size, m_maxValue*size);
0169 
0170     m_selectionItem->setSize(size);
0171 }
0172 
0173 void ValueListWidget::selectValue(int value) {
0174     m_selectedValue = value;
0175     m_selectionItem->selectValue(value);
0176 }
0177 
0178 void ValueListWidget::selectValueItem(int value) {
0179     selectValue(value);
0180     Q_EMIT valueSelected(value);
0181 }
0182 
0183 void ValueListWidget::wheelEvent (QWheelEvent* e) {
0184     int value = (m_selectedValue - e->angleDelta().y()/120) % m_maxValue;
0185     if(value <= 0) value = m_maxValue - value;
0186     selectValueItem(value);
0187 }
0188 
0189 }
0190 
0191 #include "moc_valuelistwidget.cpp"