1 /*
2     This file is part of the KDE project "KAtomic"
3 
4     SPDX-FileCopyrightText: 2006-2007 Dmitry Suzdalev <dimsuz@gmail.com>
5     SPDX-FileCopyrightText: 2010 Brian Croom <brian.s.croom@gmail.com>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #ifndef FIELD_ITEM_H
11 #define FIELD_ITEM_H
12 
13 #include "playfield.h" // for enum PlayField::Direction
14 
15 #include <KGameRenderedItem>
16 
17 #include <QGraphicsTextItem>
18 
19 class KGameRenderer;
20 class atom;
21 
22 /**
23  *  Represents item that can be placed in the PlayField.
24  *  Basically it just extends QGraphicsPixmapItem by understanding
25  *  field's cellbased coords.
26  */
27 class FieldItem : public KGameRenderedItem
28 {
29 public:
30     explicit FieldItem( KGameRenderer* renderer, const QString& spriteKey, QGraphicsScene* scene );
31 
setFieldX(int x)32     void setFieldX(int x) { m_fieldX = x; }
setFieldY(int y)33     void setFieldY(int y) { m_fieldY = y; }
setFieldXY(int x,int y)34     void setFieldXY(int x, int y) { m_fieldX = x; m_fieldY = y; }
35 
fieldX()36     int fieldX() const { return m_fieldX; }
fieldY()37     int fieldY() const { return m_fieldY; }
38 
39     // enable use of qgraphicsitem_cast
40     enum { Type = UserType + 1 };
type()41     int type() const override { return Type; }
42 private:
43     int m_fieldX;
44     int m_fieldY;
45 };
46 
47 /**
48  *  FieldItem that knows what atom number it holds
49  *  @see Molecule
50  */
51 class AtomFieldItem : public FieldItem
52 {
53 public:
54     explicit AtomFieldItem(KGameRenderer* renderer, atom at, QGraphicsScene* scene );
55 
setAtomNum(int n)56     void setAtomNum(int n) { m_atomNum = n; }
atomNum()57     int atomNum() const { return m_atomNum; }
58 
59     /**
60      * Override so that the bonds (child objects) have their render size
61      * adjusted too
62      */
63     void setRenderSize(const QSize& renderSize);
64 
65     /**
66      * Statically render the atom, for MoleculePreviewItem
67      */
68     static QPixmap renderAtom(KGameRenderer* renderer, atom at, int size);
69 
70     // enable use of qgraphicsitem_cast
71     enum { Type = UserType + 2 };
type()72     int type() const override { return Type; }
73 private:
74     // from molecule
75     int m_atomNum;
76 
77     static QHash<char, QString> s_names; // cryptic_char -> elemName
78     static QHash<char, QString> s_bondNames; // cryptic_char -> bondName
79 
80     /**
81      * Creates hashes for translating atom and bond signatures found in
82      * level files to corresponding SVG-element names
83      */
84     static void fillNameHashes();
85 };
86 
87 class QTimeLine;
88 /**
89  *  FieldItem that represents clickable arrow.
90  *  While showing plays nice fade-in effect
91  */
92 class ArrowFieldItem : public QObject, public FieldItem
93 {
94     Q_OBJECT
95 public:
96     explicit ArrowFieldItem( KGameRenderer* renderer, PlayField::Direction dir, QGraphicsScene* scene );
97     ~ArrowFieldItem() override;
98 
99     // enable use of qgraphicsitem_cast
100     enum { Type = UserType + 3 };
type()101     int type() const override { return Type; }
102 private Q_SLOTS:
103     void setOpacity( qreal opacity );
104 private:
105     QVariant itemChange( GraphicsItemChange change, const QVariant& value ) override;
106 
107     /**
108      *  Timeline object to control fade-in animation
109      */
110     QTimeLine *m_timeLine;
111 };
112 
113 class Molecule;
114 class PlayField;
115 
116 /**
117  *  QGraphicsItem which displays molecule preview.
118  */
119 class MoleculePreviewItem : public QGraphicsItem
120 {
121 public:
122     explicit MoleculePreviewItem( PlayField* scene );
123     ~MoleculePreviewItem() override;
124 
125     /**
126      *  Sets molecule to display
127      */
128     void setMolecule( const Molecule* mol );
129 
130     /**
131      *  Sets item width. Height will be calculated automatically
132      */
133     void setWidth( int width );
134     /**
135      *  Sets maximum atom size in rendered molecule preview.
136      *  Usually atom size is calculated so the whole molecule can fit
137      *  in the item.
138      *  In some cases - when item width is big and the molecule is small this
139      *  can lead to preview having a huge molecule with atom size larger than
140      *  in playfield :). That looks not very good, hence this function.
141      */
142     void setMaxAtomSize( int maxSize );
143 
boundingRect()144     inline QRectF boundingRect() const override { return QRectF(0,0, m_width, m_width); } // reimp
145 private:
146     void paint( QPainter * painter, const QStyleOptionGraphicsItem*, QWidget * widget = nullptr ) override;
147 
148     KGameRenderer* m_renderer;
149     int m_width;
150     int m_atomSize;
151     int m_maxAtomSize;
152     const Molecule* m_mol;
153 };
154 
155 #endif
156