GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/userpalette.cpp Lines: 185 251 73.7 %
Date: 2017-11-29 Branches: 219 476 46.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  Douglas Boffey <[email protected]>
4
 *  Copyright (C) 2009  The Mana World Development Team
5
 *  Copyright (C) 2009-2010  The Mana Developers
6
 *  Copyright (C) 2011-2017  The ManaPlus Developers
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#include "gui/userpalette.h"
25
26
#include "configuration.h"
27
28
#include "utils/foreach.h"
29
#include "utils/gettext.h"
30
31
#include "debug.h"
32
33
UserPalette *userPalette = nullptr;
34
35
6
const std::string ColorTypeNames[CAST_SIZE(
36
    UserColorId::USER_COLOR_LAST)] =
37
{
38
    "",
39
    "ColorBeing",
40
    "ColorFriend",
41
    "ColorDisregarded",
42
    "ColorIgnored",
43
    "ColorErased",
44
    "ColorEnemy",
45
    "ColorPlayer",
46
    "ColorSelf",
47
    "ColorGM",
48
    "ColorNPC",
49
    "ColorMonster",
50
    "ColorPet",
51
    "ColorMercenary",
52
    "ColorHomunculus",
53
    "ColorSkillUnit",
54
    "ColorParty",
55
    "ColorGuild",
56
    "ColorTeam1",
57
    "ColorTeam2",
58
    "ColorTeam3",
59
    "",
60
    "ColorParticle",
61
    "ColorPickupInfo",
62
    "ColorExpInfo",
63
    "",
64
    "ColorPlayerHp",
65
    "ColorPlayerHp2",
66
    "ColorMonsterHp",
67
    "ColorMonsterHp2",
68
    "ColorHomunHp",
69
    "ColorHomunHp2",
70
    "ColorMercHp",
71
    "ColorMercHp2",
72
    "ColorElementalHp",
73
    "ColorElementalHp2",
74
    "",
75
    "ColorHitPlayerMonster",
76
    "ColorHitMonsterPlayer",
77
    "ColorHitPlayerPlayer",
78
    "ColorHitCritical",
79
    "ColorHitLocalPlayerMonster",
80
    "ColorHitLocalPlayerCritical",
81
    "ColorHitLocalPlayerMiss",
82
    "ColorMiss",
83
    "",
84
    "ColorPortalHighlight",
85
    "ColorCollisionHighlight",
86
    "ColorCollisionAirHighlight",
87
    "ColorCollisionWaterHighlight",
88
    "ColorCollisionMonsterHighlight",
89
    "ColorCollisionGroundtopHighlight",
90
    "ColorWalkableTileHighlight",
91
    "ColorNet",
92
    "",
93
    "ColorAttackRange",
94
    "ColorAttackRangeBorder",
95
    "ColorMonsterAttackRange",
96
    "ColorSkillAttackRange",
97
    "",
98
    "ColorFloorItemText",
99
    "ColorHomePlace",
100
    "ColorHomePlaceBorder",
101
    "ColorRoadPoint",
102
































258
};
103
104
std::string UserPalette::getConfigName(const std::string &typeName)
105
{
106
    std::string res("Color" + typeName);
107
    size_t pos = 5;
108
    for (size_t i = 0; i < typeName.length(); i++)
109
    {
110
        if (i == 0 || typeName[i] == '_')
111
        {
112
            if (i > 0)
113
                i++;
114
115
            res[pos] = typeName[i];
116
        }
117
        else
118
        {
119
           res[pos] = CAST_S8(tolower(typeName[i]));
120
        }
121
        pos ++;
122
    }
123
    res.erase(pos, res.length() - pos);
124
    return res;
125
}
126
127
274
UserPalette::UserPalette() :
128
    Palette(CAST_S32(UserColorId::USER_COLOR_LAST)),
129
548
    ListModel()
130
{
131
822
    mColors[CAST_SIZE(UserColorId::BEING)] = ColorElem();
132
822
    mColors[CAST_SIZE(UserColorId::PC)] = ColorElem();
133
822
    mColors[CAST_SIZE(UserColorId::SELF)] = ColorElem();
134
822
    mColors[CAST_SIZE(UserColorId::GM)] = ColorElem();
135
822
    mColors[CAST_SIZE(UserColorId::NPC)] = ColorElem();
136
822
    mColors[CAST_SIZE(UserColorId::MONSTER)] = ColorElem();
137
138

1096
    addLabel(UserColorId::LABEL_BEING,
139
        // TRANSLATORS: palette label
140
274
        _("Beings"));
141

1096
    addColor(UserColorId::BEING,
142
        0xffffff,
143
        GradientType::STATIC,
144
        // TRANSLATORS: palette color
145
274
        _("Being"));
146

1096
    addColor(UserColorId::FRIEND,
147
        0xb0ffb0,
148
        GradientType::STATIC,
149
        // TRANSLATORS: palette color
150
274
        _("Friend names"));
151

1096
    addColor(UserColorId::DISREGARDED,
152
        0xa00000,
153
        GradientType::STATIC,
154
        // TRANSLATORS: palette color
155
274
        _("Disregarded names"));
156

1096
    addColor(UserColorId::IGNORED,
157
        0xff0000,
158
        GradientType::STATIC,
159
        // TRANSLATORS: palette color
160
274
        _("Ignored names"));
161

1096
    addColor(UserColorId::ERASED,
162
        0xff0000,
163
        GradientType::STATIC,
164
        // TRANSLATORS: palette color
165
274
        _("Erased names"));
166

1096
    addColor(UserColorId::ENEMY,
167
        0xff4040,
168
        GradientType::STATIC,
169
        // TRANSLATORS: palette color
170
274
        _("Enemy"));
171

1096
    addColor(UserColorId::PC,
172
        0xffffff,
173
        GradientType::STATIC,
174
        // TRANSLATORS: palette color
175
274
        _("Other players names"));
176

1096
    addColor(UserColorId::SELF,
177
        0xff8040,
178
        GradientType::STATIC,
179
        // TRANSLATORS: palette color
180
274
        _("Own name"));
181

1096
    addColor(UserColorId::GM,
182
        0x00ff00,
183
        GradientType::STATIC,
184
        // TRANSLATORS: palette color
185
274
        _("GM names"));
186

1096
    addColor(UserColorId::NPC,
187
        0xc8c8ff,
188
        GradientType::STATIC,
189
        // TRANSLATORS: palette color
190
274
        _("NPCs"));
191

1096
    addColor(UserColorId::MONSTER,
192
        0xff4040,
193
        GradientType::STATIC,
194
        // TRANSLATORS: palette color
195
274
        _("Monsters"));
196

1096
    addColor(UserColorId::PET,
197
        0xffffff,
198
        GradientType::STATIC,
199
        // TRANSLATORS: palette color
200
274
        _("Pets"));
201

1096
    addColor(UserColorId::MERCENARY,
202
        0xffffff,
203
        GradientType::STATIC,
204
        // TRANSLATORS: palette color
205
274
        _("Mercenary"));
206

1096
    addColor(UserColorId::HOMUNCULUS,
207
        0xffffff,
208
        GradientType::STATIC,
209
        // TRANSLATORS: palette color
210
274
        _("Homunculus"));
211

1096
    addColor(UserColorId::SKILLUNIT,
212
        0xffffff,
213
        GradientType::STATIC,
214
        // TRANSLATORS: palette color
215
274
        _("Skill unit"));
216

1096
    addColor(UserColorId::PARTY,
217
        0xff00d8,
218
        GradientType::STATIC,
219
        // TRANSLATORS: palette color
220
274
        _("Party members"));
221

1096
    addColor(UserColorId::GUILD,
222
        0xff00d8,
223
        GradientType::STATIC,
224
        // TRANSLATORS: palette color
225
274
        _("Guild members"));
226
274
    addColor(UserColorId::TEAM1,
227
        0x0000ff,
228
        GradientType::STATIC,
229
        // TRANSLATORS: palette color
230
548
        strprintf(_("Team %d"), 1));
231
274
    addColor(UserColorId::TEAM2,
232
        0x00a020,
233
        GradientType::STATIC,
234
        // TRANSLATORS: palette color
235
548
        strprintf(_("Team %d"), 2));
236
274
    addColor(UserColorId::TEAM3,
237
        0xffff20,
238
        GradientType::STATIC,
239
        // TRANSLATORS: palette color
240
548
        strprintf(_("Team %d"), 3));
241

1096
    addLabel(UserColorId::LABEL_PARTICLES,
242
        // TRANSLATORS: palette label
243
274
        _("Particles"));
244

1096
    addColor(UserColorId::PARTICLE,
245
        0xffffff,
246
        GradientType::STATIC,
247
        // TRANSLATORS: palette color
248
274
        _("Particle effects"));
249

1096
    addColor(UserColorId::PICKUP_INFO,
250
        0x28dc28,
251
        GradientType::STATIC,
252
        // TRANSLATORS: palette color
253
274
        _("Pickup notification"));
254

1096
    addColor(UserColorId::EXP_INFO,
255
        0xffff00,
256
        GradientType::STATIC,
257
        // TRANSLATORS: palette color
258
274
        _("Exp notification"));
259

1096
    addLabel(UserColorId::LABEL_HP,
260
        // TRANSLATORS: palette label
261
274
        _("Hp bars"));
262

1096
    addColor(UserColorId::PLAYER_HP,
263
        0x00ff00,
264
        GradientType::STATIC,
265
        // TRANSLATORS: palette color
266
274
        _("Player HP bar"), 50);
267

1096
    addColor(UserColorId::PLAYER_HP2,
268
        0xff0000,
269
        GradientType::STATIC,
270
        // TRANSLATORS: palette color
271
274
        _("Player HP bar (second color)"),
272
        50);
273

1096
    addColor(UserColorId::MONSTER_HP,
274
        0x00ff00,
275
        GradientType::STATIC,
276
        // TRANSLATORS: palette color
277
274
        _("Monster HP bar"),
278
        50);
279

1096
    addColor(UserColorId::MONSTER_HP2,
280
        0xff0000,
281
        GradientType::STATIC,
282
        // TRANSLATORS: palette color
283
274
        _("Monster HP bar (second color)"),
284
        50);
285

1096
    addColor(UserColorId::HOMUN_HP,
286
        0x00ff00,
287
        GradientType::STATIC,
288
        // TRANSLATORS: palette color
289
274
        _("Homunculus HP bar"),
290
        50);
291

1096
    addColor(UserColorId::HOMUN_HP2,
292
        0xff0000,
293
        GradientType::STATIC,
294
        // TRANSLATORS: palette color
295
274
        _("Homunculus HP bar (second color)"),
296
        50);
297

1096
    addColor(UserColorId::MERC_HP,
298
        0x00ff00,
299
        GradientType::STATIC,
300
        // TRANSLATORS: palette color
301
274
        _("Mercenary HP bar"),
302
        50);
303

1096
    addColor(UserColorId::MERC_HP2,
304
        0xff0000,
305
        GradientType::STATIC,
306
        // TRANSLATORS: palette color
307
274
        _("Mercenary HP bar (second color)"),
308
        50);
309
310

1096
    addColor(UserColorId::ELEMENTAL_HP,
311
        0x00ff00,
312
        GradientType::STATIC,
313
        // TRANSLATORS: palette color
314
274
        _("Elemental HP bar"),
315
        50);
316

1096
    addColor(UserColorId::ELEMENTAL_HP2,
317
        0xff0000,
318
        GradientType::STATIC,
319
        // TRANSLATORS: palette color
320
274
        _("Elemental HP bar (second color)"),
321
        50);
322

1096
    addLabel(UserColorId::LABEL_HITS,
323
        // TRANSLATORS: palette label
324
274
        _("Hits"));
325

1096
    addColor(UserColorId::HIT_PLAYER_MONSTER,
326
        0x0064ff,
327
        GradientType::STATIC,
328
        // TRANSLATORS: palette color
329
274
        _("Player hits monster"));
330

1096
    addColor(UserColorId::HIT_MONSTER_PLAYER,
331
        0xff3232,
332
        GradientType::STATIC,
333
        // TRANSLATORS: palette color
334
274
        _("Monster hits player"));
335

1096
    addColor(UserColorId::HIT_PLAYER_PLAYER,
336
        0xff5050,
337
        GradientType::STATIC,
338
       // TRANSLATORS: palette color
339
274
       _("Other player hits local player"));
340

1096
    addColor(UserColorId::HIT_CRITICAL,
341
        0xff0000,
342
        GradientType::RAINBOW,
343
        // TRANSLATORS: palette color
344
274
        _("Critical Hit"));
345

1096
    addColor(UserColorId::HIT_LOCAL_PLAYER_MONSTER,
346
        0x00ff00,
347
        GradientType::STATIC,
348
        // TRANSLATORS: palette color
349
274
        _("Local player hits monster"));
350

1096
    addColor(UserColorId::HIT_LOCAL_PLAYER_CRITICAL,
351
        0xff0000,
352
        GradientType::RAINBOW,
353
        // TRANSLATORS: palette color
354
274
        _("Local player critical hit"));
355

1096
    addColor(UserColorId::HIT_LOCAL_PLAYER_MISS,
356
        0x00ffa6,
357
        GradientType::STATIC,
358
        // TRANSLATORS: palette color
359
274
        _("Local player miss"));
360

1096
    addColor(UserColorId::MISS, 0xffff00,
361
        GradientType::STATIC,
362
        // TRANSLATORS: palette color
363
274
        _("Misses"));
364

1096
    addLabel(UserColorId::LABEL_TILES,
365
        // TRANSLATORS: palette label
366
274
        _("Tiles"));
367

1096
    addColor(UserColorId::PORTAL_HIGHLIGHT,
368
        0xC80000,
369
        GradientType::STATIC,
370
        // TRANSLATORS: palette color
371
274
        _("Portal highlight"));
372

1096
    addColor(UserColorId::COLLISION_HIGHLIGHT,
373
        0x0000C8,
374
        GradientType::STATIC,
375
        // TRANSLATORS: palette color
376
274
        _("Default collision highlight"),
377
        64);
378

1096
    addColor(UserColorId::AIR_COLLISION_HIGHLIGHT,
379
        0xe0e0ff,
380
        GradientType::STATIC,
381
        // TRANSLATORS: palette color
382
274
        _("Air collision highlight"),
383
        64);
384

1096
    addColor(UserColorId::WATER_COLLISION_HIGHLIGHT,
385
        0x2050e0,
386
        GradientType::STATIC,
387
        // TRANSLATORS: palette color
388
274
        _("Water collision highlight"),
389
        64);
390

1096
    addColor(UserColorId::MONSTER_COLLISION_HIGHLIGHT,
391
        0x2050e0,
392
        GradientType::STATIC,
393
        // TRANSLATORS: palette color
394
274
        _("Monster collision highlight"),
395
        64);
396

1096
    addColor(UserColorId::GROUNDTOP_COLLISION_HIGHLIGHT,
397
        0xffff00,
398
        GradientType::STATIC,
399
        // TRANSLATORS: palette color
400
274
        _("Special ground collision highlight"),
401
        20);
402

1096
    addColor(UserColorId::WALKABLE_HIGHLIGHT,
403
        0x00D000,
404
        GradientType::STATIC,
405
        // TRANSLATORS: palette color
406
274
        _("Walkable highlight"),
407
        255);
408

1096
    addColor(UserColorId::NET,
409
        0x000000,
410
        GradientType::STATIC,
411
        // TRANSLATORS: palette color
412
274
        _("Tiles border"), 64);
413

1096
    addLabel(UserColorId::LABEL_RANGES,
414
        // TRANSLATORS: palette label
415
274
        _("Ranges"));
416

1096
    addColor(UserColorId::ATTACK_RANGE,
417
        0xffffff,
418
        GradientType::STATIC,
419
        // TRANSLATORS: palette color
420
274
        _("Local player attack range"),
421
        5);
422

1096
    addColor(UserColorId::ATTACK_RANGE_BORDER,
423
        0x0,
424
        GradientType::STATIC,
425
        // TRANSLATORS: palette color
426
274
        _("Local player attack range border"),
427
        76);
428

1096
    addColor(UserColorId::MONSTER_ATTACK_RANGE,
429
        0xff0000,
430
        GradientType::STATIC,
431
        // TRANSLATORS: palette color
432
274
        _("Monster attack range"),
433
        20);
434

1096
    addColor(UserColorId::SKILL_ATTACK_RANGE,
435
        0x0,
436
        GradientType::STATIC,
437
        // TRANSLATORS: palette color
438
274
        _("Skill attack range border"),
439
        76);
440

1096
    addLabel(UserColorId::LABEL_OTHER,
441
        // TRANSLATORS: palette label
442
274
        _("Other"));
443

1096
    addColor(UserColorId::FLOOR_ITEM_TEXT,
444
        0xffffff,
445
        GradientType::STATIC,
446
        // TRANSLATORS: palette color
447
274
        _("Floor item amount color"),
448
        100);
449

1096
    addColor(UserColorId::HOME_PLACE,
450
        0xffffff,
451
        GradientType::STATIC,
452
        // TRANSLATORS: palette color
453
274
        _("Home place"),
454
        20);
455

1096
    addColor(UserColorId::HOME_PLACE_BORDER,
456
        0xffff00,
457
        GradientType::STATIC,
458
        // TRANSLATORS: palette color
459
274
        _("Home place border"),
460
        200);
461

1096
    addColor(UserColorId::ROAD_POINT,
462
        0x000000,
463
        GradientType::STATIC,
464
        // TRANSLATORS: palette color
465
274
        _("Road point"), 100);
466
274
    commit(true);
467
274
}
468
469
1096
UserPalette::~UserPalette()
470
{
471
19180
    FOR_EACH (Colors::const_iterator, col, mColors)
472
    {
473
17536
        if (col->grad == GradientType::LABEL)
474
1918
            continue;
475
15618
        const std::string &configName = ColorTypeNames[col->type];
476
31236
        config.setValue(configName + "Gradient",
477
15618
            CAST_S32(col->committedGrad));
478
31236
        config.setValue(configName + "Delay", col->delay);
479
480

16166
        if (col->grad == GradientType::STATIC ||
481
548
            col->grad == GradientType::PULSE)
482
        {
483
            char buffer[20];
484
45210
            snprintf(buffer, sizeof(buffer), "0x%06x", col->getRGB());
485
15070
            buffer[19] = 0;
486
60280
            config.setValue(configName, std::string(buffer));
487
        }
488
    }
489
548
}
490
491
void UserPalette::setColor(const UserColorIdT type,
492
                           const int r,
493
                           const int g,
494
                           const int b)
495
{
496
    Color &color = mColors[CAST_SIZE(type)].color;
497
    color.r = r;
498
    color.g = g;
499
    color.b = b;
500
}
501
502
void UserPalette::setGradient(const UserColorIdT type,
503
                              const GradientTypeT grad)
504
{
505
    ColorElem *const elem = &mColors[CAST_SIZE(type)];
506
507
    if (elem->grad != GradientType::STATIC && grad == GradientType::STATIC)
508
    {
509
        const size_t sz = mGradVector.size();
510
        for (size_t i = 0; i < sz; i++)
511
        {
512
            if (mGradVector[i] == elem)
513
            {
514
                mGradVector.erase(mGradVector.begin() + i);
515
                break;
516
            }
517
        }
518
    }
519
    else if (elem->grad == GradientType::STATIC &&
520
             grad != GradientType::STATIC)
521
    {
522
        mGradVector.push_back(elem);
523
    }
524
525
    if (elem->grad != grad)
526
        elem->grad = grad;
527
}
528
529
std::string UserPalette::getElementAt(int i)
530
{
531
    if (i < 0 || i >= getNumberOfElements())
532
        return "";
533
534
    return mColors[i].text;
535
}
536
537
void UserPalette::commit(const bool commitNonStatic)
538
{
539

18632
    FOR_EACH (Colors::iterator, i, mColors)
540
    {
541
17536
        i->committedGrad = i->grad;
542
17536
        i->committedDelay = i->delay;
543
        if (commitNonStatic || i->grad == GradientType::STATIC)
544
17536
            i->committedColor = i->color;
545
        else if (i->grad == GradientType::PULSE)
546
            i->committedColor = i->testColor;
547
    }
548
}
549
550
void UserPalette::rollback()
551
{
552
    FOR_EACH (Colors::iterator, i, mColors)
553
    {
554
        if (i->grad != i->committedGrad)
555
            setGradient(static_cast<UserColorIdT>(i->type), i->committedGrad);
556
557
        const Color &committedColor = i->committedColor;
558
        setGradientDelay(static_cast<UserColorIdT>(i->type),
559
            i->committedDelay);
560
        setColor(static_cast<UserColorIdT>(i->type),
561
            committedColor.r,
562
            committedColor.g,
563
            committedColor.b);
564
565
        if (i->grad == GradientType::PULSE)
566
        {
567
            Color &testColor = i->testColor;
568
            testColor.r = committedColor.r;
569
            testColor.g = committedColor.g;
570
            testColor.b = committedColor.b;
571
        }
572
    }
573
}
574
575
int UserPalette::getColorTypeAt(const int i)
576
{
577
    if (i < 0 || i >= getNumberOfElements())
578
        return 0;
579
580
    return mColors[i].type;
581
}
582
583
15618
void UserPalette::addColor(const UserColorIdT type,
584
                           const unsigned rgb,
585
                           GradientTypeT grad,
586
                           const std::string &text,
587
                           int delay)
588
{
589
15618
    const unsigned maxType = sizeof(ColorTypeNames)
590
        / sizeof(ColorTypeNames[0]);
591
592
15618
    if (CAST_U32(type) >= maxType)
593
        return;
594
595
15618
    const std::string &configName = ColorTypeNames[CAST_SIZE(type)];
596
    char buffer[20];
597
15618
    snprintf(buffer, sizeof(buffer), "0x%06x", rgb);
598
15618
    buffer[19] = 0;
599
600
    const std::string rgbString = config.getValue(
601

78090
        configName, std::string(buffer));
602
15618
    unsigned int rgbValue = 0;
603

46854
    if (rgbString.length() == 8 && rgbString[0] == '0' && rgbString[1] == 'x')
604
15618
        rgbValue = atox(rgbString);
605
    else
606
        rgbValue = atoi(rgbString.c_str());
607
15618
    const Color &trueCol = Color(rgbValue);
608
15618
    grad = static_cast<GradientTypeT>(config.getValue(
609
31236
        configName + "Gradient",
610
        CAST_S32(grad)));
611

31236
    delay = config.getValueInt(configName + "Delay", delay);
612
46854
    mColors[CAST_SIZE(type)].set(CAST_S32(type),
613
        trueCol, grad, delay);
614
46854
    mColors[CAST_SIZE(type)].text = text;
615
616
15618
    if (grad != GradientType::STATIC)
617
1644
        mGradVector.push_back(&mColors[CAST_SIZE(type)]);
618
}
619
620
1918
void UserPalette::addLabel(const UserColorIdT type,
621
                           const std::string &text)
622
{
623
1918
    const unsigned maxType = sizeof(ColorTypeNames)
624
        / sizeof(ColorTypeNames[0]);
625
626
1918
    if (CAST_U32(type) >= maxType)
627
        return;
628
629
630
5754
    mColors[CAST_SIZE(type)] = ColorElem();
631
    const std::string str(" \342\200\225\342\200\225\342\200\225"
632
7672
        "\342\200\225\342\200\225 ");
633
3836
    mColors[CAST_SIZE(type)].grad = GradientType::LABEL;
634
5754
    mColors[CAST_SIZE(type)].text =
635
9590
        std::string(str).append(text).append(str);
636
}
637
638
int UserPalette::getIdByChar(const signed char c, bool &valid) const
639
{
640
    const CharColors::const_iterator it = mCharColors.find(c);
641
    if (it != mCharColors.end())
642
    {
643
        valid = true;
644
        return (*it).second;
645
    }
646
647
    valid = false;
648
    return 0;
649

6
}