Crossfire Server, Trunk
CRESmoothFaceMaker.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2022 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include "CRESmoothFaceMaker.h"
14 #include "CREPixmap.h"
15 #include <QtWidgets>
16 #include "FaceComboBox.h"
17 
18 #include "global.h"
19 #include "image.h"
20 
21 #include "assets.h"
22 #include "AssetsManager.h"
23 
25 {
26  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
27 
28  myAutoClose = false;
29  myOverwrite = false;
30 
31  QGridLayout* layout = new QGridLayout(this);
32  int line = 0;
33 
34  layout->addWidget(new QLabel(tr("Face to use:"), this), line, 0);
35  myFace = new FaceComboBox(this, false);
36  layout->addWidget(myFace, line++, 1, 1, 2);
37 
38  layout->addWidget(new QLabel(tr("Path of the picture to create:"), this), line, 0);
39  myDestination = new QLineEdit();
40  layout->addWidget(myDestination, line, 1);
41  connect(myDestination, SIGNAL(textEdited(const QString &)), this, SLOT(destinationEdited(const QString&)));
42 
43  QPushButton* browse = new QPushButton(tr("Browse"), this);
44  layout->addWidget(browse, line++, 2);
45  connect(browse, SIGNAL(clicked(bool)), this, SLOT(browse(bool)));
46 
47  QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close, Qt::Horizontal, this);
48  layout->addWidget(box, line++, 1, 1, 3);
49  connect(box, SIGNAL(rejected()), this, SLOT(reject()));
50  connect(box, SIGNAL(accepted()), this, SLOT(makeSmooth()));
51 
52  setWindowTitle(tr("Smooth face base generator"));
53 
54  QApplication::restoreOverrideCursor();
55 }
56 
58 {
59 }
60 
62 {
63  myFace->setFace(face);
64 }
65 
67 {
68  return myDestination->text();
69 }
70 
72 {
73  myAutoClose = autoClose;
74 }
75 
77 {
78  if (destination().isEmpty())
79  {
80  QMessageBox::warning(this, tr("Oops"), tr("You must select a destination!"));
81  return;
82  }
83 
84  if (!myOverwrite && QFile::exists(destination()))
85  {
86  if (QMessageBox::question(this, tr("Confirm file overwrite"), tr("File %1 already exists. Overwrite it?").arg(destination()), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
87  return;
88  }
89 
90  QPixmap pic(32 * 16, 32 * 2);
91  pic.fill(QColor(0, 0, 0, 0));
92  QImage icon = CREPixmap::getIcon(myFace->face()->number).pixmap(32, 32).toImage();
93  QPainter device(&pic);
94  device.setBackground(QColor(0, 0, 0, 0));
95 
96  long spots[] = {
97  0x0, /* 0b000000000 */
98  0x49, /* 0b001001001 */
99  0x7, /* 0b000000111 */
100  0x4f, /* 0b001001111 */
101  0x124, /* 0b100100100 */
102  0x16d, /* 0b101101101 */
103  0x127, /* 0b100100111 */
104  0x16f, /* 0b101101111 */
105  0x1c0, /* 0b111000000 */
106  0x1c9, /* 0b111001001 */
107  0x1c7, /* 0b111000111 */
108  0x1cf, /* 0b111001111 */
109  0x1e4, /* 0b111100100 */
110  0x1ed, /* 0b111101101 */
111  0x1e7, /* 0b111100111 */
112  0x1ef, /* 0b111101111 */
113  0x0, /* 0b000000000 */
114  0x1, /* 0b000000001 */
115  0x4, /* 0b000000100 */
116  0x5, /* 0b000000101 */
117  0x100, /* 0b100000000 */
118  0x101, /* 0b100000001 */
119  0x104, /* 0b100000100 */
120  0x105, /* 0b100000101 */
121  0x40, /* 0b001000000 */
122  0x41, /* 0b001000001 */
123  0x44, /* 0b001000100 */
124  0x45, /* 0b001000101 */
125  0x140, /* 0b101000000 */
126  0x141, /* 0b101000001 */
127  0x144, /* 0b101000100 */
128  0x145, /* 0b101000101 */
129  };
130 
131 
132  int sx, sy, sw, sh, dx, dy, spot;
133  for (int x = 0; x < 16; x++) {
134  for (int y = 0; y < 2; y++) {
135  spot = y * 16 + x;
136 
137  for (int bit = 0; bit < 9; bit++) {
138  if ((spots[spot] & (1 << bit)) == 0)
139  continue;
140 
141  dx = x * 32;
142  dy = y * 32;
143  sw = 8;
144  sh = 8;
145 
146  switch (bit / 3)
147  {
148  case 0:
149  sy = 0;
150  break;
151  case 1:
152  sy = 8;
153  dy += 8;
154  sh = 16;
155  break;
156  case 2:
157  sy = 24;
158  dy += 24;
159  break;
160  default:
161  Q_ASSERT(false);
162  }
163 
164  switch (bit % 3)
165  {
166  case 0:
167  sx = 0;
168  break;
169  case 1:
170  sx = 8;
171  dx += 8;
172  sw = 16;
173  break;
174  case 2:
175  sx = 24;
176  dx += 24;
177  break;
178  default:
179  Q_ASSERT(false);
180  }
181 
182  device.drawImage(dx, dy, icon, sx, sy, sw, sh);
183  }
184 
185  }
186  }
187 
188  if (!pic.save(destination(), "PNG"))
189  {
190  QMessageBox::critical(this, tr("Error"), tr("Error while saving the picture as %1!").arg(destination()));
191  return;
192  }
193 
194  QMessageBox::information(this, tr("Smooth base saved"), tr("The smooth base was correctly saved as %1").arg(destination()));
195 
196  if (myAutoClose)
197  accept();
198 
199  myOverwrite = false;
200 }
201 
203 {
204  QString dest = QFileDialog::getSaveFileName(this, tr("Select destination file"), "", tr("PNG file (*.png);;All files (*.*)"));
205  if (dest.isEmpty())
206  return;
207 
208  myDestination->setText(dest);
209  myOverwrite = true;
210 }
211 
213 {
214  myOverwrite = false;
215 }
Face
Definition: face.h:14
global.h
layout
Definition: main.cpp:84
FaceComboBox
Definition: FaceComboBox.h:23
diamondslots.x
x
Definition: diamondslots.py:15
AssetsManager.h
CREPixmap::getIcon
static QIcon getIcon(uint16_t faceNumber)
Definition: CREPixmap.cpp:65
CRESmoothFaceMaker::myFace
FaceComboBox * myFace
Definition: CRESmoothFaceMaker.h:45
CRESmoothFaceMaker::destinationEdited
void destinationEdited(const QString &)
Definition: CRESmoothFaceMaker.cpp:212
CRESmoothFaceMaker::CRESmoothFaceMaker
CRESmoothFaceMaker()
Definition: CRESmoothFaceMaker.cpp:24
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
Face::number
uint16_t number
Definition: face.h:15
FaceComboBox::setFace
void setFace(const Face *face)
Definition: FaceComboBox.cpp:45
CRESmoothFaceMaker::myDestination
QLineEdit * myDestination
Definition: CRESmoothFaceMaker.h:44
say.box
box
Definition: say.py:152
image.h
CRESmoothFaceMaker::myAutoClose
bool myAutoClose
Definition: CRESmoothFaceMaker.h:42
CRESmoothFaceMaker::destination
QString destination() const
Definition: CRESmoothFaceMaker.cpp:66
CRESmoothFaceMaker::browse
void browse(bool)
Definition: CRESmoothFaceMaker.cpp:202
CRESmoothFaceMaker::makeSmooth
void makeSmooth()
Definition: CRESmoothFaceMaker.cpp:76
convert.dest
dest
Definition: convert.py:25
diamondslots.y
y
Definition: diamondslots.py:16
assets.h
CRESmoothFaceMaker::setAutoClose
void setAutoClose(bool autoClose=true)
Definition: CRESmoothFaceMaker.cpp:71
FaceComboBox::face
const Face face
Definition: FaceComboBox.h:27
FaceComboBox.h
connect
Definition: connect.py:1
CRESmoothFaceMaker.h
altar_valkyrie.accept
def accept(description)
Definition: altar_valkyrie.py:22
CRESmoothFaceMaker::myOverwrite
bool myOverwrite
Definition: CRESmoothFaceMaker.h:43
CREPixmap.h
CRESmoothFaceMaker::setSelectedFace
void setSelectedFace(const Face *face)
Definition: CRESmoothFaceMaker.cpp:61
CRESmoothFaceMaker::~CRESmoothFaceMaker
virtual ~CRESmoothFaceMaker()
Definition: CRESmoothFaceMaker.cpp:57