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