1 /***********************************************************************
2  *
3  * Copyright (C) 2009 Graeme Gott <graeme@gottcode.org>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  ***********************************************************************/
19 
20 #include "letter.h"
21 
22 #include "board.h"
23 #include "cell.h"
24 #include "word.h"
25 
26 #include <QCursor>
27 #include <QFont>
28 #include <QGraphicsSceneMouseEvent>
29 #include <QGraphicsSimpleTextItem>
30 #include <QPainterPath>
31 #include <QPen>
32 
Letter(const QChar & character,Board * board)33 Letter::Letter(const QChar& character, Board* board)
34 : m_board(board), m_character(character), m_cell(0), m_correct(false), m_movable(true), m_dragged(false), m_shadow(0) {
35 	QPainterPath path;
36 	path.addRoundedRect(0, 0, 32, 32, 5, 5);
37 	setPath(path);
38 	setCursor(Qt::OpenHandCursor);
39 	setPen(Qt::NoPen);
40 	setBrush(QColor("#bbbbbb"));
41 	setFlag(QGraphicsItem::ItemIsMovable);
42 	setZValue(1);
43 
44 	m_text = new QGraphicsSimpleTextItem(this);
45 
46 	QFont f = m_text->font();
47 	f.setPixelSize(20);
48 	f.setWeight(QFont::Bold);
49 	m_text->setFont(f);
50 	m_text->setBrush(Qt::white);
51 	setText(m_character);
52 }
53 
54 //-----------------------------------------------------------------------------
55 
setCell(Cell * cell)56 void Letter::setCell(Cell* cell) {
57 	m_cell = cell;
58 	QGraphicsItem* item = m_shadow ? m_shadow : this;
59 	item->setPos(m_cell->position().x() * 34 + 2, m_cell->position().y() * 34 + 34);
60 }
61 
62 //-----------------------------------------------------------------------------
63 
setCorrect()64 void Letter::setCorrect() {
65 	setFlag(QGraphicsItem::ItemIsMovable, false);
66 	setBrush(QColor("#008c00"));
67 	setCursor(Qt::PointingHandCursor);
68 	m_correct = true;
69 	m_movable = false;
70 }
71 
72 //-----------------------------------------------------------------------------
73 
setHighlight(bool highlight)74 void Letter::setHighlight(bool highlight) {
75 	if (m_movable) {
76 		setBrush(highlight ? QColor("#0057ae") : QColor("#bbbbbb"));
77 	}
78 }
79 
80 //-----------------------------------------------------------------------------
81 
setJoin()82 void Letter::setJoin() {
83 	setFlag(QGraphicsItem::ItemIsMovable, false);
84 	setBrush(QColor("#555555"));
85 	setCursor(Qt::ArrowCursor);
86 	m_movable = false;
87 }
88 
89 //-----------------------------------------------------------------------------
90 
setPaused(bool paused)91 void Letter::setPaused(bool paused) {
92 	if (m_movable) {
93 		setText(!paused ? m_character : '?');
94 	}
95 }
96 
97 //-----------------------------------------------------------------------------
98 
mouseMoveEvent(QGraphicsSceneMouseEvent * event)99 void Letter::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
100 	if (m_dragged == false) {
101 		event->accept();
102 		return;
103 	}
104 	QGraphicsPathItem::mouseMoveEvent(event);
105 
106 	if (m_board->isPaused()) {
107 		m_board->setPaused(false);
108 		m_board->setCurrentWord(m_cell->word());
109 	}
110 
111 	QPoint pos = (((mapToScene(boundingRect().center()) - QPoint(2.f, 34.f)) / 34.f) - QPointF(0.5f, 0.5f)).toPoint();
112 	Cell* cell = 0;
113 	if (m_cell->word()->orientation() == Qt::Horizontal) {
114 		cell = m_board->cell(pos.x(), m_cell->position().y());
115 	} else {
116 		cell = m_board->cell(m_cell->position().x(), pos.y());
117 	}
118 	if (cell == 0 || cell == m_cell || cell->word() != m_cell->word()) {
119 		return;
120 	}
121 
122 	Letter* letter = cell->letter();
123 	if (letter == 0 || letter->m_movable == false) {
124 		return;
125 	}
126 	m_cell->setLetter(letter);
127 	cell->setLetter(this);
128 }
129 
130 //-----------------------------------------------------------------------------
131 
mousePressEvent(QGraphicsSceneMouseEvent * event)132 void Letter::mousePressEvent(QGraphicsSceneMouseEvent* event) {
133 	if (event->button() != Qt::LeftButton) {
134 		event->ignore();
135 		return;
136 	}
137 	m_dragged = true;
138 
139 	if (!m_movable) {
140 		if (m_correct) {
141 			Word* word = m_cell->word();
142 			if (word) {
143 				word->click();
144 			} else {
145 				m_board->click("");
146 			}
147 		}
148 		m_dragged = false;
149 		return;
150 	}
151 	setCursor(Qt::ClosedHandCursor);
152 	setZValue(10);
153 	m_board->setPaused(false);
154 	m_board->setCurrentWord(m_cell->word());
155 
156 	m_shadow = scene()->addPath(path(), Qt::NoPen, QColor("#a5c1e4"));
157 	m_shadow->setPos(pos());
158 
159 	QGraphicsPathItem::mousePressEvent(event);
160 }
161 
162 //-----------------------------------------------------------------------------
163 
mouseReleaseEvent(QGraphicsSceneMouseEvent * event)164 void Letter::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) {
165 	if (event->button() != Qt::LeftButton) {
166 		event->ignore();
167 		return;
168 	}
169 
170 	if (m_dragged == false) {
171 		event->accept();
172 		return;
173 	}
174 
175 	m_dragged = false;
176 
177 	setCursor(Qt::OpenHandCursor);
178 	setZValue(1);
179 
180 	setPos(m_shadow->pos());
181 	delete m_shadow;
182 	m_shadow = 0;
183 
184 	m_cell->word()->check();
185 
186 	QGraphicsPathItem::mouseReleaseEvent(event);
187 }
188 
189 //-----------------------------------------------------------------------------
190 
setText(const QChar & character)191 void Letter::setText(const QChar& character) {
192 	m_text->setText(character);
193 	m_text->setPos(boundingRect().center() - m_text->boundingRect().center());
194 }
195