GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/tabs/setup_colors.cpp Lines: 110 257 42.8 %
Date: 2018-05-19 03:07:18 Branches: 133 344 38.7 %

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


16
    mColorBox(CREATEWIDGETR(ListBox, this, userPalette, "")),
56
4
    mScroll(new ScrollArea(this, mColorBox,
57

8
        Opaque_true, "setup_colors_background.xml")),
58
    mPreview(new BrowserBox(this, Opaque_true,
59

4
        "browserbox.xml")),
60

8
    mTextPreview(new TextPreview(this, gettext(rawmsg))),
61
4
    mPreviewBox(new ScrollArea(this, mPreview, Opaque_true,
62

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

8
    mGradTypeLabel(new Label(this, _("Type:"))),
66

4
    mGradTypeSlider(new Slider(this, 0.0, 3.0, 1.0)),
67

4
    mGradTypeText(new Label(this)),
68
    // TRANSLATORS: colors tab. label.
69

8
    mGradDelayLabel(new Label(this, _("Delay:"))),
70

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

8
        nullptr, std::string(), false)),
73
    // TRANSLATORS: colors tab. label.
74

8
    mRedLabel(new Label(this, _("Red:"))),
75

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

8
        nullptr, std::string(), false)),
78
    // TRANSLATORS: colors tab. label.
79

8
    mGreenLabel(new Label(this, _("Green:"))),
80

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

8
        nullptr, std::string(), false)),
83
    // TRANSLATORS: colors tab. label.
84

8
    mBlueLabel(new Label(this, _("Blue:"))),
85

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





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


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


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


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

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

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

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

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

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

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