Freeciv-3.3
Loading...
Searching...
No Matches
hudwidget.cpp
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18// Qt
19#include <QAction>
20#include <QApplication>
21#include <QComboBox>
22#include <QDialogButtonBox>
23#include <QGridLayout>
24#include <QGroupBox>
25#include <QHBoxLayout>
26#include <QHeaderView>
27#include <QLineEdit>
28#include <QPainter>
29#include <QPaintEvent>
30#include <QRadioButton>
31#include <QSpacerItem>
32#include <QVBoxLayout>
33
34// common
35#include "movement.h"
36#include "research.h"
37#include "tile.h"
38#include "unit.h"
39#include "unitlist.h"
40
41// client
42#include "client_main.h"
43#include "text.h"
44
45// gui-qt
46#include "fc_client.h"
47#include "fonts.h"
48#include "hudwidget.h"
49#include "sprite.h"
50
51extern "C" {
52 const char *calendar_text(void);
53 bool goto_is_active(void);
54}
55static QString popup_terrain_info(struct tile *ptile);
56
57/************************************************************************/
61{
63 if (utype_number(punit->utype) == utype) {
64 return true;
65 }
67
68 return false;
69}
70
71/************************************************************************/
75{
76 int size;
77 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
78 | Qt::FramelessWindowHint);
81
82 size = f_text.pointSize();
83 if (size > 0) {
84 f_text.setPointSize(size * 4 / 3);
85 f_title.setPointSize(size * 3 / 2);
86 } else {
87 size = f_text.pixelSize();
88 f_text.setPixelSize(size * 4 / 3);
89 f_title.setPointSize(size * 3 / 2);
90 }
91 f_title.setBold(true);
92 f_title.setCapitalization(QFont::SmallCaps);
95 top = 0;
97 hide();
98 mult = 1;
99}
100
101/************************************************************************/
105{
106 delete fm_text;
107 delete fm_title;
108}
109
110/************************************************************************/
114{
115 if (event->key() == Qt::Key_Escape) {
116 close();
117 destroy();
118 event->accept();
119 }
120 QWidget::keyPressEvent(event);
121}
122
123/************************************************************************/
127{
130 int w, w2, h;
131 QPoint p;
132
133 if (s1.contains('\n')) {
134 int i;
135
136 i = s1.indexOf('\n');
137 cs1 = s1.left(i);
138 cs2 = s1.right(s1.length() - i);
139 mult = 2;
140 w2 = qMax(fm_text->horizontalAdvance(cs1),
141 fm_text->horizontalAdvance(cs2));
142 w = qMax(w2, fm_title->horizontalAdvance(s2));
143 } else {
144 w = qMax(fm_text->horizontalAdvance(s1),
145 fm_title->horizontalAdvance(s2));
146 }
147 w = w + 20;
148 h = mult * (fm_text->height() * 3 / 2) + 2 * fm_title->height();
149 top = 2 * fm_title->height();
150 spacer = new QSpacerItem(w, 0, QSizePolicy::Minimum,
151 QSizePolicy::Expanding);
152 layout = (QGridLayout *)this->layout();
153 layout->addItem(spacer, layout->rowCount(), 0, 1, layout->columnCount());
154 spacer = new QSpacerItem(0, h, QSizePolicy::Expanding,
155 QSizePolicy::Minimum);
156 layout->addItem(spacer, 0, 0, 1, layout->columnCount());
157
158 text = s1;
159 title = s2;
160
161 p = QPoint((parentWidget()->width() - w) / 2,
162 (parentWidget()->height() - h) / 2);
163 p = parentWidget()->mapToGlobal(p);
164 move(p);
165 if (!return_exec) {
166 show ();
167 }
168 m_timer.start();
169 startTimer(45);
170 return (return_exec) ? exec () : 0;
171}
172
173/************************************************************************/
177{
178 m_animate_step = m_timer.elapsed() / 40;
179 update();
180}
181
182/************************************************************************/
186{
187 QPainter p;
188 QRect rx, ry, rfull;
190 QColor c1;
191 QColor c2;
192 int step;
193
194 step = m_animate_step % 300;
195 if (step > 150) {
196 step = step - 150;
197 step = 150 - step;
198 }
199 step = step + 30;
200
201 rfull = QRect(2 , 2, width() - 4 , height() - 4);
202 rx = QRect(2 , 2, width() - 4 , top);
203 ry = QRect(2 , top, width() - 4, height() - top - 4);
204
205 c1 = QColor(palette().color(QPalette::Highlight));
206 c2 = QColor(palette().color(QPalette::AlternateBase));
207 step = qMax(0, step);
208 step = qMin(255, step);
209 c1.setAlpha(step);
210 c2.setAlpha(step);
211
212 g = QLinearGradient(0 , 0, width(), height());
213 g.setColorAt(0, c1);
214 g.setColorAt(1, c2);
215
216 p.begin(this);
217 p.fillRect(rx, QColor(palette().color(QPalette::Highlight)));
218 p.fillRect(ry, QColor(palette().color(QPalette::AlternateBase)));
219 p.fillRect(rfull, g);
220 p.setFont(f_title);
221 p.drawText((width() - fm_title->horizontalAdvance(title)) / 2,
222 fm_title->height() * 4 / 3, title);
223 p.setFont(f_text);
224 if (mult == 1) {
225 p.drawText((width() - fm_text->horizontalAdvance(text)) / 2,
226 2 * fm_title->height() + fm_text->height() * 4 / 3, text);
227 } else {
228 p.drawText((width() - fm_text->horizontalAdvance(cs1)) / 2,
229 2 * fm_title->height() + fm_text->height() * 4 / 3, cs1);
230 p.drawText((width() - fm_text->horizontalAdvance(cs2)) / 2,
231 2 * fm_title->height() + fm_text->height() * 8 / 3, cs2);
232 }
233 p.end();
234 event->accept();
235}
236
237/************************************************************************/
241 QWidget *parent) : QWidget(parent)
242{
243 int size;
244
245 text = s;
247
248 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
250 f_text.setBold(true);
251 f_text.setCapitalization(QFont::SmallCaps);
252 size = f_text.pointSize();
253 if (size > 0) {
254 f_text.setPointSize(size * 2);
255 } else {
256 size = f_text.pixelSize();
257 f_text.setPixelSize(size * 2);
258 }
260 m_animate_step = 0;
261 m_timer.start();
262 startTimer(46);
263 setAttribute(Qt::WA_TranslucentBackground);
264 setAttribute(Qt::WA_ShowWithoutActivating);
265 setAttribute(Qt::WA_TransparentForMouseEvents);
266 setFocusPolicy(Qt::NoFocus);
267}
268
269/************************************************************************/
273{
274 show();
275 center_me();
276}
277
278/************************************************************************/
282{
283 int w;
284 QPoint p;
285
286 w = width();
287 if (!bound_rect.isEmpty()) {
288 setFixedSize(bound_rect.width(), bound_rect.height());
289 }
290 p = QPoint((parentWidget()->width() - w) / 2,
291 parentWidget()->height() / 20);
292 move(p);
293}
294
295/************************************************************************/
299{
300 delete fm_text;
301}
302
303/************************************************************************/
307{
308 m_animate_step = m_timer.elapsed() / 40;
309 if (m_timer.elapsed() > timeout * 1000) {
310 close();
311 deleteLater();
312 }
313 update();
314}
315
316/************************************************************************/
320{
321 QPainter p;
322 QRect rfull;
323 QColor c1;
324 QColor c2;
325 float opacity;
326
327 center_me();
328 if (m_timer.elapsed() < timeout * 500) {
329 opacity = static_cast<float>(m_timer.elapsed())/(timeout * 300);
330 } else {
331 opacity = static_cast<float>(5000 - m_timer.elapsed())/(timeout * 200);
332 }
333 opacity = qMin(1.0f, opacity);
334 opacity = qMax(0.0f, opacity);
335 rfull = QRect(0 , 0, width(), height());
336 c1 = QColor(Qt::white);
337 c2 = QColor(35, 35, 35, 175);
338 c1.setAlphaF(c1.alphaF() * opacity);
339 c2.setAlphaF(c2.alphaF() * opacity);
340 p.begin(this);
341 p.setBrush(c2);
342 p.setPen(QColor(0, 0, 0, 0));
343 p.drawRoundedRect(rfull, height() / 6 , height() / 6);
344 p.setFont(f_text);
345 p.setPen(c1);
346 p.drawText(rfull, Qt::AlignCenter, text, &bound_rect);
347
348 p.end();
349}
350
351/************************************************************************/
355{
356 int size;
357
358 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
359 | Qt::FramelessWindowHint);
360
363
364 size = f_text.pointSize();
365 if (size > 0) {
366 f_text.setPointSize(size * 4 / 3);
367 f_title.setPointSize(size * 3 / 2);
368 } else {
369 size = f_text.pixelSize();
370 f_text.setPixelSize(size * 4 / 3);
371 f_title.setPointSize(size * 3 / 2);
372 }
373 f_title.setBold(true);
374 f_title.setCapitalization(QFont::SmallCaps);
377 top = 0;
378 m_animate_step = 0;
379 hide();
380 mult = 1;
381}
382
383/************************************************************************/
387{
388 delete fm_text;
389 delete fm_title;
390}
391
392/************************************************************************/
397{
400 int w, w2, h;
401 QDialogButtonBox *button_box;
402 QPoint p;
403
404 button_box = new QDialogButtonBox(QDialogButtonBox::Ok
405 | QDialogButtonBox::Cancel,
406 Qt::Horizontal, this);
407 layout = new QVBoxLayout;
408 if (s1.contains('\n')) {
409 int i;
410
411 i = s1.indexOf('\n');
412 cs1 = s1.left(i);
413 cs2 = s1.right(s1.length() - i);
414 mult = 2;
415 w2 = qMax(fm_text->horizontalAdvance(cs1),
416 fm_text->horizontalAdvance(cs2));
417 w = qMax(w2, fm_title->horizontalAdvance(s2));
418 } else {
419 w = qMax(fm_text->horizontalAdvance(s1),
420 fm_title->horizontalAdvance(s2));
421 }
422 w = w + 20;
423 h = mult * (fm_text->height() * 3 / 2) + 2 * fm_title->height();
424 top = 2 * fm_title->height();
425
426 spacer = new QSpacerItem(w, h, QSizePolicy::Expanding,
427 QSizePolicy::Minimum);
428 layout->addItem(spacer);
429 layout->addWidget(&input_edit);
430 layout->addWidget(button_box);
431 input_edit.setFont(f_text);
432 input_edit.setText(def_input);
434 QObject::connect(button_box, &QDialogButtonBox::accepted, this, &QDialog::accept);
435 QObject::connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
436
437 text = s1;
438 title = s2;
439 p = QPoint((parentWidget()->width() - w) / 2,
440 (parentWidget()->height() - h) / 2);
441 p = parentWidget()->mapToGlobal(p);
442 move(p);
443 input_edit.activateWindow();
444 input_edit.setFocus();
445 m_timer.start();
446 startTimer(41);
447 show();
448 update();
449}
450
451/************************************************************************/
455{
456 m_animate_step = m_timer.elapsed() / 40;
457 update();
458}
459
460/************************************************************************/
464{
465 QPainter p;
466 QRect rx, ry;
468 QColor c1;
469 QColor c2;
470 QColor c3;
471 int step;
472 float fstep;
473
474
475 step = m_animate_step % 300;
476 if (step > 150) {
477 step = step - 150;
478 step = 150 - step;
479 }
480 step = step + 10;
481 rx = QRect(2 , 2, width() - 4 , top);
482 ry = QRect(2 , top, width() - 4, height() - top - 4);
483
484 c1 = QColor(palette().color(QPalette::Highlight));
485 c2 = QColor(Qt::transparent);
486 c3 = QColor(palette().color(QPalette::Highlight)).lighter(145);
487 step = qMax(0, step);
488 step = qMin(255, step);
489 c1.setAlpha(step);
490 c2.setAlpha(step);
491 c3.setAlpha(step);
492
493 fstep = static_cast<float>(step) / 400;
494 g = QLinearGradient(0 , 0, width(), height());
495 g.setColorAt(0, c2);
496 g.setColorAt(fstep, c3);
497 g.setColorAt(1, c2);
498
499 p.begin(this);
500 p.fillRect(rx, QColor(palette().color(QPalette::Highlight)));
501 p.fillRect(ry, QColor(palette().color(QPalette::AlternateBase)));
502 p.fillRect(rx, g);
503 p.setFont(f_title);
504 p.drawText((width() - fm_title->horizontalAdvance(title)) / 2,
505 fm_title->height() * 4 / 3, title);
506 p.setFont(f_text);
507 if (mult == 1) {
508 p.drawText((width() - fm_text->horizontalAdvance(text)) / 2,
509 2 * fm_title->height() + fm_text->height() * 4 / 3, text);
510 } else {
511 p.drawText((width() - fm_text->horizontalAdvance(cs1)) / 2,
512 2 * fm_title->height() + fm_text->height() * 4 / 3, cs1);
513 p.drawText((width() - fm_text->horizontalAdvance(cs2)) / 2,
514 2 * fm_title->height() + fm_text->height() * 8 / 3, cs2);
515 }
516 p.end();
517 event->accept();
518}
519
520/************************************************************************/
524{
525 QVBoxLayout *vbox;
529
531 sp = new QSpacerItem(50, 2);
532 vbox = new QVBoxLayout;
533 unit_lab = new QVBoxLayout;
534 unit_lab->setContentsMargins(6, 9, 0, 3);
535 vbox->setSpacing(0);
536 unit_lab->addWidget(&unit_label);
537 main_layout->addLayout(unit_lab);
538 main_layout->addWidget(&tile_label);
539 unit_icons = new unit_actions(this, nullptr);
540 vbox->addSpacerItem(sp);
541 vbox->addWidget(&text_label);
542 vbox->addWidget(unit_icons);
543 main_layout->addLayout(vbox);
544 main_layout->setSpacing(0);
545 main_layout->setSpacing(3);
546 main_layout->setContentsMargins(0, 0, 0, 0);
547 vbox->setSpacing(3);
548 vbox->setContentsMargins(0, 0, 0, 0);
550 mw = new move_widget(this);
551 setFocusPolicy(Qt::ClickFocus);
552
553}
554
555/************************************************************************/
561
562/************************************************************************/
566{
567 gui()->qt_settings.unit_info_pos_fx = static_cast<float>(event->pos().x())
568 / gui()->mapview_wdg->width();
569 gui()->qt_settings.unit_info_pos_fy = static_cast<float>(event->pos().y())
570 / gui()->mapview_wdg->height();
571}
572
573/************************************************************************/
577{
578 int num;
579 int wwidth;
580 int font_width;
585 QImage img;
586 QPainter p;
587 QPixmap pix, pix2;
589 QString mp;
593 struct canvas *tile_pixmap;
594 struct canvas *unit_pixmap;
595 struct city *pcity;
596 struct player *owner;
597 struct tileset *tmp;
598 struct unit *punit;
599 QPoint move_pnt(qRound(gui()->mapview_wdg->width()
600 * gui()->qt_settings.unit_info_pos_fx),
601 qRound((gui()->mapview_wdg->height()
602 * gui()->qt_settings.unit_info_pos_fy)));
603 QRect parent_frame = this->parentWidget()->geometry();
604
605 punit = head_of_units_in_focus();
606 if (punit == nullptr) {
607 hide();
608 return;
609 }
610
611 font.setCapitalization(QFont::AllUppercase);
612 font.setBold(true);
614 text_label.setFixedHeight((height() * 2) / 10);
615
616 move_pnt.rx() = qMax(0, qMin(move_pnt.x(),
617 parent_frame.width() - mw->frameRect().width()));
618 move_pnt.ry() = qMax(0, qMin(move_pnt.y(),
619 parent_frame.height() - mw->frameRect().height()));
620 move(move_pnt);
621 unit_icons->setFixedHeight((height() * 8) / 10);
622
623 setUpdatesEnabled(false);
624
625 tmp = nullptr;
626 if (unscaled_tileset) {
627 tmp = tileset;
629 }
631 owner = punit->owner;
633 if (pcity != nullptr) {
634 text_str = QString(("%1(%2)"))
636 }
637 text_str = text_str + " ";
641 unit_type_get(punit)->move_rate
642 * ((punit->fuel) - 1)
643 + punit->moves_left), false))
644 + QString(")");
645 }
646 // TRANS: MP = Movement points
647 mp = QString(_("MP: ")) + mp;
648 text_str = text_str + mp + " ";
649 text_str += QString(_("HP:%1/%2")).arg(
650 QString::number(punit->hp),
651 QString::number(unit_type_get(punit)->hp));
653 snum = QString::number(unit_list_size(punit->tile->units) - 1);
656
657 // TRANS: preserve leading space; always at least 2
658 text_str = text_str + QString(PL_(" (Selected %1 unit)",
659 " (Selected %1 units)", n))
660 .arg(n);
661 } else if (num > 1) {
663
664 ut_bytes = snum.toUtf8();
665 // TRANS: preserve leading space
666 text_str = text_str + QString(PL_(" +%1 unit",
667 " +%1 units", num-1))
668 .arg(ut_bytes.data());
669 }
670 text_label.setTextFormat(Qt::PlainText);
671 text_label.setText(text_str);
672 font.setPixelSize((text_label.height() * 9) / 10);
673 text_label.setFont(font);
674 fm = new QFontMetrics(font);
675 text_label.setFixedWidth(fm->horizontalAdvance(text_str) + 20);
676 delete fm;
677
680 unit_pixmap->map_pixmap.fill(Qt::transparent);
681 put_unit(punit, unit_pixmap, 1, 0, 0);
682 img = unit_pixmap->map_pixmap.toImage();
684 cropped_img = img.copy(crop);
685 img = cropped_img.scaledToHeight(height(), Qt::SmoothTransformation);
687 ((height() + 0.0) / tileset_unit_height(tileset));
688 pix = QPixmap::fromImage(img);
689 /* add transparent borders if image is too slim, accounting for the
690 * scaledToHeight() we've applied */
691 if (pix.width() < expanded_unit_width) {
692 pix2 = QPixmap(expanded_unit_width, pix.height());
693 pix2.fill(Qt::transparent);
694 p.begin(&pix2);
695 p.drawPixmap(expanded_unit_width / 2 - pix.width() / 2, 0, pix);
696 p.end();
697 pix = pix2;
698 }
699
700 // Draw movement points
702 if (move_pt_text.contains('/')) {
703 fraction2 = move_pt_text.right(1);
704 move_pt_text.remove(move_pt_text.length() - 2, 2);
705 fraction1 = move_pt_text.right(1);
706 move_pt_text.remove(move_pt_text.length() - 1, 1);
707 }
708 crop = QRect(5, 5, pix.width() - 5, pix.height() - 5);
709 font.setCapitalization(QFont::Capitalize);
710 font.setPointSize((pix.height() * 2) / 5);
711 p.begin(&pix);
712 p.setFont(font);
713 p.setPen(Qt::white);
714 p.drawText(crop, Qt::AlignLeft | Qt::AlignBottom, move_pt_text,
716
717 bounding_rect.adjust(bounding_rect.width(), 0 ,
718 bounding_rect.width() * 2, 0);
719 if (punit->fuel > 1) {
720 QString s;
721 int fuel;
722
723 font.setPointSize(pix.height() / 4);
724 p.setFont(font);
725 fuel = punit->fuel - 1;
726 fuel = fuel * punit->utype->move_rate / SINGLE_MOVE;
727 p.drawText(bounding_rect, Qt::AlignCenter,
728 QString("+") + QString::number(fuel));
729 }
730
731 if (move_pt_text.isEmpty()) {
732 move_pt_text = " ";
733 }
734 bounding_rect = p.boundingRect(crop, Qt::AlignLeft | Qt::AlignBottom,
736 font.setPointSize(pix.height() / 5);
737 fm = new QFontMetrics(font);
738 font_width = (fm->horizontalAdvance(move_pt_text) * 3) / 5;
739 delete fm;
740 p.setFont(font);
741 if (!fraction1.isNull()) {
742 int t = 2 * font.pointSize();
743
745 bounding_rect.top(), t, (t / 5) * 4);
746 p.drawText(crop, Qt::AlignLeft | Qt::AlignBottom, fraction1);
748 (bounding_rect.bottom() + bounding_rect.top()) / 2,
749 t, (t / 5) * 4);
750 p.drawText(crop, Qt::AlignLeft | Qt::AlignTop, fraction2);
752 (bounding_rect.bottom() + bounding_rect.top()) / 2 - t / 16,
753 (t * 2) / 5, t / 8);
754 p.fillRect(crop, Qt::white);
755 }
756 p.end();
757 wwidth = 2 * 3 + pix.width();
758 unit_label.setPixmap(pix);
762 } else {
765 }
766 tile_pixmap->map_pixmap.fill(QColor(0 , 0 , 0 , 0));
767 put_terrain(punit->tile, tile_pixmap, 1.0, 0, 0);
768 img = tile_pixmap->map_pixmap.toImage();
770 cropped_img = img.copy(crop);
771 img = cropped_img.scaledToHeight(height() - 5, Qt::SmoothTransformation);
772 pix = QPixmap::fromImage(img);
773 tile_label.setPixmap(pix);
774 unit_label.setToolTip(popup_info_text(punit->tile));
776 wwidth = wwidth + pix.width();
779
781 / 10, text_label.width()));
782 mw->put_to_corner();
783 if (tmp != nullptr) {
784 tileset = tmp;
785 }
786 setUpdatesEnabled(true);
788 update();
789
790 show();
791}
792
793/************************************************************************/
797{
799}
800
801/************************************************************************/
805{
806 if (e->button() == Qt::LeftButton) {
808 }
809}
810
811/************************************************************************/
815{
816 gui()->game_tab_widget->setCurrentIndex(0);
818}
819
820/************************************************************************/
824{
825 connect(this, &hud_action::left_clicked, this, &hud_action::on_clicked);
826 setFocusPolicy(Qt::StrongFocus);
827 setMouseTracking(true);
828 focus = false;
829 action_pixmap = nullptr;
830}
831
832/************************************************************************/
836{
837 action_pixmap = p;
838}
839
840/************************************************************************/
844{
845 QRect rx, ry, rz;
846 QPainter p;
847
848 rx = QRect(0, 0, width(), height());
849 ry = QRect(0, 0, action_pixmap->width(), action_pixmap->height());
850 rz = QRect(0, 0, width() - 1, height() - 3);
851 p.begin(this);
852 p.setCompositionMode(QPainter::CompositionMode_Source);
853 p.setRenderHint(QPainter::SmoothPixmapTransform);
854 p.drawPixmap(rx, *action_pixmap, ry);
855 p.setPen(QColor(palette().color(QPalette::Text)));
856 p.drawRect(rz);
857 if (focus) {
858 p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
859 p.fillRect(rx, QColor(palette().color(QPalette::Highlight)));
860 }
861 p.end();
862
863}
864
865/************************************************************************/
869{
870 if (action_pixmap) {
871 delete action_pixmap;
872 }
873}
874
875/************************************************************************/
879{
880 if (e->button() == Qt::RightButton) {
882 } else if (e->button() == Qt::LeftButton) {
884 }
885}
886
887/************************************************************************/
891{
892 focus = true;
893 update();
894}
895
896/************************************************************************/
900{
901 focus = false;
902 update();
903 QWidget::leaveEvent(event);
904}
905
906/************************************************************************/
909#ifndef FC_QT5_MODE
911#else // FC_QT5_MODE
912void hud_action::enterEvent(QEvent *event)
913#endif // FC_QT5_MODE
914{
915 focus = true;
916 update();
917 QWidget::enterEvent(event);
918}
919
920/************************************************************************/
926
927/************************************************************************/
931{
932 gui()->menu_bar->execute_shortcut(action_shortcut);
933}
934
935/************************************************************************/
939{
940 layout = new QHBoxLayout(this);
941 layout->setSpacing(3);
942 layout->setContentsMargins(0, 0, 0, 0);
944 init_layout();
945 setFocusPolicy(Qt::ClickFocus);
946}
947
948/************************************************************************/
956
957/************************************************************************/
961{
962 QSizePolicy size_fixed_policy(QSizePolicy::MinimumExpanding,
963 QSizePolicy::Fixed,
964 QSizePolicy::Frame);
966 layout->setSpacing(0);
968}
969
970/************************************************************************/
974{
975 hud_action *a;
976
978
979 if (current_unit == nullptr) {
980 clear_layout();
981 hide();
982 return 0;
983 }
984 /* HACK prevent crash with active goto when leaving widget,
985 * just skip update because with active goto actions shouldn't change */
986 if (goto_is_active() ) {
987 return actions.count();
988 }
989 hide();
990 clear_layout();
991 setUpdatesEnabled(false);
992
993
994 foreach (a, actions) {
995 delete a;
996 }
998 actions.clear();
999
1000 // Create possible actions
1001
1003 a = new hud_action(this);
1005 a->set_pixmap(fc_icons::instance()->get_pixmap("home"));
1006 actions.append(a);
1007 }
1008
1009
1011 a = new hud_action(this);
1013 a->set_pixmap(fc_icons::instance()->get_pixmap("mine"));
1014 actions.append(a);
1015 }
1016
1018 a = new hud_action(this);
1020 a->set_pixmap(fc_icons::instance()->get_pixmap("plantforest"));
1021 actions.append(a);
1022 }
1023
1025 a = new hud_action(this);
1027 a->set_pixmap(fc_icons::instance()->get_pixmap("irrigation"));
1028 actions.append(a);
1029 }
1030
1032 a = new hud_action(this);
1034 a->set_pixmap(fc_icons::instance()->get_pixmap("chopchop"));
1035 actions.append(a);
1036 }
1037
1039 a = new hud_action(this);
1041 a->set_pixmap(fc_icons::instance()->get_pixmap("transform"));
1042 actions.append(a);
1043 }
1044
1045 // Road
1046 {
1047 bool ok = false;
1048
1050 struct road_type *proad = extra_road_get(pextra);
1051
1053 ok = true;
1054 }
1056 if (ok) {
1057 a = new hud_action(this);
1059 a->set_pixmap(fc_icons::instance()->get_pixmap("buildroad"));
1060 actions.append(a);
1061 }
1062 }
1063 // Goto
1064 a = new hud_action(this);
1066 a->set_pixmap(fc_icons::instance()->get_pixmap("goto"));
1067 actions.append(a);
1068
1069
1071 a = new hud_action(this);
1073 a->set_pixmap(fc_icons::instance()->get_pixmap("fortify"));
1074 actions.append(a);
1075 }
1076
1077
1079 a = new hud_action(this);
1081 a->set_pixmap(fc_icons::instance()->get_pixmap("sentry"));
1082 actions.append(a);
1083 }
1084
1085 // Board
1087 a = new hud_action(this);
1089 a->set_pixmap(fc_icons::instance()->get_pixmap("load"));
1090 actions.append(a);
1091 }
1092
1093 // Set homecity
1097 a = new hud_action(this);
1099 a->set_pixmap(fc_icons::instance()->get_pixmap("set_homecity"));
1100 actions.append(a);
1101 }
1102 }
1103
1104 // Upgrade
1106 a = new hud_action(this);
1108 a->set_pixmap(fc_icons::instance()->get_pixmap("upgrade"));
1109 actions.append(a);
1110 }
1111
1112 // Automate
1114 a = new hud_action(this);
1116 a->set_pixmap(fc_icons::instance()->get_pixmap("automate"));
1117 actions.append(a);
1118 }
1119
1120 // Paradrop
1122 a = new hud_action(this);
1124 a->set_pixmap(fc_icons::instance()->get_pixmap("paradrop"));
1125 actions.append(a);
1126 }
1127
1128 // Clean
1130 a = new hud_action(this);
1132 a->set_pixmap(fc_icons::instance()->get_pixmap("clean"));
1133 actions.append(a);
1134 }
1135
1136 // Deboard
1141 a = new hud_action(this);
1143 a->set_pixmap(fc_icons::instance()->get_pixmap("unload"));
1144 actions.append(a);
1145 }
1146
1147 // Nuke
1149 a = new hud_action(this);
1151 a->set_pixmap(fc_icons::instance()->get_pixmap("nuke"));
1152 actions.append(a);
1153 }
1154
1155 // Wait
1156 a = new hud_action(this);
1158 a->set_pixmap(fc_icons::instance()->get_pixmap("wait"));
1159 actions.append(a);
1160
1161 // Done moving
1162 a = new hud_action(this);
1164 a->set_pixmap(fc_icons::instance()->get_pixmap("done"));
1165 actions.append(a);
1166
1167
1168 foreach (a, actions) {
1169 a->setToolTip(gui()->menu_bar->shortcut_2_menustring(a->action_shortcut));
1170 a->setFixedHeight(height());
1171 a->setFixedWidth(height());
1172 layout->addWidget(a);
1173 }
1174
1175 setFixedWidth(actions.count() * height());
1176 setUpdatesEnabled(true);
1177 show();
1178 layout->update();
1180 return actions.count();
1181}
1182
1183/************************************************************************/
1187{
1188 int i = actions.count();
1189 hud_action *ui;
1190 int j;
1191
1192 setUpdatesEnabled(false);
1193 for (j = 0; j < i; j++) {
1194 ui = actions[j];
1195 layout->removeWidget(ui);
1196 delete ui;
1197 }
1198 while (!actions.empty()) {
1199 actions.removeFirst();
1200 }
1201 setUpdatesEnabled(true);
1202}
1203
1204/************************************************************************/
1208{
1209 setProperty("showGrid", "false");
1210 setProperty("selectionBehavior", "SelectRows");
1211 setEditTriggers(QAbstractItemView::NoEditTriggers);
1212 setSelectionMode(QAbstractItemView::SingleSelection);
1213 verticalHeader()->setVisible(false);
1214 horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
1215 horizontalHeader()->setVisible(false);
1216 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1217 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1218 connect(selectionModel(),
1220 const QItemSelection &)), this,
1222 const QItemSelection &)));
1223 cargo = pcargo;
1224 qtile = ptile;
1225
1226}
1227
1228/************************************************************************/
1234
1235/************************************************************************/
1240{
1242 int max_size = 0;
1243 int i, j;
1244 int w,h;
1245 sprite *spite;
1246
1251 transports.append(ptransport);
1252 max_size = qMax(max_size, get_transporter_occupancy(ptransport));
1253 }
1255
1256 setRowCount(transports.count());
1257 setColumnCount(max_size + 1);
1258 for (i = 0 ; i < transports.count(); i++) {
1259 QString str;
1260 struct unit *tp = transports.at(i);
1261
1262 spite = get_unittype_sprite(tileset, tp->utype, tp->activity,
1264 str = utype_rule_name(transports.at(i)->utype);
1265 // TRANS: MP - just movement points
1266 str = str + " ("
1267 + QString(move_points_text(transports.at(i)->moves_left, false))
1268 + _("MP") + ")";
1269 new_item = new QTableWidgetItem(QIcon(*spite->pm), str);
1270 setItem(i, 0, new_item);
1271 j = 1;
1272 unit_list_iterate(transports.at(i)->transporting, tunit) {
1273 spite = get_unittype_sprite(tileset, tunit->utype, tunit->activity,
1275 new_item = new QTableWidgetItem(QIcon(*spite->pm), "");
1276 setItem(i, j, new_item);
1277 j++;
1279 }
1280
1281 w = verticalHeader()->width() + 4;
1282 for (i = 0; i < columnCount(); i++) {
1283 w += columnWidth(i);
1284 }
1285 h = horizontalHeader()->height() + 4;
1286 for (i = 0; i < rowCount(); i++) {
1287 h += rowHeight(i);
1288 }
1289
1290 resize(w, h);
1291 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
1292 | Qt::FramelessWindowHint);
1293 show();
1294}
1295
1296/************************************************************************/
1300 const QItemSelection& s2)
1301{
1302 int curr_row;
1303
1304 curr_row = s1.indexes().at(0).row();
1305 request_unit_load(cargo, transports.at(curr_row), qtile);
1306 close();
1307}
1308
1309/************************************************************************/
1313{
1318
1319 hide();
1320 struct unit *punit = head_of_units_in_focus();
1321
1322 setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog
1323 | Qt::FramelessWindowHint);
1324 main_layout = new QVBoxLayout(this);
1325
1326 unit_sel_type = new QComboBox();
1327
1328 unit_type_iterate(utype) {
1329 utype_id = utype_index(utype);
1332 }
1333 }
1335
1336 if (punit) {
1337 int i;
1339 unit_sel_type->setCurrentIndex(i);
1340 }
1341 no_name = new QGroupBox();
1342 no_name->setTitle(_("Unit type"));
1343 this_type = new QRadioButton(_("Selected type"), no_name);
1344 this_type->setChecked(true);
1345 any_type = new QRadioButton(_("All types"), no_name);
1346 connect(unit_sel_type, SIGNAL(currentIndexChanged(int)), this,
1347 SLOT(select_units(int)));
1348 connect(this_type, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1349 connect(any_type, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1351 groupbox_layout->addWidget(unit_sel_type);
1352 groupbox_layout->addWidget(this_type);
1353 groupbox_layout->addWidget(any_type);
1354 no_name->setLayout(groupbox_layout);
1355 hibox = new QHBoxLayout;
1356 hibox->addWidget(no_name);
1357
1358 no_name = new QGroupBox();
1359 no_name->setTitle(_("Unit activity"));
1360 any_activity = new QRadioButton(_("Any activity"), no_name);
1361 any_activity->setChecked(true);
1362 fortified = new QRadioButton(_("Fortified"), no_name);
1363 idle = new QRadioButton(_("Idle"), no_name);
1364 sentried = new QRadioButton(_("Sentried"), no_name);
1365 connect(any_activity, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1366 connect(idle, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1367 connect(fortified, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1368 connect(sentried, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1370 groupbox_layout->addWidget(any_activity);
1371 groupbox_layout->addWidget(idle);
1372 groupbox_layout->addWidget(fortified);
1373 groupbox_layout->addWidget(sentried);
1374 no_name->setLayout(groupbox_layout);
1375 hibox->addWidget(no_name);
1376 main_layout->addLayout(hibox);
1377
1378 no_name = new QGroupBox();
1379 no_name->setTitle(_("Unit HP and MP"));
1380 any = new QRadioButton(_("Any unit"), no_name);
1381 full_hp = new QRadioButton(_("Full HP"), no_name);
1382 full_mp = new QRadioButton(_("Full MP"), no_name);
1383 full_hp_mp = new QRadioButton(_("Full HP and MP"), no_name);
1384 full_hp_mp->setChecked(true);
1385 connect(any, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1386 connect(full_hp, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1387 connect(full_mp, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1388 connect(full_hp_mp, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1390 groupbox_layout->addWidget(any);
1391 groupbox_layout->addWidget(full_hp);
1392 groupbox_layout->addWidget(full_mp);
1393 groupbox_layout->addWidget(full_hp_mp);
1394 no_name->setLayout(groupbox_layout);
1395 hibox = new QHBoxLayout;
1396 hibox->addWidget(no_name);
1397
1398 no_name = new QGroupBox();
1399 no_name->setTitle(_("Location"));
1400 anywhere = new QRadioButton(_("Anywhere"), no_name);
1401 this_tile = new QRadioButton(_("Current tile"), no_name);
1402 this_continent = new QRadioButton(_("Current continent"), no_name);
1403 main_continent = new QRadioButton(_("Main continent"), no_name);
1405
1406 if (punit) {
1407 this_tile->setChecked(true);
1408 } else {
1409 this_tile->setDisabled(true);
1410 this_continent->setDisabled(true);
1411 main_continent->setChecked(true);
1412 }
1413
1414 groupbox_layout->addWidget(this_tile);
1415 groupbox_layout->addWidget(this_continent);
1416 groupbox_layout->addWidget(main_continent);
1417 groupbox_layout->addWidget(anywhere);
1418
1419 no_name->setLayout(groupbox_layout);
1420 hibox->addWidget(no_name);
1421 main_layout->addLayout(hibox);
1422
1423 select = new QPushButton(_("Select"));
1424 cancel = new QPushButton(_("Cancel"));
1425 connect(anywhere, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1426 connect(this_tile, SIGNAL(toggled(bool)), this, SLOT(select_units(bool)));
1427 connect(this_continent, SIGNAL(toggled(bool)), this,
1428 SLOT(select_units(bool)));
1429 connect(main_continent, SIGNAL(toggled(bool)), this,
1430 SLOT(select_units(bool)));
1431 connect(select, &QAbstractButton::clicked, this, &unit_hud_selector::uhs_select);
1432 connect(cancel, &QAbstractButton::clicked, this, &unit_hud_selector::uhs_cancel);
1433 hbox = new QHBoxLayout;
1434 hbox->addWidget(cancel);
1435 hbox->addWidget(select);
1436
1437 result_label.setAlignment(Qt::AlignCenter);
1438 main_layout->addWidget(&result_label, Qt::AlignHCenter);
1439 main_layout->addLayout(hbox);
1441
1442}
1443
1444/************************************************************************/
1448{
1449 QPoint p;
1450
1451 p = QPoint((parentWidget()->width() - sizeHint().width()) / 2,
1452 (parentWidget()->height() - sizeHint().height()) / 2);
1453 p = parentWidget()->mapToGlobal(p);
1454 move(p);
1455 setVisible(true);
1456 show();
1457 select_units();
1458}
1459
1460/************************************************************************/
1466
1467/************************************************************************/
1471{
1472 const struct player *pplayer;
1473
1474 pplayer = client_player();
1475
1476 unit_list_iterate(pplayer->units, punit) {
1480 }
1482 close();
1483}
1484
1485/************************************************************************/
1489{
1490 close();
1491}
1492
1493/************************************************************************/
1497{
1498 int num = 0;
1499 const struct player *pplayer;
1500
1501 pplayer = client_player();
1502
1503 unit_list_iterate(pplayer->units, punit) {
1506 num++;
1507 }
1509 result_label.setText(QString(PL_("%1 unit", "%1 units", num)).arg(num));
1510}
1511
1512/************************************************************************/
1516{
1517 select_units(0);
1518}
1519
1520/************************************************************************/
1524{
1525 if ((event->key() == Qt::Key_Return)
1526 || (event->key() == Qt::Key_Enter)) {
1527 uhs_select();
1528 }
1529 if (event->key() == Qt::Key_Escape) {
1530 close();
1531 event->accept();
1532 }
1533 QWidget::keyPressEvent(event);
1534}
1535
1536/************************************************************************/
1540{
1541 if ((punit->activity == ACTIVITY_FORTIFIED && fortified->isChecked())
1542 || (punit->activity == ACTIVITY_SENTRY && sentried->isChecked())
1543 || (punit->activity == ACTIVITY_IDLE && idle->isChecked())
1544 || any_activity->isChecked()) {
1545 return true;
1546 }
1547 return false;
1548}
1549
1550/************************************************************************/
1554{
1555 if ((any->isChecked()
1556 || (full_mp->isChecked()
1558 || (full_hp->isChecked() && punit->hp >= punit->utype->hp)
1559 || (full_hp_mp->isChecked() && punit->hp >= punit->utype->hp
1560 && punit->moves_left >= punit->utype->move_rate))) {
1561 return true;
1562 }
1563 return false;
1564}
1565
1566/************************************************************************/
1570{
1571 int island = -1;
1572 struct unit *cunit = head_of_units_in_focus();
1573
1574 if (this_tile->isChecked() && cunit) {
1575 if (punit->tile == cunit->tile) {
1576 return true;
1577 }
1578 }
1579
1580 if (main_continent->isChecked()
1583 } else if (this_continent->isChecked() && cunit) {
1584 island = cunit->tile->continent;
1585 }
1586
1587 if (island > -1) {
1588 if (punit->tile->continent == island) {
1589 return true;
1590 }
1591 }
1592
1593 if (anywhere->isChecked()) {
1594 return true;
1595 }
1596 return false;
1597}
1598
1599/************************************************************************/
1603{
1604 QVariant qvar;
1606
1607 if (this_type->isChecked()) {
1608 qvar = unit_sel_type->currentData();
1609 utype_id = qvar.toInt();
1610 if (utype_id == utype_index(punit->utype)) {
1611 return true;
1612 } else {
1613 return false;
1614 }
1615 }
1616 if (any_type->isChecked()) {
1617 return true;
1618 }
1619 return false;
1620}
1621
1622/************************************************************************/
1626{
1627 int movement_cost;
1628 struct terrain *terr;
1629 QString ret, t, move_text;
1630 bool has_road = false;
1631
1632 terr = ptile->terrain;
1633 ret = QString(_("Terrain: %1\n")).arg(tile_get_info_text(ptile, TRUE, 0));
1634 ret = ret + QString(_("Food/Prod/Trade: %1\n"))
1635 .arg(get_tile_output_text(ptile));
1636 t = get_infrastructure_text(ptile->extras);
1637 if (t != "") {
1638 ret = ret + QString(_("Infrastructure: %1\n")).arg(t);
1639 }
1640 ret = ret + QString(_("Defense bonus: %1%\n")).arg(terr->defense_bonus);
1641 movement_cost = terr->movement_cost;
1642
1644 struct road_type *proad = extra_road_get(pextra);
1645
1646 if (tile_has_road(ptile, proad)) {
1647 if (proad->move_cost <= movement_cost) {
1648 has_road = true;
1649 move_text = move_points_text(proad->move_cost, TRUE);
1650 movement_cost = proad->move_cost;
1651 }
1652 }
1654
1655 if (has_road) {
1656 ret = ret + QString(_("Movement cost: %1")).arg(move_text);
1657 } else {
1658 ret = ret + QString(_("Movement cost: %1")).arg(movement_cost);
1659 }
1660
1661 return ret;
1662}
1663
1664/************************************************************************/
1668{
1669 QString s;
1670 hud_text *ht;
1672 struct research *research;
1673 int i;
1674 char buf[25];
1675
1676 if (!client_has_player()
1677 || !gui()->qt_settings.show_new_turn_text) {
1678 return;
1679 }
1680 close_list = gui()->mapview_wdg->findChildren<hud_text *>();
1681 for (i = 0; i < close_list.size(); ++i) {
1682 close_list.at(i)->close();
1683 close_list.at(i)->deleteLater();
1684 }
1686 s = QString(_("Year: %1 (Turn: %2)"))
1687 .arg(calendar_text()).arg(game.info.turn) + "\n";
1689 if (client_is_observer()) {
1690 s += QString(_(" (observer)"));
1691 }
1692 s += " - " + QString(_("Population: %1"))
1696 && research->researching != A_NONE) {
1699 " (" + QString::number(research->bulbs_researched) + "/"
1700 + QString::number(research->client.researching_cost) + ")";
1701 }
1702 s = s + "\n" + science_dialog_text() + "\n";
1703
1704 // Can't use QString().sprintf() as msys libintl.h defines sprintf() as a macro
1706
1707 // TRANS: current gold, then loss/gain per turn
1708 s = s + QString(_("Gold: %1 (%2)"))
1710 .arg(buf);
1711 ht = new hud_text(s, 5, gui()->mapview_wdg);
1712 ht->show_me();
1713}
1714
1715/************************************************************************/
1718hud_unit_combat::hud_unit_combat(int attacker_unit_id, int defender_unit_id,
1719 int attacker_hp, int defender_hp,
1720 bool make_att_veteran, bool make_def_veteran,
1721 float scale, QWidget *parent) : QWidget(parent)
1722{
1723 hud_scale = scale;
1724 att_hp = attacker_hp;
1725 def_hp = defender_hp;
1726
1727 attacker = game_unit_by_number(attacker_unit_id);
1728 defender = game_unit_by_number(defender_unit_id);
1731 att_veteran = make_att_veteran;
1732 def_veteran = make_def_veteran;
1735 if (defender_hp <= 0) {
1737 } else {
1739 }
1740 init_images();
1741}
1742
1743/************************************************************************/
1747{
1749 QRect dr, ar;
1750 QPainter p;
1751 struct canvas *defender_pixmap;
1752 struct canvas *attacker_pixmap;
1753 int w;
1754
1755 focus = false;
1756 w = 3 * hud_scale * tileset_unit_height(tileset) / 2;
1757 setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
1758 setFixedSize(2 * w, w);
1761 defender_pixmap->map_pixmap.fill(Qt::transparent);
1762 if (defender != nullptr) {
1763 if (!redraw) {
1764 put_unit(defender, defender_pixmap, 1.0, 0, 0);
1765 } else {
1767 }
1768 dimg = defender_pixmap->map_pixmap.toImage();
1770 crdimg = dimg.copy(dr);
1771 dimg = crdimg.scaledToHeight(w, Qt::SmoothTransformation);
1772 }
1773 if (dimg.width() < w) {
1774 dt = QImage(w, dimg.height(), QImage::Format_ARGB32_Premultiplied);
1775 dt.fill(Qt::transparent);
1776 p.begin(&dt);
1777 p.drawImage(w / 2 - dimg.width() / 2, 0, dimg);
1778 p.end();
1779 dimg = dt;
1780 }
1781 dimg = dimg.scaled(w, w, Qt::IgnoreAspectRatio,
1782 Qt::SmoothTransformation);
1785 attacker_pixmap->map_pixmap.fill(Qt::transparent);
1786 if (attacker != nullptr) {
1787 if (!redraw) {
1789 } else {
1791 }
1792 aimg = attacker_pixmap->map_pixmap.toImage();
1794 acrimg = aimg.copy(ar);
1795 aimg = acrimg.scaledToHeight(w, Qt::SmoothTransformation);
1796 }
1797 if (aimg.width() < w) {
1798 at = QImage(w, dimg.height(), QImage::Format_ARGB32_Premultiplied);
1799 at.fill(Qt::transparent);
1800 p.begin(&at);
1801 p.drawImage(w / 2 - aimg.width() / 2, 0, aimg);
1802 p.end();
1803 aimg = at;
1804 }
1805 aimg = aimg.scaled(w, w, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1806 delete defender_pixmap;
1807 delete attacker_pixmap;
1808}
1809
1810/************************************************************************/
1814{
1815 hud_scale = scale;
1816 init_images(true);
1817}
1818
1819/************************************************************************/
1825
1826/************************************************************************/
1830{
1831 fading = fade;
1832 update();
1833}
1834
1835/************************************************************************/
1839{
1840 return focus;
1841}
1842
1843/************************************************************************/
1847{
1848 QPainter p;
1849 QRect left, right;
1850 QColor c1, c2;
1851 QPen pen;
1854
1855 if (att_hp_loss > 0) {
1856 ahploss = "-" + QString::number(att_hp_loss);
1857 } else {
1858 ahploss = "0";
1859 }
1860 if (def_hp_loss > 0) {
1861 dhploss = "-" + QString::number(def_hp_loss);
1862 } else {
1863 dhploss = "0";
1864 }
1865 f.setBold(true);
1866
1867 if (def_hp == 0) {
1868 c1 = QColor(25, 125, 25, 175);
1869 c2 = QColor(125, 25, 25, 175);
1870 } else {
1871 c1 = QColor(125, 25, 25, 175);
1872 c2 = QColor(25, 125, 25, 175);
1873 }
1874 int w = 3 * tileset_unit_height(tileset) / 2 * hud_scale;
1875
1876 left = QRect(0 , 0, w , w);
1877 right = QRect(w, 0, w , w);
1878 pen = QPen(QColor(palette().color(QPalette::AlternateBase)), 2.0);
1879 p.begin(this);
1880 if (fading < 1.0) {
1881 p.setOpacity(fading);
1882 }
1883 if (focus) {
1884 p.fillRect(left, QColor(palette().color(QPalette::Highlight)));
1885 p.fillRect(right, QColor(palette().color(QPalette::Highlight)));
1886 c1.setAlpha(110);
1887 c2.setAlpha(110);
1888 }
1889 p.fillRect(left, c1);
1890 p.fillRect(right, c2);
1891 p.setPen(pen);
1892 p.drawRect(1, 1, width() - 2 , height() - 2);
1893 p.drawImage(left, aimg);
1894 p.setFont(f);
1895 p.setPen(QColor(Qt::white));
1896 if (def_veteran) {
1897 p.drawText(right, Qt::AlignHCenter | Qt::AlignJustify
1898 | Qt::AlignAbsolute, "*");
1899 }
1900 if (att_veteran) {
1901 p.drawText(left, Qt::AlignHCenter | Qt::AlignJustify
1902 | Qt::AlignAbsolute, "*");
1903 }
1904 p.drawText(left, Qt::AlignHorizontal_Mask, ahploss);
1905 p.drawImage(right, dimg);
1906 p.drawText(right, Qt::AlignHorizontal_Mask, dhploss);
1907 p.end();
1908}
1909
1910/************************************************************************/
1917
1918/************************************************************************/
1922{
1923 focus = false;
1924 update();
1925}
1926
1927/************************************************************************/
1930#ifndef FC_QT5_MODE
1932#else // FC_QT5_MODE
1934#endif // FC_QT5_MODE
1935{
1936 focus = true;
1937 update();
1938}
1939
1940
1941/************************************************************************/
1944scale_widget::scale_widget(QRubberBand::Shape s,
1945 QWidget* p) : QRubberBand(s, p)
1946{
1947 QPixmap *pix;
1948
1949 size = 12;
1950 pix = fc_icons::instance()->get_pixmap("plus");
1951 plus = pix->scaledToWidth(size);
1952 delete pix;
1953 pix = fc_icons::instance()->get_pixmap("minus");
1954 minus = plus = pix->scaledToWidth(size);
1955 delete pix;
1956 setFixedSize(2 * size, size);
1957 scale = 1.0f;
1958 setAttribute(Qt::WA_TransparentForMouseEvents, false);
1959}
1960
1961/************************************************************************/
1965{
1966 QRubberBand::paintEvent(event);
1967 QPainter p;
1968
1969 p.begin(this);
1970 p.drawPixmap(0, 0, minus);
1971 p.drawPixmap(size, 0, plus);
1972 p.end();
1973}
1974
1975/************************************************************************/
1979{
1980 if (event->button() == Qt::LeftButton) {
1981#ifndef FC_QT5_MODE
1982 if (event->position().x() <= size) {
1983#else // FC_QT5_MODE
1984 if (event->localPos().x() <= size) {
1985#endif // FC_QT5_MODE
1986 scale = scale / 1.2;
1987 } else {
1988 scale = scale * 1.2;
1989 }
1990 parentWidget()->update();
1991 }
1992}
1993
1994/************************************************************************/
1998{
1999 setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
2000 main_layout = new QVBoxLayout(this);
2001 mw = new move_widget(this);
2002 setContentsMargins(0, 0, 0, 0);
2003 main_layout->setContentsMargins(0, 0, 0, 0);
2004 sw = new scale_widget(QRubberBand::Rectangle, this);
2005 sw->show();
2006}
2007
2008/************************************************************************/
2012{
2013 delete sw;
2014 delete mw;
2015}
2016
2017/************************************************************************/
2021{
2023 int w = 3 * tileset_unit_height(tileset) / 2 * scale;
2024
2025 gui()->qt_settings.battlelog_scale = scale;
2026 delete layout();
2028 foreach (hudc, lhuc) {
2029 hudc->set_scale(scale);
2030 main_layout->addWidget(hudc);
2031 hudc->set_fading(1.0);
2032 }
2033 setFixedSize(2 * w + 10, lhuc.count() * w + 10);
2035
2036 update();
2037 show();
2038 m_timer.restart();
2039 startTimer(50);
2040}
2041
2042/************************************************************************/
2046{
2047 scale = s;
2048 sw->scale = s;
2049}
2050
2051/************************************************************************/
2055{
2057 int w = 3 * tileset_unit_height(tileset) / 2 * scale;
2058
2059 delete layout();
2061 lhuc.prepend(huc);
2062 while (lhuc.count() > 5) {
2063 hudc = lhuc.takeLast();
2064 delete hudc;
2065 }
2066 foreach (hudc, lhuc) {
2067 main_layout->addWidget(hudc);
2068 hudc->set_fading(1.0);
2069 }
2070 setFixedSize(2 * w + 10, lhuc.count() * w + 10);
2072
2073 update();
2074 show();
2075 m_timer.restart();
2076 startTimer(50);
2077}
2078
2079/************************************************************************/
2083{
2084 if (scale != sw->scale) {
2085 scale = sw->scale;
2086 update_size();
2087 }
2088 mw->put_to_corner();
2089 sw->move(width() - sw->width(), 0);
2090}
2091
2092/************************************************************************/
2096{
2097 QPoint p;
2098
2099 p = pos();
2100 gui()->qt_settings.battlelog_x = static_cast<float>(p.x()) / mapview.width;
2101 gui()->qt_settings.battlelog_y = static_cast<float>(p.y())
2102 / mapview.height;
2103 m_timer.restart();
2104}
2105
2106/************************************************************************/
2112{
2114
2115 foreach (hupdate, lhuc) {
2116 hupdate->set_fading(1.0);
2117 }
2118}
2119
2120/************************************************************************/
2124{
2126
2127 if (m_timer.elapsed() > 4000 && m_timer.elapsed() < 5000) {
2128 foreach (hudc, lhuc) {
2129 if (hudc->get_focus()) {
2130 m_timer.restart();
2131 te_inner();
2132 return;
2133 }
2134 hudc->set_fading((5000.0 - m_timer.elapsed()) / 1000);
2135 }
2136 }
2137 if (m_timer.elapsed() >= 5000) {
2138 hide();
2139 }
2140}
2141
2142/************************************************************************/
2146{
2148
2149 foreach (hupdate, lhuc) {
2150 hupdate->set_fading(1.0);
2151 }
2152 m_timer.restart();
2153 setVisible(true);
2154}
#define str
Definition astring.c:76
#define n
Definition astring.c:77
QRect zealous_crop_rect(QImage &p)
Definition canvas.cpp:419
void qtg_canvas_free(struct canvas *store)
Definition canvas.cpp:48
struct canvas * qtg_canvas_create(int width, int height)
Definition canvas.cpp:36
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
void left_clicked()
void mousePressEvent(QMouseEvent *e)
void on_clicked()
static fc_font * instance()
Definition fonts.cpp:41
QFont * get_font(QString name)
Definition fonts.cpp:63
QPixmap * get_pixmap(const QString &id)
static fc_icons * instance()
void paintEvent(QPaintEvent *event)
void leaveEvent(QEvent *event)
void mousePressEvent(QMouseEvent *e)
void on_clicked()
void mouseMoveEvent(QMouseEvent *event)
void right_clicked()
QPixmap * action_pixmap
Definition hudwidget.h:159
hud_action(QWidget *parent)
void on_right_clicked()
void enterEvent(QEnterEvent *event)
shortcut_id action_shortcut
Definition hudwidget.h:165
void left_clicked()
void set_pixmap(QPixmap *p)
move_widget * mw
Definition hudwidget.h:377
QList< hud_unit_combat * > lhuc
Definition hudwidget.h:360
QElapsedTimer m_timer
Definition hudwidget.h:378
void add_combat_info(hud_unit_combat *huc)
hud_battle_log(QWidget *parent)
QVBoxLayout * main_layout
Definition hudwidget.h:359
void moveEvent(QMoveEvent *event)
void timerEvent(QTimerEvent *event)
scale_widget * sw
Definition hudwidget.h:376
void paintEvent(QPaintEvent *event)
void set_scale(float s)
void showEvent(QShowEvent *event)
QString cs1
Definition hudwidget.h:131
void set_text_title_definput(QString s1, QString s2, QString def_input)
void paintEvent(QPaintEvent *event)
QElapsedTimer m_timer
Definition hudwidget.h:113
QString cs2
Definition hudwidget.h:131
void timerEvent(QTimerEvent *event)
QFontMetrics * fm_text
Definition hudwidget.h:128
hud_input_box(QWidget *parent)
QLineEdit input_edit
Definition hudwidget.h:119
QFontMetrics * fm_title
Definition hudwidget.h:129
QString text
Definition hudwidget.h:126
QString title
Definition hudwidget.h:127
QFontMetrics * fm_text
Definition hudwidget.h:73
QString title
Definition hudwidget.h:72
QElapsedTimer m_timer
Definition hudwidget.h:58
void timerEvent(QTimerEvent *event)
void paintEvent(QPaintEvent *event)
int set_text_title(QString s1, QString s2, bool return_exec=false)
hud_message_box(QWidget *parent)
Definition hudwidget.cpp:74
void keyPressEvent(QKeyEvent *event)
QFontMetrics * fm_title
Definition hudwidget.h:74
QElapsedTimer m_timer
Definition hudwidget.h:101
QString text
Definition hudwidget.h:100
void timerEvent(QTimerEvent *event)
QFont f_text
Definition hudwidget.h:103
int timeout
Definition hudwidget.h:98
void center_me()
hud_text(QString s, int time_secs, QWidget *parent)
QRect bound_rect
Definition hudwidget.h:97
void show_me()
void paintEvent(QPaintEvent *event)
QFontMetrics * fm_text
Definition hudwidget.h:102
int m_animate_step
Definition hudwidget.h:99
void set_fading(float fade)
hud_unit_combat(int attacker_unit_id, int defender_unit_id, int attacker_hp, int defender_hp, bool make_att_veteran, bool make_def_veteran, float scale, QWidget *parent)
struct unit * defender
Definition hudwidget.h:324
void leaveEvent(QEvent *event)
void mousePressEvent(QMouseEvent *e)
void paintEvent(QPaintEvent *event)
void init_images(bool redraw=false)
struct unit * attacker
Definition hudwidget.h:323
const struct unit_type * type_attacker
Definition hudwidget.h:325
void set_scale(float scale)
struct tile * center_tile
Definition hudwidget.h:327
const struct unit_type * type_defender
Definition hudwidget.h:326
void enterEvent(QEnterEvent *event)
hud_unit_loader(struct unit *pcargo, struct tile *ptile)
struct tile * qtile
Definition hudwidget.h:241
struct unit * cargo
Definition hudwidget.h:240
void selection_changed(const QItemSelection &, const QItemSelection &)
QList< unit * > transports
Definition hudwidget.h:231
QLabel text_label
Definition hudwidget.h:210
void update_actions(unit_list *punits)
hud_units(QWidget *parent)
void moveEvent(QMoveEvent *event)
click_label unit_label
Definition hudwidget.h:208
click_label tile_label
Definition hudwidget.h:209
move_widget * mw
Definition hudwidget.h:221
QHBoxLayout * main_layout
Definition hudwidget.h:212
unit_actions * unit_icons
Definition hudwidget.h:213
void put_to_corner()
Definition mapview.cpp:399
void paintEvent(QPaintEvent *event)
void mousePressEvent(QMouseEvent *event)
QPixmap minus
Definition hudwidget.h:349
QPixmap plus
Definition hudwidget.h:348
scale_widget(Shape s, QWidget *p=0)
unit_actions(QWidget *parent, unit *punit)
void clear_layout()
QList< hud_action * > actions
Definition hudwidget.h:197
void init_layout()
unit * current_unit
Definition hudwidget.h:199
int update_actions()
QHBoxLayout * layout
Definition hudwidget.h:196
QRadioButton * this_continent
Definition hudwidget.h:282
QComboBox * unit_sel_type
Definition hudwidget.h:251
QRadioButton * sentried
Definition hudwidget.h:274
void keyPressEvent(QKeyEvent *event)
QVBoxLayout * main_layout
Definition hudwidget.h:250
QRadioButton * anywhere
Definition hudwidget.h:284
QRadioButton * main_continent
Definition hudwidget.h:283
QRadioButton * full_hp_mp
Definition hudwidget.h:279
QPushButton * cancel
Definition hudwidget.h:253
bool island_filter(struct unit *punit)
bool type_filter(struct unit *punit)
unit_hud_selector(QWidget *parent)
QRadioButton * full_mp
Definition hudwidget.h:277
void select_units(int x=0)
QRadioButton * fortified
Definition hudwidget.h:272
QRadioButton * this_tile
Definition hudwidget.h:281
QRadioButton * any_type
Definition hudwidget.h:287
QRadioButton * any_activity
Definition hudwidget.h:271
QPushButton * select
Definition hudwidget.h:252
QRadioButton * any
Definition hudwidget.h:276
bool activity_filter(struct unit *punit)
bool hp_filter(struct unit *punit)
QRadioButton * full_hp
Definition hudwidget.h:278
QRadioButton * this_type
Definition hudwidget.h:286
QRadioButton * idle
Definition hudwidget.h:273
bool client_is_observer(void)
struct civclient client
bool client_has_player(void)
#define client_player()
char * incite_cost
Definition comments.c:76
void request_unit_load(struct unit *pcargo, struct unit *ptrans, struct tile *ptile)
Definition control.c:2168
void unit_focus_add(struct unit *punit)
Definition control.c:573
struct unit_list * get_units_in_focus(void)
Definition control.c:177
void request_center_focus_unit(void)
Definition control.c:2762
struct unit * head_of_units_in_focus(void)
Definition control.c:410
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
enum event_type event
Definition events.c:81
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
int Unit_type_id
Definition fc_types.h:242
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * population_to_text(int thousand_citizen)
Definition game.c:739
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
struct unit * game_unit_by_number(int id)
Definition game.c:115
int civ_population(const struct player *pplayer)
Definition game.c:73
bool goto_is_active(void)
Definition goto.c:1070
static PangoLayout * layout
Definition canvas.c:325
struct city * owner
Definition citydlg.c:226
static struct tile * pos
Definition finddlg.c:53
#define show(id)
Definition widget.h:235
#define hide(id)
Definition widget.h:238
static QString popup_terrain_info(struct tile *ptile)
const char * calendar_text(void)
Definition calendar.c:142
bool has_player_unit_type(Unit_type_id utype)
Definition hudwidget.cpp:60
bool goto_is_active(void)
Definition goto.c:1070
void show_new_turn_info()
bool has_player_unit_type(Unit_type_id utype)
Definition hudwidget.cpp:60
void put_terrain(struct tile *ptile, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
struct view mapview
void put_unit(const struct unit *punit, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
void put_unittype(const struct unit_type *putype, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
void center_tile_mapcanvas(const struct tile *ptile)
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1066
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
bool unit_can_load(const struct unit *punit)
Definition movement.c:934
bool can_unit_transport(const struct unit *transporter, const struct unit *transported)
Definition movement.c:906
#define SINGLE_MOVE
Definition movement.h:26
static mpgui * gui
Definition mpgui_qt.cpp:52
const char *const default_font
Definition fonts.h:27
const char *const notify_label
Definition fonts.h:28
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
const char * science_dialog_text(void)
Definition text.c:794
int player_get_expected_income(const struct player *pplayer)
Definition player.c:1286
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1337
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:273
struct research * research_get(const struct player *pplayer)
Definition research.c:128
bool can_build_road(const struct civ_map *nmap, struct road_type *proad, const struct unit *punit, const struct tile *ptile)
Definition road.c:301
@ SC_PARADROP
Definition shortcuts.h:95
@ SC_UPGRADE_UNIT
Definition shortcuts.h:63
@ SC_BUILDIRRIGATION
Definition shortcuts.h:67
@ SC_BUILDCITY
Definition shortcuts.h:70
@ SC_DONE_MOVING
Definition shortcuts.h:57
@ SC_BUILDROAD
Definition shortcuts.h:69
@ SC_CULTIVATE
Definition shortcuts.h:68
@ SC_SENTRY
Definition shortcuts.h:71
@ SC_NUKE
Definition shortcuts.h:76
@ SC_SETHOME
Definition shortcuts.h:64
@ SC_PLANT
Definition shortcuts.h:66
@ SC_BUILDMINE
Definition shortcuts.h:65
@ SC_TRANSFORM
Definition shortcuts.h:75
@ SC_FORTIFY
Definition shortcuts.h:72
@ SC_GOTO
Definition shortcuts.h:73
@ SC_WAIT
Definition shortcuts.h:74
@ SC_DEBOARD
Definition shortcuts.h:78
@ SC_AUTOMATE
Definition shortcuts.h:81
@ SC_BOARD
Definition shortcuts.h:77
@ SC_CLEAN
Definition shortcuts.h:82
int step
Definition specpq.h:92
size_t size
Definition specvec.h:72
struct sprite int int int int struct sprite int int float scale
Definition sprite_g.h:33
struct sprite int x
Definition sprite_g.h:31
Definition city.h:317
struct tile * tile
Definition city.h:319
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
Definition colors.h:21
struct player * playing
Definition connection.h:151
Definition mapimg.c:367
struct unit_list * units
Definition player.h:282
struct player_economic economic
Definition player.h:284
Tech_type_id researching
Definition research.h:52
struct research::@79::@81 client
int researching_cost
Definition research.h:96
int bulbs_researched
Definition research.h:53
int movement_cost
Definition terrain.h:92
Definition tile.h:50
bv_extras extras
Definition tile.h:55
struct unit_list * units
Definition tile.h:58
struct terrain * terrain
Definition tile.h:57
Continent_id continent
Definition tile.h:54
int move_rate
Definition unittype.h:522
Definition unit.h:140
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
int hp
Definition unit.h:153
int fuel
Definition unit.h:155
struct tile * tile
Definition unit.h:142
int homecity
Definition unit.h:148
const struct unit_type * utype
Definition unit.h:141
struct player * owner
Definition unit.h:145
int height
int width
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
#define A_UNKNOWN
Definition tech.h:49
const char * get_infrastructure_text(bv_extras extras)
Definition terrain.c:507
const char * popup_info_text(struct tile *ptile)
Definition text.c:147
const char * get_tile_output_text(const struct tile *ptile)
Definition text.c:63
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:844
const char * tile_get_info_text(const struct tile *ptile, bool include_nuisances, int linebreaks)
Definition tile.c:771
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
int tileset_unit_width(const struct tileset *t)
Definition tilespec.c:823
int tileset_unit_height(const struct tileset *t)
Definition tilespec.c:831
struct tileset * unscaled_tileset
Definition tilespec.c:592
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:738
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:791
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:802
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:7052
int get_transporter_occupancy(const struct unit *ptrans)
Definition unit.c:1846
bool can_unit_change_homecity_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pcity)
Definition unit.c:507
bool unit_can_add_or_build_city(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:490
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2544
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:401
bool can_unit_do_autoworker(const struct unit *punit)
Definition unit.c:648
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:315
bool can_unit_paradrop(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:864
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:2051
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2528
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:794
#define unit_tile(_pu)
Definition unit.h:407
@ UU_OK
Definition unit.h:62
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1573
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1582
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1564
#define utype_fuel(ptype)
Definition unittype.h:844
#define unit_type_iterate(_p)
Definition unittype.h:860
#define unit_type_iterate_end
Definition unittype.h:867