GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/window.h Lines: 19 22 86.4 %
Date: 2021-03-17 Branches: 0 4 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
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
/*      _______   __   __   __   ______   __   __   _______   __   __
25
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
26
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
27
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
28
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
29
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
30
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
31
 *
32
 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
33
 *
34
 *
35
 * Per Larsson a.k.a finalman
36
 * Olof Naessén a.k.a jansem/yakslem
37
 *
38
 * Visit: http://guichan.sourceforge.net
39
 *
40
 * License: (BSD)
41
 * Redistribution and use in source and binary forms, with or without
42
 * modification, are permitted provided that the following conditions
43
 * are met:
44
 * 1. Redistributions of source code must retain the above copyright
45
 *    notice, this list of conditions and the following disclaimer.
46
 * 2. Redistributions in binary form must reproduce the above copyright
47
 *    notice, this list of conditions and the following disclaimer in
48
 *    the documentation and/or other materials provided with the
49
 *    distribution.
50
 * 3. Neither the name of Guichan nor the names of its contributors may
51
 *    be used to endorse or promote products derived from this software
52
 *    without specific prior written permission.
53
 *
54
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
55
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
56
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
57
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
58
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
60
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
61
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
62
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
63
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65
 */
66
67
#ifndef GUI_WIDGETS_WINDOW_H
68
#define GUI_WIDGETS_WINDOW_H
69
70
#include "enums/simpletypes/modal.h"
71
#include "enums/simpletypes/move.h"
72
73
#include "enums/resources/imageposition.h"
74
75
#include "gui/fonts/textchunk.h"
76
77
#include "gui/widgets/basiccontainer2.h"
78
79
#include "listeners/mouselistener.h"
80
#include "listeners/widgetlistener.h"
81
82
#include "render/graphics.h"
83
84
#include "localconsts.h"
85
86
class ContainerPlacer;
87
class ImageCollection;
88
class Layout;
89
class LayoutCell;
90
class Skin;
91
class WindowContainer;
92
93
/**
94
 * A window. This window can be dragged around and has a title bar. Windows are
95
 * invisible by default.
96
 *
97
 * \ingroup GUI
98
 */
99
class Window notfinal : public BasicContainer2,
100
                        public MouseListener,
101
                        public WidgetListener
102
{
103
    public:
104
        /**
105
         * Constructor. Initializes the title to the given text and hooks
106
         * itself into the window container.
107
         *
108
         * @param caption The initial window title, "Window" by default.
109
         * @param modal   Block input to other windows.
110
         * @param parent  The parent window. This is the window standing above
111
         *                this one in the window hiearchy. When reordering,
112
         *                a window will never go below its parent window.
113
         * @param skin    The location where the window's skin XML can be found.
114
         */
115
        Window(const std::string &caption,
116
               const Modal modal,
117
               Window *const parent,
118
               std::string skin);
119
120
        A_DELETE_COPY(Window)
121
122
        /**
123
         * Destructor. Deletes all the added widgets.
124
         */
125
        ~Window() override;
126
127
        /**
128
         * Sets the window container to be used by new windows.
129
         */
130
        static void setWindowContainer(WindowContainer *const windowContainer);
131
132
        /**
133
         * Draws the window.
134
         */
135
        void draw(Graphics *const graphics) override A_NONNULL(2);
136
137
        void safeDraw(Graphics *const graphics) override A_NONNULL(2);
138
139
        /**
140
         * Sets the size of this window.
141
         */
142
        void setContentSize(int width, int height);
143
144
        /**
145
         * Sets the location relative to the given widget.
146
         */
147
        void setLocationRelativeTo(const Widget *const widget);
148
149
        /**
150
         * Sets the location relative to the given widget (only horisontally)
151
         */
152
        void setLocationHorisontallyRelativeTo(const Widget
153
                                               *const widget);
154
155
        /**
156
         * Sets the location relative to the given enumerated position.
157
         */
158
        void setLocationRelativeTo(const ImagePosition::Type &position,
159
                                   int offsetX,
160
                                   int offsetY);
161
162
        /**
163
         * Sets whether or not the window can be resized.
164
         */
165
        void setResizable(const bool resize);
166
167
        void redraw();
168
169
        /**
170
         * Called whenever the widget changes size.
171
         */
172
        void widgetResized(const Event &event) override;
173
174
        void widgetMoved(const Event& event) override;
175
176
        /**
177
         * Called whenever the widget is hidden.
178
         */
179
        void widgetHidden(const Event &event) override;
180
181
        /**
182
         * Sets whether or not the window has a close button.
183
         */
184
        void setCloseButton(const bool flag);
185
186
        bool getCloseButton() const noexcept2 A_WARN_UNUSED
187
        { return mCloseWindowButton; }
188
189
        void setAllowClose(const bool b)
190
2
        { mAllowClose = b; }
191
192
        bool getAlowClose() const noexcept2 A_WARN_UNUSED
193
        { return mCloseWindowButton || mAllowClose; }
194
195
        /**
196
         * Returns whether the window can be resized.
197
         */
198
        bool isResizable() const A_WARN_UNUSED;
199
200
        /**
201
         * Sets the minimum width of the window.
202
         */
203
        void setMinWidth(const int width);
204
205
        int getMinWidth() const noexcept2 A_WARN_UNUSED
206
76
        { return mMinWinWidth; }
207
208
        /**
209
         * Sets the minimum height of the window.
210
         */
211
        void setMinHeight(const int height);
212
213
        int getMinHeight() const noexcept2 A_WARN_UNUSED
214
76
        { return mMinWinHeight; }
215
216
        /**
217
         * Sets the maximum width of the window.
218
         */
219
        void setMaxWidth(const int width);
220
221
        int getMaxWidth() const noexcept2 A_WARN_UNUSED
222
75
        { return mMaxWinWidth; }
223
224
        /**
225
         * Sets the minimum height of the window.
226
         */
227
        void setMaxHeight(const int height);
228
229
        int getMaxHeight() const noexcept2 A_WARN_UNUSED
230
75
        { return mMaxWinHeight; }
231
232
        /**
233
         * Sets flag to show a title or not.
234
         */
235
        void setShowTitle(bool flag)
236
6
        { mShowTitle = flag; }
237
238
        /**
239
         * Sets whether or not the window has a sticky button.
240
         */
241
        void setStickyButton(const bool flag);
242
243
        /**
244
          * Sets whether the window is sticky. A sticky window will not have
245
          * its visibility set to false on a general setVisible(false) call.
246
          * Use this to set the default before you call loadWindowState().
247
          */
248
        void setSticky(const bool sticky);
249
250
        /**
251
         * Returns whether the window is sticky.
252
         */
253
        bool isSticky() const noexcept2 A_WARN_UNUSED
254
71
        { return mSticky; }
255
256
        /**
257
          * Sets whether the window sticky mean window locked or not.
258
          */
259
        void setStickyButtonLock(const bool sticky);
260
261
        /**
262
         * Returns whether the window sticky locking window.
263
         */
264
        bool isStickyButtonLock() const noexcept2 A_WARN_UNUSED
265
        { return mStickyButtonLock; }
266
267
        /**
268
         * Overloads window setVisible by Guichan to allow sticky window
269
         * handling.
270
         */
271
        virtual void setVisible(Visible visible);
272
273
        /**
274
         * Overloads window setVisible by Guichan to allow sticky window
275
         * handling, or not, if you force the sticky state.
276
         */
277
        void setVisible(const Visible visible, const bool forceSticky);
278
279
        /**
280
         * Returns whether the window is visible by default.
281
         */
282
        bool isDefaultVisible() const noexcept2 A_WARN_UNUSED
283
        { return mDefaultVisible; }
284
285
        /**
286
         * Sets whether the window is visible by default.
287
         */
288
        void setDefaultVisible(const bool save)
289
6
        { mDefaultVisible = save; }
290
291
        /**
292
         * Returns whether the window will save it's visibility.
293
         */
294
        bool willSaveVisible() const
295
        { return mSaveVisible; }
296
297
        /**
298
         * Sets whether the window will save it's visibility.
299
         */
300
        void setSaveVisible(const bool save)
301
21
        { mSaveVisible = save; }
302
303
        void postInit() override;
304
305
        /**
306
         * Returns the parent window.
307
         *
308
         * @return The parent window or <code>NULL</code> if there is none.
309
         */
310
        Window *getParentWindow() const
311
        { return mParentWindow; }
312
313
        /**
314
         * Schedule this window for deletion. It will be deleted at the start
315
         * of the next logic update.
316
         */
317
        virtual void scheduleDelete();
318
319
        /**
320
         * Starts window resizing when appropriate.
321
         */
322
        void mousePressed(MouseEvent &event) override;
323
324
        /**
325
         * Implements window resizing and makes sure the window is not
326
         * dragged/resized outside of the screen.
327
         */
328
        void mouseDragged(MouseEvent &event) override;
329
330
        /**
331
         * Implements custom cursor image changing context, based on mouse
332
         * relative position.
333
         */
334
        void mouseMoved(MouseEvent &event) override;
335
336
        /**
337
         * When the mouse button has been let go, this ensures that the mouse
338
         * custom cursor is restored back to it's standard image.
339
         */
340
        void mouseReleased(MouseEvent &event) override;
341
342
        /**
343
         * When the mouse leaves the window this ensures that the custom cursor
344
         * is restored back to it's standard image.
345
         */
346
        void mouseExited(MouseEvent &event) override;
347
348
        void mouseEntered(MouseEvent &event) override;
349
350
        void updateResizeHandler(MouseEvent &event);
351
352
        /**
353
         * Sets the name of the window. This is not the window title.
354
         */
355
        void setWindowName(const std::string &name)
356
98
        { mWindowName = name; }
357
358
        /**
359
         * Returns the name of the window. This is not the window title.
360
         */
361
        const std::string &getWindowName() const noexcept2 A_WARN_UNUSED
362
2
        { return mWindowName; }
363
364
        /**
365
         * Reads the position (and the size for resizable windows) in the
366
         * configuration based on the given string.
367
         * Uses the default values when config values are missing.
368
         * Don't forget to set these default values and resizable before
369
         * calling this function.
370
         */
371
        void loadWindowState();
372
373
        /**
374
         * Saves the window state so that when the window is reloaded, it'll
375
         * maintain its previous state and location.
376
         */
377
        void saveWindowState();
378
379
        /**
380
         * Set the default win pos and size.
381
         * (which can be different of the actual ones.)
382
         */
383
        void setDefaultSize(const int defaultX, const int defaultY,
384
                            int defaultWidth, int defaultHeight);
385
386
        /**
387
         * Set the default win pos and size to the current ones.
388
         */
389
        void setDefaultSize();
390
391
        /**
392
         * Set the default win pos and size.
393
         * (which can be different of the actual ones.)
394
         * This version of setDefaultSize sets the window's position based
395
         * on a relative enumerated position, rather than a coordinate position.
396
         */
397
        void setDefaultSize(const int defaultWidth,
398
                            const int defaultHeight,
399
                            const ImagePosition::Type &position,
400
                            const int offsetx,
401
                            const int offsetY);
402
403
        /**
404
         * Reset the win pos and size to default. Don't forget to set defaults
405
         * first.
406
         */
407
        virtual void resetToDefaultSize();
408
409
        /**
410
         * Adjusts the window position after the application window has been
411
         * resized.
412
         */
413
        void adjustPositionAfterResize(const int oldScreenWidth,
414
                                       const int oldScreenHeight);
415
416
        /**
417
         * Gets the layout handler for this window.
418
         */
419
        Layout &getLayout() A_WARN_UNUSED;
420
421
        /**
422
         * Clears the window's layout (useful for redesigning the window). Does
423
         * not delete the widgets!
424
         */
425
        void clearLayout();
426
427
        /**
428
         * Computes the position of the widgets according to the current
429
         * layout. Resizes the window so that the layout fits. Deletes the
430
         * layout.
431
         * @param w if non-zero, force the window to this width.
432
         * @param h if non-zero, force the window to this height.
433
         * @note This function is meant to be called with fixed-size windows.
434
         */
435
        void reflowLayout(int w,
436
                          int h);
437
438
        /**
439
         * Adds a widget to the window and sets it at given cell.
440
         */
441
        LayoutCell &place(const int x,
442
                          const int y,
443
                          Widget *const wg,
444
                          const int w,
445
                          const int h);
446
447
        /**
448
         * Returns a proxy for adding widgets in an inner table of the layout.
449
         */
450
        ContainerPlacer getPlacer(const int x, const int y) A_WARN_UNUSED;
451
452
        /**
453
         * Positions the window in the center of it's parent.
454
         */
455
        void center();
456
457
        /**
458
         * Positions the window in the horisontal center of it's parent.
459
         */
460
        void centerHorisontally();
461
462
        /**
463
         * Overrideable functionality for when the window is to close. This
464
         * allows for class implementations to clean up or do certain actions
465
         * on window close they couldn't do otherwise.
466
         */
467
        virtual void close();
468
469
         /**
470
         * Allows the windows modal status to change
471
         */
472
        void setModal(const Modal modal);
473
474
        Rect getWindowArea() const A_WARN_UNUSED;
475
476
        bool isResizeAllowed(const MouseEvent &event) const A_WARN_UNUSED;
477
478
        void setCaptionFont(Font *font)
479
        { mCaptionFont = font; }
480
481
        void enableVisibleSound(bool b)
482
44
        { mPlayVisibleSound = b; }
483
484
        bool isWindowVisible() const noexcept2 A_WARN_UNUSED
485
16
        { return mVisible == Visible_true; }
486
487
        /**
488
         * Sets the padding of the window. The padding is the distance between the
489
         * window border and the content.
490
         *
491
         * @param padding The padding of the window.
492
         * @see getPadding
493
         */
494
        void setPadding(int padding)
495
126
        { mPadding = padding; }
496
497
        /**
498
         * Gets the padding of the window. The padding is the distance between the
499
         * window border and the content.
500
         *
501
         * @return The padding of the window.
502
         * @see setPadding
503
         */
504
        int getPadding() const
505
        { return mPadding; }
506
507
        /**
508
         * Sets the title bar height.
509
         *
510
         * @param height The title height value.
511
         * @see getTitleBarHeight
512
         */
513
        void setTitleBarHeight(unsigned int height)
514
131
        { mTitleBarHeight = height; }
515
516
        /**
517
         * Gets the title bar height.
518
         *
519
         * @return The title bar height.
520
         * @see setTitleBarHeight
521
         */
522
        unsigned int getTitleBarHeight() const
523
        { return mTitleBarHeight; }
524
525
        /**
526
         * Sets the caption of the window.
527
         *
528
         * @param caption The caption of the window.
529
         * @see getCaption
530
         */
531
        void setCaption(const std::string& caption)
532
14
        { mCaption = caption; mTextChanged = true; }
533
534
        /**
535
         * Gets the caption of the window.
536
         *
537
         * @return the caption of the window.
538
         * @see setCaption
539
         */
540
        const std::string& getCaption() const
541
1
        { return mCaption; }
542
543
        /**
544
         * Sets the alignment of the caption.
545
         *
546
         * @param alignment The alignment of the caption.
547
         * @see getAlignment, Graphics
548
         */
549
        void setAlignment(Graphics::Alignment alignment)
550
        { mAlignment = alignment; }
551
552
        /**
553
         * Gets the alignment of the caption.
554
         *
555
         * @return The alignment of caption.
556
         * @see setAlignment, Graphics
557
         */
558
        Graphics::Alignment getAlignment() const
559
        { return mAlignment; }
560
561
        /**
562
         * Sets the window to be moveble or not.
563
         *
564
         * @param movable True if the window should be movable, false otherwise.
565
         * @see isMovable
566
         */
567
        void setMovable(Move movable)
568
1
        { mMovable = movable; }
569
570
        /**
571
         * Checks if the window is movable.
572
         *
573
         * @return True if the window is movable, false otherwise.
574
         * @see setMovable
575
         */
576
        bool isMovable() const
577
        { return mMovable == Move_true; }
578
579
        Rect getChildrenArea() override;
580
581
        /**
582
         * Resizes the window to fit the content.
583
         */
584
        virtual void resizeToContent();
585
586
#ifdef USE_PROFILER
587
        virtual void logic();
588
#endif  // USE_PROFILER
589
590
    protected:
591
        bool canMove() const A_WARN_UNUSED;
592
593
        int getOption(const std::string &name,
594
                      const int def) const A_WARN_UNUSED;
595
596
        bool getOptionBool(const std::string &name,
597
                           const bool def) const A_WARN_UNUSED;
598
599
        void setTitlePadding(const int p) noexcept2
600
        { mTitlePadding = p; }
601
602
        int getTitlePadding() const noexcept2 A_WARN_UNUSED
603
5
        { return mTitlePadding; }
604
605
        /**
606
         * Holds the caption of the window.
607
         */
608
        std::string mCaption;
609
610
        /**
611
         * Holds the alignment of the caption.
612
         */
613
        Graphics::Alignment mAlignment;
614
615
        /**
616
         * Holds the padding of the window.
617
         */
618
        int mPadding;
619
620
        /**
621
         * Holds the title bar height of the window.
622
         */
623
        unsigned int mTitleBarHeight;
624
625
        /**
626
         * True if the window is movable, false otherwise.
627
         */
628
        Move mMovable;
629
630
        /**
631
         * Holds a drag offset as an x coordinate where the drag of the window
632
         * started if the window is being dragged. It's used to move the window
633
         * correctly when dragged.
634
         */
635
        int mDragOffsetX;
636
637
        /**
638
         * Holds a drag offset as an y coordinate where the drag of the window
639
         * started if the window is being dragged. It's used to move the window
640
         * correctly when dragged.
641
         */
642
        int mDragOffsetY;
643
644
        /**
645
         * True if the window is being moved, false otherwise.
646
         */
647
        bool mMoved;
648
649
        Skin *mSkin;                  /**< Skin in use by this window */
650
        int mDefaultX;                /**< Default window X position */
651
        int mDefaultY;                /**< Default window Y position */
652
        int mDefaultWidth;            /**< Default window width */
653
        int mDefaultHeight;           /**< Default window height */
654
        int mCaptionOffsetX;
655
        int mCaptionOffsetY;
656
        bool mShowTitle;              /**< Window has a title bar */
657
        bool mLastRedraw;
658
659
    private:
660
        enum ResizeHandles
661
        {
662
            TOP    = 0x01,
663
            RIGHT  = 0x02,
664
            BOTTOM = 0x04,
665
            LEFT   = 0x08,
666
            CLOSE  = 0x10
667
        };
668
669
        /**
670
         * Ensures the window is on the screen, moving it if necessary. This is
671
         * used by loadWindowState and setVisible(true), and when the screen
672
         * is resized.
673
         */
674
        void ensureOnScreen();
675
676
        void adjustSizeToScreen();
677
678
        /**
679
         * Determines if the mouse is in a resize area and returns appropriate
680
         * resize handles. Also initializes drag offset in case the resize
681
         * grip is used.
682
         *
683
         * @see ResizeHandles
684
         */
685
        int getResizeHandles(const MouseEvent &event) A_WARN_UNUSED;
686
687
        Image *mGrip;                 /**< Resize grip */
688
        Window *mParentWindow;        /**< The parent window */
689
        Layout *mLayout;              /**< Layout handler */
690
        Rect mCloseRect;    /**< Close button rectangle */
691
        Rect mStickyRect;   /**< Sticky button rectangle */
692
        Rect mGripRect;     /**< Resize grip rectangle */
693
        TextChunk mTextChunk;
694
        std::string mWindowName;      /**< Name of the window */
695
        int mMinWinWidth;             /**< Minimum window width */
696
        int mMinWinHeight;            /**< Minimum window height */
697
        int mMaxWinWidth;             /**< Maximum window width */
698
        int mMaxWinHeight;            /**< Maximum window height */
699
700
        static int mouseResize;       /**< Active resize handles */
701
        static int windowInstances;   /**< Number of Window instances */
702
703
704
        /**
705
         * The width of the resize border. Is independent of the actual window
706
         * border width, and determines mostly the size of the corner area
707
         * where two borders are moved at the same time.
708
         */
709
        static const unsigned resizeBorderWidth = 10;
710
        ImageCollection *mVertexes A_NONNULLPOINTER;
711
        Graphics::Alignment mCaptionAlign;
712
        int mTitlePadding;
713
        int mGripPadding;
714
        int mResizeHandles;
715
        int mOldResizeHandles;
716
        int mClosePadding;
717
        int mStickySpacing;
718
        int mStickyPadding;
719
        Font *mCaptionFont A_NONNULLPOINTER;
720
        Modal mModal;                 /**< Window is modal */
721
        bool mCloseWindowButton;      /**< Window has a close button */
722
        bool mDefaultVisible;         /**< Window's default visibility */
723
        bool mSaveVisible;            /**< Window will save visibility */
724
        bool mStickyButton;           /**< Window has a sticky button */
725
        bool mSticky;                 /**< Window resists hiding*/
726
        bool mStickyButtonLock;       /**< Window locked if sticky enabled*/
727
        bool mPlayVisibleSound;
728
        bool mInit;
729
        bool mTextChanged;
730
        bool mAllowClose;
731
};
732
733
#endif  // GUI_WIDGETS_WINDOW_H