Fixed management of border letters in the board
[tagua/yd.git] / src / clock.cpp
blob49ed85f665c9b706355ecb608633072a78880c40
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
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 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "clock.h"
12 #include "constrainedtext.h"
13 #include <math.h>
14 #include <iostream>
16 Clock::Clock(int col, KGameCanvasAbstract* canvas)
17 : ClickableCanvas(canvas)
18 , m_color(col)
19 , m_running(false) {
20 m_background = new KGameCanvasPixmap(this);
21 m_caption = new ConstrainedText(this);
22 m_time_label = new ConstrainedText(this);
23 m_player_name = new ConstrainedText(this);
24 m_decs = new ConstrainedText(this);
26 m_background->show();
27 m_caption->show();
28 m_time_label->show();
29 m_player_name->show();
31 setTime(0);
32 setPlayer(Player());
33 m_caption->setText(col == 0 ? "White" : "Black");
34 connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
37 Clock::~Clock() {
38 delete m_background;
39 delete m_caption;
40 delete m_time_label;
41 delete m_player_name;
42 delete m_decs;
45 void Clock::start() {
46 m_running = true;
47 m_time.start();
48 m_timer.start(100);
51 void Clock::stop() {
52 if (m_running) m_total_time -= m_time.elapsed();
53 m_running = false;
54 m_timer.stop();
57 void Clock::activate(bool a) {
58 if(m_active == a)
59 return;
61 m_active = a;
62 m_background->setPixmap(m_active ? m_active_pixmap : m_inactive_pixmap);
64 m_time_label->setColor(m_active ? m_active_text : m_inactive_text);
65 m_player_name->setColor(m_active ? m_active_text : m_inactive_text);
66 m_caption->setColor(m_active ? m_active_text : m_inactive_text);
69 void Clock::tick() {
70 computeTime();
73 void Clock::computeTime() {
74 int time = m_total_time;
75 if (m_running) time -= m_time.elapsed();
77 bool positive;
78 int total_secs;
79 int decs = -1;
81 if (time > 0 && time < 10000) {
82 int total_decs = static_cast<int>(ceil(time / 100.0));
83 positive = total_decs >= 0;
84 if (!positive) total_decs = -total_decs;
85 decs = total_decs % 10;
86 total_secs = total_decs / 10;
88 else {
89 total_secs = static_cast<int>(ceil(time / 1000.0));
90 positive = total_secs >= 0;
91 if (!positive) total_secs = -total_secs;
95 int secs = total_secs % 60;
96 int mins = total_secs / 60;
97 QString timeText;
100 QString secText = QString::number(secs);
101 if (secText.length() < 2) secText = "0" + secText;
103 QString minText = QString::number(mins);
104 if (minText.length() < 2) minText = "0" + minText;
106 timeText = minText + ":" + secText;
107 if (!positive)
108 timeText = "-" + timeText;
110 #if 0
111 if (positive && decs != -1) {
112 int dec = static_cast<int>(ceil(time / 100.0)) % 10;
114 m_decs->moveTo(m_time_label->rect().bottomRight() + QPoint(2, 0));
115 m_decs->setText(":" + QString::number(dec));
116 m_decs->show();
118 else
119 m_decs->hide();
120 #endif
123 m_time_label->setText(timeText);
126 QString Clock::playerString(const Player& player) {
127 QString rating = player.rating != -1 ? QString(" (%1)").arg(player.rating) : QString();
128 return QString("%1").arg(player.name) + rating;
131 void Clock::setPlayer(const Player& player) {
132 m_player_name->setText(playerString(player));
135 void Clock::setTime(int t) {
136 m_total_time = t;
137 tick();
140 void Clock::onMousePress(const QPoint& /*pos*/, int /*button*/) {
143 void Clock::resize(int size) {
144 m_controls_loader.setSize(size);
146 m_height = (int)m_controls_loader.getValue<double>("clock_height");
148 m_active_pixmap = m_controls_loader.getValue<QPixmap>("clock_active_background");
149 m_inactive_pixmap = m_controls_loader.getValue<QPixmap>("clock_inactive_background");
151 m_active_text = m_controls_loader.getValue<QBrush>("clock_active_text").color();
152 m_inactive_text = m_controls_loader.getValue<QBrush>("clock_inactive_text").color();
154 m_background->setPixmap(m_active ? m_active_pixmap : m_inactive_pixmap);
155 m_background->moveTo(m_controls_loader.getValue<QPointF>("clock_background_offset").toPoint());
157 m_time_label->setConstrainRect(m_controls_loader.getValue<QRectF>("clock_time_rect").toRect());
158 m_time_label->setColor(m_active ? m_active_text : m_inactive_text);
160 m_player_name->setConstrainRect(m_controls_loader.getValue<QRectF>("clock_player_rect").toRect());
161 m_player_name->setColor(m_active ? m_active_text : m_inactive_text);
163 m_caption->setConstrainRect(m_controls_loader.getValue<QRectF>("clock_caption_rect").toRect());
164 m_caption->setColor(m_active ? m_active_text : m_inactive_text);
167 #if 1-1
168 #include <math.h>
169 #include <iostream>
170 #include <QResizeEvent>
171 #include "clock.h"
172 #include "global.h"
174 static void setFontSize(int max, int width, const QString& text, QFont& font) {
175 font.setPointSize(max);
176 return; // FIXME
177 while (max >= 8) {
178 QTime tm; tm.start();
179 QFontMetrics metrics(font);
180 int fw = metrics.boundingRect(text).width();
181 std::cout << "font metrics: " << tm.elapsed() << std::endl;
183 if (fw <= width) break;
184 max--;
185 font.setPointSize(max);
189 void Clock::Info::settingsChanged() {
192 void Clock::Info::setup(const Player& player, const QRect& rect, const QString& caption, KGameCanvasAbstract* canvas) {
193 putInCanvas(canvas);
195 m_player = player;
196 m_total_time = 0;
197 m_rect = rect;
199 Settings s_clock = settings.group("clock");
201 QColor framecol(0x60,0x60,0x90);
202 QColor backgroundColor;
203 (s_clock["background"] |= QColor(0xa0,0xf0,0xd0,200)) >> backgroundColor;
204 m_background = new KGameCanvasRectangle(backgroundColor, QSize(m_rect.size()), this);
205 m_frame[0] = new KGameCanvasRectangle(framecol, QSize(m_rect.width()-2,1), this);
206 m_frame[0]->moveTo(1,0);
207 m_frame[1] = new KGameCanvasRectangle(framecol, QSize(m_rect.width()-2,1), this);
208 m_frame[1]->moveTo(0,m_rect.height()-1);
209 m_frame[2] = new KGameCanvasRectangle(framecol, QSize(1,m_rect.height()), this);
210 m_frame[2]->moveTo(0,0);
211 m_frame[3] = new KGameCanvasRectangle(framecol, QSize(1,m_rect.height()), this);
212 m_frame[3]->moveTo(m_rect.width()-1,0);
214 int tempFontSize;
217 QFont captionFont("Bitstream Vera Sans");
218 (s_clock["captionFontSize"] |=
219 static_cast<int>(captionFont.pointSize() * 1.4)) >> tempFontSize;
220 captionFont.setPointSize(tempFontSize);
221 m_caption = new KGameCanvasText(caption, Qt::black, captionFont,
222 KGameCanvasText::HStart, KGameCanvasText::VTop, this);
223 m_caption->show();
227 QFont timeFont("Bitstream Vera Sans");
228 (s_clock["timeFontSize"] |= timeFont.pointSize() * 2) >> tempFontSize;
229 timeFont.setPointSize(tempFontSize);
230 timeFont.setWeight(QFont::Bold);
231 m_time_label = new KGameCanvasText("", Qt::black, timeFont,
232 KGameCanvasText::HStart, KGameCanvasText::VCenter, this);
233 m_time_label->show();
237 QFont decsFont("Bitstream Vera Sans");
238 (s_clock["decsFontSize"] |=
239 static_cast<int>(decsFont.pointSize() * 0.8)) >> tempFontSize;
240 decsFont.setPointSize(tempFontSize);
241 m_decs = new KGameCanvasText("", Qt::black, decsFont,
242 KGameCanvasText::HStart, KGameCanvasText::VBottom, this);
246 QFont playerFont("Bitstream Vera Sans");
247 (s_clock["playerFontSize"] |= playerFont.pointSize()) >> tempFontSize;
248 playerFont.setPointSize(tempFontSize);
249 m_player_name = new KGameCanvasText(playerString(player), Qt::black, playerFont,
250 KGameCanvasText::HStart, KGameCanvasText::VBottom, this);
251 m_player_name->show();
254 computeTime();
255 update();
256 show();
259 void Clock::Info::reload() {
260 Settings s_clock = settings.group("clock");
262 QFont tempFont;
263 QColor backgroundColor;
265 s_clock["background"] >> backgroundColor;
266 m_background->setColor(backgroundColor);
268 tempFont = m_caption->font();
269 tempFont.setPointSize(s_clock["captionFontSize"].value<int>());
270 m_caption->setFont(tempFont);
272 tempFont = m_time_label->font();
273 tempFont.setPointSize(s_clock["timeFontSize"].value<int>());
274 m_time_label->setFont(tempFont);
276 tempFont = m_decs->font();
277 tempFont.setPointSize(s_clock["decsFontSize"].value<int>());
278 m_decs->setFont(tempFont);
280 tempFont = m_player_name->font();
281 tempFont.setPointSize(s_clock["playerFontSize"].value<int>());
282 m_player_name->setFont(tempFont);
285 QString Clock::Info::playerString(const Player& player) const {
286 QString rating = player.rating != -1 ? QString(" (%1)").arg(player.rating) : "";
287 return QString("%1").arg(player.name) + rating;
290 void Clock::Info::setPlayer(const Player& player) {
291 m_player_name->setText(playerString(player));
294 void Clock::Info::setTime(int time) {
295 m_total_time = time;
296 tick();
299 void Clock::Info::resize(const QRect& rect) {
300 m_rect = rect;
301 update();
304 void Clock::Info::update() {
305 m_background->setSize(m_rect.size());
307 m_frame[0]->setSize(QSize(m_rect.width()-2,1));
308 m_frame[0]->moveTo(1,0);
309 m_frame[1]->setSize(QSize(m_rect.width()-2,1));
310 m_frame[1]->moveTo(1,m_rect.height()-1);
311 m_frame[2]->setSize(QSize(1,m_rect.height()));
312 m_frame[2]->moveTo(0,0);
313 m_frame[3]->setSize(QSize(1,m_rect.height()));
314 m_frame[3]->moveTo(m_rect.width()-1,0);
317 /*QFont font = m_caption->font();
318 setFontSize(20, m_rect.width() / 2, m_caption->text(), font);
319 m_caption->setFont(font);*/
320 m_caption->moveTo(QPoint(10, 10));
324 QPoint pos(
325 static_cast<int>(m_rect.width() * 0.5),
326 static_cast<int>(m_rect.height() * 0.5));
327 /*QFont font = m_time_label->font();
328 int width = m_rect.width() - pos.x();
329 setFontSize(22, width,
330 m_time_label->text(), font);
331 m_time_label->setFont(font);*/
332 m_time_label->moveTo(pos);
335 m_player_name->moveTo(QPoint(
336 static_cast<int>(m_rect.width() * 0.05),
337 static_cast<int>(m_rect.height() * 0.8)));
339 moveTo(m_rect.topLeft());
342 void Clock::Info::start() {
343 m_running = true;
344 m_time.start();
347 void Clock::Info::stop() {
348 if (m_running) m_total_time -= m_time.elapsed();
349 m_running = false;
352 void Clock::Info::computeTime() const {
353 int time = m_total_time;
354 if (m_running) time -= m_time.elapsed();
355 bool positive;
356 int total_secs;
357 int decs = -1;
359 if (time > 0 && time < 10000) {
360 int total_decs = static_cast<int>(ceil(time / 100.0));
361 positive = total_decs >= 0;
362 if (!positive) total_decs = -total_decs;
363 decs = total_decs % 10;
364 total_secs = total_decs / 10;
366 else {
367 total_secs = static_cast<int>(ceil(time / 1000.0));
368 positive = total_secs >= 0;
369 if (!positive) total_secs = -total_secs;
373 int secs = total_secs % 60;
374 int mins = total_secs / 60;
375 QString timeText;
378 QString secText = QString::number(secs);
379 if (secText.length() < 2) secText = "0" + secText;
381 QString minText = QString::number(mins);
382 if (minText.length() < 2) minText = "0" + minText;
384 timeText = minText + ":" + secText;
385 if (!positive)
386 timeText = "-" + timeText;
388 if (positive && decs != -1) {
389 int dec = static_cast<int>(ceil(time / 100.0)) % 10;
391 m_decs->moveTo(m_time_label->rect().bottomRight() + QPoint(2, 0));
392 m_decs->setText(":" + QString::number(dec));
393 m_decs->show();
395 else
396 m_decs->hide();
399 m_time_label->setText(timeText);
400 m_time_label->setColor(time <= 0 && m_running ? QColor(200,20,20) : Qt::black);
403 void Clock::Info::tick() {
404 computeTime();
407 void Clock::Info::activate(bool value) {
408 m_background->setVisible(value);
409 for(int i=0;i<4;i++)
410 m_frame[i]->setVisible(value);
412 QColor textcolor = value ? Qt::black : Qt::darkGray;
413 m_caption->setColor(textcolor);
414 m_time_label->setColor(textcolor);
415 m_decs->setColor(textcolor);
416 m_player_name->setColor(textcolor);
419 QRect Clock::Info::eventRect() const {
420 return m_background->rect().translated(pos());
424 Clock::Clock(KGameCanvasAbstract* parent)
425 : ClickableCanvas(parent)
426 , m_running(-1)
427 , m_active(-1) {
428 QTime startup_time; startup_time.start();
429 m_info[0].setup(Player(), QRect(0, 0, 0, 0), "White", this);
430 m_info[1].setup(Player(), QRect(0, 0, 0, 0), "Black", this);
431 connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
434 void Clock::settingsChanged() {
435 for(int i=0;i<2;i++)
436 m_info[i].settingsChanged();
439 void Clock::resize(QSize size) {
440 int baseWidth = (size.width() - 10) / 2;
441 m_info[0].resize(QRect(0, 0, baseWidth, 70));
442 m_info[1].resize(QRect(baseWidth + 10, 0, baseWidth, 70));
445 void Clock::reload() {
446 m_info[0].reload();
447 m_info[1].reload();
450 void Clock::setTime(int index, int value) {
451 Q_ASSERT(index == 0 || index == 1);
453 m_info[index].setTime(value);
456 void Clock::start(int index) {
457 Q_ASSERT(index == 0 || index == 1);
459 m_timer.start(10);
460 m_running = index;
461 m_info[index].start();
462 m_info[1 - index].stop();
465 void Clock::stop() {
466 m_info[0].stop();
467 m_info[1].stop();
468 m_timer.stop();
469 m_running = -1;
472 void Clock::activate(int index) {
473 m_active = index;
474 m_info[0].activate(index == 0);
475 m_info[1].activate(index == 1);
478 void Clock::tick() {
479 if (m_running != -1) {
480 Q_ASSERT(m_running == 0 || m_running == 1);
481 m_info[m_running].tick();
485 void Clock::setPlayers(const Player& white, const Player& black) {
486 m_info[0].setPlayer(white);
487 m_info[1].setPlayer(black);
490 void Clock::onMousePress(const QPoint& pos, int button) {
491 if (button == Qt::LeftButton) {
492 if (m_info[0].eventRect().contains(pos))
493 emit labelClicked(0);
494 else if (m_info[1].eventRect().contains(pos))
495 emit labelClicked(1);
499 #endif