GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/tabs/setup_colors.cpp Lines: 111 256 43.4 %
Date: 2021-03-17 Branches: 134 340 39.4 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  Douglas Boffey <[email protected]>
4
 *  Copyright (C) 2011-2019  The ManaPlus Developers
5
 *  Copyright (C) 2019-2021  Andrei Karas
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "gui/widgets/tabs/setup_colors.h"
24
25
#include "gui/gui.h"
26
#include "gui/userpalette.h"
27
28
#include "gui/fonts/font.h"
29
30
#include "gui/widgets/browserbox.h"
31
#include "gui/widgets/containerplacer.h"
32
#include "gui/widgets/createwidget.h"
33
#include "gui/widgets/label.h"
34
#include "gui/widgets/layouthelper.h"
35
#include "gui/widgets/listbox.h"
36
#include "gui/widgets/scrollarea.h"
37
#include "gui/widgets/slider.h"
38
#include "gui/widgets/textfield.h"
39
#include "gui/widgets/textpreview.h"
40
41
#include "utils/delete2.h"
42
#include "utils/gettext.h"
43
#include "utils/stringutils.h"
44
45
#include <cmath>
46
47
#include "debug.h"
48
49
const char *const Setup_Colors::rawmsg =
50
    // TRANSLATORS: color selection preview message
51
    N_("This is what the color looks like");
52
53
2
Setup_Colors::Setup_Colors(const Widget2 *const widget) :
54
    SetupTab(widget),
55
    SelectionListener(),
56


6
    mColorBox(CREATEWIDGETR(ListBox, this, userPalette, "")),
57
2
    mScroll(new ScrollArea(this, mColorBox,
58

4
        Opaque_true, "setup_colors_background.xml")),
59
    mPreview(new BrowserBox(this, Opaque_true,
60

2
        "browserbox.xml")),
61

4
    mTextPreview(new TextPreview(this, gettext(rawmsg))),
62
2
    mPreviewBox(new ScrollArea(this, mPreview, Opaque_true,
63

4
        "setup_colors_preview_background.xml")),
64
    mSelected(-1),
65
    // TRANSLATORS: colors tab. label.
66

4
    mGradTypeLabel(new Label(this, _("Type:"))),
67

2
    mGradTypeSlider(new Slider(this, 0.0, 3.0, 1.0)),
68

2
    mGradTypeText(new Label(this)),
69
    // TRANSLATORS: colors tab. label.
70

4
    mGradDelayLabel(new Label(this, _("Delay:"))),
71

2
    mGradDelaySlider(new Slider(this, 20.0, 100.0, 1.0)),
72
4
    mGradDelayText(new TextField(this, std::string(), LoseFocusOnTab_true,
73

4
        nullptr, std::string(), false)),
74
    // TRANSLATORS: colors tab. label.
75

4
    mRedLabel(new Label(this, _("Red:"))),
76

2
    mRedSlider(new Slider(this, 0.0, 255.0, 1.0)),
77
4
    mRedText(new TextField(this, std::string(), LoseFocusOnTab_true,
78

4
        nullptr, std::string(), false)),
79
    // TRANSLATORS: colors tab. label.
80

4
    mGreenLabel(new Label(this, _("Green:"))),
81

2
    mGreenSlider(new Slider(this, 0.0, 255.0, 1.0)),
82
4
    mGreenText(new TextField(this, std::string(), LoseFocusOnTab_true,
83

4
        nullptr, std::string(), false)),
84
    // TRANSLATORS: colors tab. label.
85

4
    mBlueLabel(new Label(this, _("Blue:"))),
86

2
    mBlueSlider(new Slider(this, 0.0, 255.0, 1.0)),
87
4
    mBlueText(new TextField(this, std::string(), LoseFocusOnTab_true,
88





106
        nullptr, std::string(), false))
89
{
90
    // TRANSLATORS: settings colors tab name
91
8
    setName(_("Colors"));
92
2
    mColorBox->addSelectionListener(this);
93
2
    mScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
94
4
    mPreview->setOpaque(Opaque_false);
95
96
    // don't do anything with links
97
2
    mPreview->setLinkHandler(nullptr);
98
99
2
    mPreviewBox->setHeight(20);
100
2
    mPreviewBox->setScrollPolicy(ScrollArea::SHOW_NEVER,
101
2
        ScrollArea::SHOW_NEVER);
102
103
2
    mGradTypeSlider->setWidth(180);
104
8
    mGradTypeSlider->setActionEventId("slider_grad");
105
2
    mGradTypeSlider->setValue(0);
106
2
    mGradTypeSlider->addActionListener(this);
107
4
    mGradTypeSlider->setEnabled(false);
108
109
    // TRANSLATORS: color type
110
6
    std::string longText = _("Static");
111
112
2
    const Font *const font = getFont();
113
    // TRANSLATORS: color type
114


8
    if (getFont()->getWidth(_("Pulse")) > font->getWidth(longText))
115
    {
116
        // TRANSLATORS: color type
117
        longText = _("Pulse");
118
    }
119
    // TRANSLATORS: color type
120


8
    if (getFont()->getWidth(_("Rainbow")) > font->getWidth(longText))
121
    {
122
        // TRANSLATORS: color type
123
2
        longText = _("Rainbow");
124
    }
125
    // TRANSLATORS: color type
126


8
    if (getFont()->getWidth(_("Spectrum")) > font->getWidth(longText))
127
    {
128
        // TRANSLATORS: color type
129
2
        longText = _("Spectrum");
130
    }
131
132
2
    mGradTypeText->setCaption(longText);
133
134
2
    mGradDelayText->setWidth(40);
135
4
    mGradDelayText->setRange(20, 100);
136
2
    mGradDelayText->setNumeric(true);
137
4
    mGradDelayText->setEnabled(false);
138
139
2
    mGradDelaySlider->setWidth(180);
140

2
    mGradDelaySlider->setValue(mGradDelayText->getValue());
141
8
    mGradDelaySlider->setActionEventId("slider_graddelay");
142
2
    mGradDelaySlider->addActionListener(this);
143
4
    mGradDelaySlider->setEnabled(false);
144
145
2
    mRedText->setWidth(40);
146
4
    mRedText->setRange(0, 255);
147
2
    mRedText->setNumeric(true);
148
4
    mRedText->setEnabled(false);
149
150
2
    mRedSlider->setWidth(180);
151

2
    mRedSlider->setValue(mRedText->getValue());
152
8
    mRedSlider->setActionEventId("slider_red");
153
2
    mRedSlider->addActionListener(this);
154
4
    mRedSlider->setEnabled(false);
155
156
2
    mGreenText->setWidth(40);
157
4
    mGreenText->setRange(0, 255);
158
2
    mGreenText->setNumeric(true);
159
4
    mGreenText->setEnabled(false);
160
161
2
    mGreenSlider->setWidth(180);
162

2
    mGreenSlider->setValue(mGreenText->getValue());
163
8
    mGreenSlider->setActionEventId("slider_green");
164
2
    mGreenSlider->addActionListener(this);
165
4
    mGreenSlider->setEnabled(false);
166
167
2
    mBlueText->setWidth(40);
168
4
    mBlueText->setRange(0, 255);
169
2
    mBlueText->setNumeric(true);
170
4
    mBlueText->setEnabled(false);
171
172
2
    mBlueSlider->setWidth(180);
173

2
    mBlueSlider->setValue(mBlueText->getValue());
174
8
    mBlueSlider->setActionEventId("slider_blue");
175
2
    mBlueSlider->addActionListener(this);
176
4
    mBlueSlider->setEnabled(false);
177
178
4
    setOpaque(Opaque_false);
179
180
    // Do the layout
181
4
    LayoutHelper h(this);
182
2
    ContainerPlacer place = h.getPlacer(0, 0);
183
184
4
    place(0, 0, mScroll, 6, 6).setPadding(2);
185
4
    place(0, 6, mPreviewBox, 6, 1).setPadding(2);
186
2
    place(0, 7, mGradTypeLabel, 3, 1);
187
2
    place(3, 7, mGradTypeSlider, 1, 1);
188
4
    place(4, 7, mGradTypeText, 2, 1).setPadding(1);
189
2
    place(0, 8, mRedLabel, 3, 1);
190
2
    place(3, 8, mRedSlider, 1, 1);
191
4
    place(5, 8, mRedText, 1, 1).setPadding(1);
192
2
    place(0, 9, mGreenLabel, 3, 1);
193
2
    place(3, 9, mGreenSlider, 1, 1);
194
4
    place(5, 9, mGreenText, 1, 1).setPadding(1);
195
2
    place(0, 10, mBlueLabel, 3, 1);
196
2
    place(3, 10, mBlueSlider, 1, 1);
197
4
    place(5, 10, mBlueText, 1, 1).setPadding(1);
198
2
    place(0, 11, mGradDelayLabel, 3, 1);
199
2
    place(3, 11, mGradDelaySlider, 1, 1);
200
4
    place(5, 11, mGradDelayText, 1, 1).setPadding(1);
201
202

8
    mGradTypeText->setCaption("");
203
204
2
    setDimension(Rect(0, 0, 365, 350));
205
2
}
206
207
8
Setup_Colors::~Setup_Colors()
208
{
209

2
    if ((mPreviewBox != nullptr) && mPreviewBox->getContent() == mPreview)
210
2
        delete2(mTextPreview)
211
    else
212
        delete2(mPreview)
213
4
}
214
215
void Setup_Colors::action(const ActionEvent &event)
216
{
217
    const std::string &eventId = event.getId();
218
    if (eventId == "slider_grad")
219
    {
220
        updateGradType();
221
        updateColor();
222
        return;
223
    }
224
225
    if (eventId == "slider_graddelay")
226
    {
227
        mGradDelayText->setText(toString(
228
            std::floor(mGradDelaySlider->getValue())));
229
        updateColor();
230
        return;
231
    }
232
    if (eventId == "slider_red")
233
    {
234
        mRedText->setText(toString(std::floor(mRedSlider->getValue())));
235
        updateColor();
236
        return;
237
    }
238
    if (eventId == "slider_green")
239
    {
240
        mGreenText->setText(toString(std::floor(mGreenSlider->getValue())));
241
        updateColor();
242
        return;
243
    }
244
    if (eventId == "slider_blue")
245
    {
246
        mBlueText->setText(toString(std::floor(mBlueSlider->getValue())));
247
        updateColor();
248
        return;
249
    }
250
}
251
252
void Setup_Colors::valueChanged(const SelectionEvent &event A_UNUSED)
253
{
254
    if (userPalette == nullptr)
255
        return;
256
257
    mSelected = mColorBox->getSelected();
258
    const UserColorIdT type = static_cast<UserColorIdT>(
259
        userPalette->getColorTypeAt(mSelected));
260
    const Color *col = &userPalette->getColor(type, 255U);
261
    const GradientTypeT grad = userPalette->getGradientType(type);
262
    const int delay = userPalette->getGradientDelay(type);
263
    const Visible showControls = fromBool(grad != GradientType::LABEL,
264
        Visible);
265
    mPreview->setVisible(showControls);
266
    mPreviewBox->setVisible(showControls);
267
    mTextPreview->setVisible(showControls);
268
    mGradTypeLabel->setVisible(showControls);
269
    mGradTypeSlider->setVisible(showControls);
270
    mGradTypeText->setVisible(showControls);
271
    mGradDelayLabel->setVisible(showControls);
272
    mGradDelaySlider->setVisible(showControls);
273
    mGradDelayText->setVisible(showControls);
274
    mRedLabel->setVisible(showControls);
275
    mRedSlider->setVisible(showControls);
276
    mRedText->setVisible(showControls);
277
    mGreenLabel->setVisible(showControls);
278
    mGreenSlider->setVisible(showControls);
279
    mGreenText->setVisible(showControls);
280
    mBlueLabel->setVisible(showControls);
281
    mBlueSlider->setVisible(showControls);
282
    mBlueText->setVisible(showControls);
283
284
    mPreview->clearRows();
285
    mPreviewBox->setContent(mTextPreview);
286
    mTextPreview->setFont(boldFont);
287
    mTextPreview->setTextColor(col);
288
    mTextPreview->setTextBGColor(nullptr);
289
    mTextPreview->setOpaque(Opaque_false);
290
    mTextPreview->setShadow(true);
291
    mTextPreview->setOutline(true);
292
    mTextPreview->useTextAlpha(false);
293
294
// probably need combite both switches and add all mssing color ids.
295
296
    PRAGMA45(GCC diagnostic push)
297
    PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
298
    switch (type)
299
    {
300
        case UserColorId::AIR_COLLISION_HIGHLIGHT:
301
        case UserColorId::WATER_COLLISION_HIGHLIGHT:
302
        case UserColorId::MONSTER_COLLISION_HIGHLIGHT:
303
        case UserColorId::GROUNDTOP_COLLISION_HIGHLIGHT:
304
        case UserColorId::COLLISION_HIGHLIGHT:
305
        case UserColorId::PORTAL_HIGHLIGHT:
306
        case UserColorId::HOME_PLACE:
307
        case UserColorId::ROAD_POINT:
308
        case UserColorId::NET:
309
            mTextPreview->setBGColor(col);
310
            mTextPreview->setOpaque(Opaque_true);
311
            mTextPreview->setOutline(false);
312
            mTextPreview->setShadow(false);
313
            break;
314
        case UserColorId::ATTACK_RANGE_BORDER:
315
        case UserColorId::HOME_PLACE_BORDER:
316
            if (gui != nullptr)
317
                mTextPreview->setFont(gui->getFont());
318
            mTextPreview->setTextColor(col);
319
            mTextPreview->setOutline(false);
320
            mTextPreview->setShadow(false);
321
            break;
322
        case UserColorId::PARTICLE:
323
        case UserColorId::EXP_INFO:
324
        case UserColorId::PICKUP_INFO:
325
        case UserColorId::HIT_PLAYER_MONSTER:
326
        case UserColorId::HIT_MONSTER_PLAYER:
327
        case UserColorId::HIT_CRITICAL:
328
        case UserColorId::MISS:
329
        case UserColorId::HIT_LOCAL_PLAYER_MONSTER:
330
        case UserColorId::HIT_LOCAL_PLAYER_CRITICAL:
331
        case UserColorId::HIT_LOCAL_PLAYER_MISS:
332
        case UserColorId::ATTACK_RANGE:
333
        case UserColorId::MONSTER_ATTACK_RANGE:
334
        case UserColorId::FLOOR_ITEM_TEXT:
335
        case UserColorId::SKILL_ATTACK_RANGE:
336
            mTextPreview->setShadow(false);
337
            break;
338
        default:
339
            break;
340
    }
341
342
    switch (type)
343
    {
344
        case UserColorId::PORTAL_HIGHLIGHT:
345
        case UserColorId::ATTACK_RANGE:
346
        case UserColorId::ATTACK_RANGE_BORDER:
347
        case UserColorId::MONSTER_ATTACK_RANGE:
348
        case UserColorId::SKILL_ATTACK_RANGE:
349
        case UserColorId::HOME_PLACE:
350
        case UserColorId::HOME_PLACE_BORDER:
351
        case UserColorId::AIR_COLLISION_HIGHLIGHT:
352
        case UserColorId::WATER_COLLISION_HIGHLIGHT:
353
        case UserColorId::MONSTER_COLLISION_HIGHLIGHT:
354
        case UserColorId::GROUNDTOP_COLLISION_HIGHLIGHT:
355
        case UserColorId::COLLISION_HIGHLIGHT:
356
        case UserColorId::WALKABLE_HIGHLIGHT:
357
        case UserColorId::ROAD_POINT:
358
        case UserColorId::MONSTER_HP:
359
        case UserColorId::MONSTER_HP2:
360
        case UserColorId::HOMUN_HP:
361
        case UserColorId::HOMUN_HP2:
362
        case UserColorId::MERC_HP:
363
        case UserColorId::MERC_HP2:
364
        case UserColorId::ELEMENTAL_HP:
365
        case UserColorId::ELEMENTAL_HP2:
366
        case UserColorId::PLAYER_HP:
367
        case UserColorId::PLAYER_HP2:
368
        case UserColorId::FLOOR_ITEM_TEXT:
369
        case UserColorId::NET:
370
            // TRANSLATORS: colors tab. label.
371
            mGradDelayLabel->setCaption(_("Alpha:"));
372
            mGradDelayText->setRange(0, 255);
373
            mGradDelaySlider->setScale(0, 255);
374
            break;
375
        default:
376
            // TRANSLATORS: colors tab. label.
377
            mGradDelayLabel->setCaption(_("Delay:"));
378
            mGradDelayText->setRange(20, 100);
379
            mGradDelaySlider->setScale(20, 100);
380
            break;
381
    }
382
    PRAGMA45(GCC diagnostic pop)
383
    if (grad != GradientType::STATIC && grad != GradientType::PULSE)
384
    { // If nonstatic color, don't display the current, but the committed
385
      // color at the sliders
386
        col = &userPalette->getCommittedColor(type);
387
    }
388
    else if (grad == GradientType::PULSE)
389
    {
390
        col = &userPalette->getTestColor(type);
391
    }
392
393
    setEntry(mGradDelaySlider, mGradDelayText, delay);
394
    setEntry(mRedSlider, mRedText, col->r);
395
    setEntry(mGreenSlider, mGreenText, col->g);
396
    setEntry(mBlueSlider, mBlueText, col->b);
397
398
    mGradTypeSlider->setValue(CAST_S32(grad));
399
    updateGradType();
400
    mGradTypeSlider->setEnabled(true);
401
}
402
403
void Setup_Colors::setEntry(Slider *const s, TextField *const t,
404
                            const int value)
405
{
406
    if (s != nullptr)
407
        s->setValue(value);
408
    if (t != nullptr)
409
        t->setText(toString(value));
410
}
411
412
void Setup_Colors::apply()
413
{
414
    if (userPalette != nullptr)
415
        userPalette->commit();
416
}
417
418
void Setup_Colors::cancel()
419
{
420
    if (userPalette == nullptr)
421
        return;
422
423
    userPalette->rollback();
424
    const UserColorIdT type = static_cast<UserColorIdT>(
425
        userPalette->getColorTypeAt(mSelected));
426
    const Color *const col = &userPalette->getColor(type, 255U);
427
    mGradTypeSlider->setValue(CAST_S32(
428
        userPalette->getGradientType(type)));
429
    const int delay = userPalette->getGradientDelay(type);
430
    setEntry(mGradDelaySlider, mGradDelayText, delay);
431
    setEntry(mRedSlider, mRedText, col->r);
432
    setEntry(mGreenSlider, mGreenText, col->g);
433
    setEntry(mBlueSlider, mBlueText, col->b);
434
}
435
436
void Setup_Colors::updateGradType()
437
{
438
    if (mSelected == -1 || (userPalette == nullptr))
439
        return;
440
441
    mSelected = mColorBox->getSelected();
442
    const UserColorIdT type = static_cast<UserColorIdT>(
443
        userPalette->getColorTypeAt(mSelected));
444
    const GradientTypeT grad = userPalette->getGradientType(type);
445
446
    mGradTypeText->setCaption(
447
        // TRANSLATORS: color type
448
        (grad == GradientType::STATIC) ? _("Static") :
449
        // TRANSLATORS: color type
450
        (grad == GradientType::PULSE) ? _("Pulse") :
451
        // TRANSLATORS: color type
452
        (grad == GradientType::RAINBOW) ? _("Rainbow") : _("Spectrum"));
453
454
    const bool enable = (grad == GradientType::STATIC ||
455
        grad == GradientType::PULSE);
456
    const bool delayEnable = true;
457
458
    mGradDelayText->setEnabled(delayEnable);
459
    mGradDelaySlider->setEnabled(delayEnable);
460
461
    mRedText->setEnabled(enable);
462
    mRedSlider->setEnabled(enable);
463
    mGreenText->setEnabled(enable);
464
    mGreenSlider->setEnabled(enable);
465
    mBlueText->setEnabled(enable);
466
    mBlueSlider->setEnabled(enable);
467
}
468
469
void Setup_Colors::updateColor() const
470
{
471
    if (mSelected == -1 || (userPalette == nullptr))
472
        return;
473
474
    const UserColorIdT type = static_cast<UserColorIdT>(
475
        userPalette->getColorTypeAt(mSelected));
476
    const GradientTypeT grad = static_cast<GradientTypeT>(
477
        CAST_S32(mGradTypeSlider->getValue()));
478
    const int delay = CAST_S32(mGradDelaySlider->getValue());
479
    userPalette->setGradient(type, grad);
480
    userPalette->setGradientDelay(type, delay);
481
482
    if (grad == GradientType::STATIC)
483
    {
484
        userPalette->setColor(type,
485
            CAST_S32(mRedSlider->getValue()),
486
            CAST_S32(mGreenSlider->getValue()),
487
            CAST_S32(mBlueSlider->getValue()));
488
    }
489
    else if (grad == GradientType::PULSE)
490
    {
491
        userPalette->setTestColor(type, Color(
492
            CAST_S32(mRedSlider->getValue()),
493
            CAST_S32(mGreenSlider->getValue()),
494
            CAST_S32(mBlueSlider->getValue()),
495
            255U));
496
    }
497
}