GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/window.h Lines: 19 22 86.4 %
Date: 2018-07-14 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-2018  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
        Window(const std::string &caption,
115
               const Modal modal,
116
               Window *const parent,
117
               std::string skin);
118
119
        A_DELETE_COPY(Window)
120
121
        /**
122
         * Destructor. Deletes all the added widgets.
123
         */
124
        ~Window() override;
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,
159
                                   int offsetY);
160
161
        /**
162
         * Sets whether or not the window can be resized.
163
         */
164
        void setResizable(const bool resize);
165
166
        void redraw();
167
168
        /**
169
         * Called whenever the widget changes size.
170
         */
171
        void widgetResized(const Event &event) override;
172
173
        void widgetMoved(const Event& event) override;
174
175
        /**
176
         * Called whenever the widget is hidden.
177
         */
178
        void widgetHidden(const Event &event) override;
179
180
        /**
181
         * Sets whether or not the window has a close button.
182
         */
183
        void setCloseButton(const bool flag);
184
185
        bool getCloseButton() const noexcept2 A_WARN_UNUSED
186
        { return mCloseWindowButton; }
187
188
        void setAllowClose(const bool b)
189
2
        { mAllowClose = b; }
190
191
        bool getAlowClose() const noexcept2 A_WARN_UNUSED
192
        { return mCloseWindowButton || mAllowClose; }
193
194
        /**
195
         * Returns whether the window can be resized.
196
         */
197
        bool isResizable() const A_WARN_UNUSED;
198
199
        /**
200
         * Sets the minimum width of the window.
201
         */
202
        void setMinWidth(const int width);
203
204
        int getMinWidth() const noexcept2 A_WARN_UNUSED
205
76
        { return mMinWinWidth; }
206
207
        /**
208
         * Sets the minimum height of the window.
209
         */
210
        void setMinHeight(const int height);
211
212
        int getMinHeight() const noexcept2 A_WARN_UNUSED
213
76
        { return mMinWinHeight; }
214
215
        /**
216
         * Sets the maximum width of the window.
217
         */
218
        void setMaxWidth(const int width);
219
220
        int getMaxWidth() const noexcept2 A_WARN_UNUSED
221
75
        { return mMaxWinWidth; }
222
223
        /**
224
         * Sets the minimum height of the window.
225
         */
226
        void setMaxHeight(const int height);
227
228
        int getMaxHeight() const noexcept2 A_WARN_UNUSED
229
75
        { return mMaxWinHeight; }
230
231
        /**
232
         * Sets flag to show a title or not.
233
         */
234
        void setShowTitle(bool flag)
235
6
        { mShowTitle = flag; }
236
237
        /**
238
         * Sets whether or not the window has a sticky button.
239
         */
240
        void setStickyButton(const bool flag);
241
242
        /**
243
          * Sets whether the window is sticky. A sticky window will not have
244
          * its visibility set to false on a general setVisible(false) call.
245
          * Use this to set the default before you call loadWindowState().
246
          */
247
        void setSticky(const bool sticky);
248
249
        /**
250
         * Returns whether the window is sticky.
251
         */
252
        bool isSticky() const noexcept2 A_WARN_UNUSED
253
71
        { return mSticky; }
254
255
        /**
256
          * Sets whether the window sticky mean window locked or not.
257
          */
258
        void setStickyButtonLock(const bool sticky);
259
260
        /**
261
         * Returns whether the window sticky locking window.
262
         */
263
        bool isStickyButtonLock() const noexcept2 A_WARN_UNUSED
264
        { return mStickyButtonLock; }
265
266
        /**
267
         * Overloads window setVisible by Guichan to allow sticky window
268
         * handling.
269
         */
270
        virtual void setVisible(Visible visible);
271
272
        /**
273
         * Overloads window setVisible by Guichan to allow sticky window
274
         * handling, or not, if you force the sticky state.
275
         */
276
        void setVisible(const Visible visible, const bool forceSticky);
277
278
        /**
279
         * Returns whether the window is visible by default.
280
         */
281
        bool isDefaultVisible() const noexcept2 A_WARN_UNUSED
282
        { return mDefaultVisible; }
283
284
        /**
285
         * Sets whether the window is visible by default.
286
         */
287
        void setDefaultVisible(const bool save)
288
6
        { mDefaultVisible = save; }
289
290
        /**
291
         * Returns whether the window will save it's visibility.
292
         */
293
        bool willSaveVisible() const
294
        { return mSaveVisible; }
295
296
        /**
297
         * Sets whether the window will save it's visibility.
298
         */
299
        void setSaveVisible(const bool save)
300
21
        { mSaveVisible = save; }
301
302
        void postInit() override;
303
304
        /**
305
         * Returns the parent window.
306
         *
307
         * @return The parent window or <code>NULL</code> if there is none.
308
         */
309
        Window *getParentWindow() const
310
        { return mParentWindow; }
311
312
        /**
313
         * Schedule this window for deletion. It will be deleted at the start
314
         * of the next logic update.
315
         */
316
        virtual void scheduleDelete();
317
318
        /**
319
         * Starts window resizing when appropriate.
320
         */
321
        void mousePressed(MouseEvent &event) override;
322
323
        /**
324
         * Implements window resizing and makes sure the window is not
325
         * dragged/resized outside of the screen.
326
         */
327
        void mouseDragged(MouseEvent &event) override;
328
329
        /**
330
         * Implements custom cursor image changing context, based on mouse
331
         * relative position.
332
         */
333
        void mouseMoved(MouseEvent &event) override;
334
335
        /**
336
         * When the mouse button has been let go, this ensures that the mouse
337
         * custom cursor is restored back to it's standard image.
338
         */
339
        void mouseReleased(MouseEvent &event) override;
340
341
        /**
342
         * When the mouse leaves the window this ensures that the custom cursor
343
         * is restored back to it's standard image.
344
         */
345
        void mouseExited(MouseEvent &event) override;
346
347
        void mouseEntered(MouseEvent &event) override;
348
349
        void updateResizeHandler(MouseEvent &event);
350
351
        /**
352
         * Sets the name of the window. This is not the window title.
353
         */
354
        void setWindowName(const std::string &name)
355
98
        { mWindowName = name; }
356
357
        /**
358
         * Returns the name of the window. This is not the window title.
359
         */
360
        const std::string &getWindowName() const noexcept2 A_WARN_UNUSED
361
2
        { return mWindowName; }
362
363
        /**
364
         * Reads the position (and the size for resizable windows) in the
365
         * configuration based on the given string.
366
         * Uses the default values when config values are missing.
367
         * Don't forget to set these default values and resizable before
368
         * calling this function.
369
         */
370
        void loadWindowState();
371
372
        /**
373
         * Saves the window state so that when the window is reloaded, it'll
374
         * maintain its previous state and location.
375
         */
376
        void saveWindowState();
377
378
        /**
379
         * Set the default win pos and size.
380
         * (which can be different of the actual ones.)
381
         */
382
        void setDefaultSize(const int defaultX, const int defaultY,
383
                            int defaultWidth, int defaultHeight);
384
385
        /**
386
         * Set the default win pos and size to the current ones.
387
         */
388
        void setDefaultSize();
389
390
        /**
391
         * Set the default win pos and size.
392
         * (which can be different of the actual ones.)
393
         * This version of setDefaultSize sets the window's position based
394
         * on a relative enumerated position, rather than a coordinate position.
395
         */
396
        void setDefaultSize(const int defaultWidth,
397
                            const int defaultHeight,
398
                            const ImagePosition::Type &position,
399
                            const int offsetx,
400
                            const int offsetY);
401
402
        /**
403
         * Reset the win pos and size to default. Don't forget to set defaults
404
         * first.
405
         */
406
        virtual void resetToDefaultSize();
407
408
        /**
409
         * Adjusts the window position after the application window has been
410
         * resized.
411
         */
412
        void adjustPositionAfterResize(const int oldScreenWidth,
413
                                       const int oldScreenHeight);
414
415
        /**
416
         * Gets the layout handler for this window.
417
         */
418
        Layout &getLayout() A_WARN_UNUSED;
419
420
        /**
421
         * Clears the window's layout (useful for redesigning the window). Does
422
         * not delete the widgets!
423
         */
424
        void clearLayout();
425
426
        /**
427
         * Computes the position of the widgets according to the current
428
         * layout. Resizes the window so that the layout fits. Deletes the
429
         * layout.
430
         * @param w if non-zero, force the window to this width.
431
         * @param h if non-zero, force the window to this height.
432
         * @note This function is meant to be called with fixed-size windows.
433
         */
434
        void reflowLayout(int w,
435
                          int h);
436
437
        /**
438
         * Adds a widget to the window and sets it at given cell.
439
         */
440
        LayoutCell &place(const int x,
441
                          const int y,
442
                          Widget *const wg,
443
                          const int w,
444
                          const int h);
445
446
        /**
447
         * Returns a proxy for adding widgets in an inner table of the layout.
448
         */
449
        ContainerPlacer getPlacer(const int x, const int y) A_WARN_UNUSED;
450
451
        /**
452
         * Positions the window in the center of it's parent.
453
         */
454
        void center();
455
456
        /**
457
         * Positions the window in the horisontal center of it's parent.
458
         */
459
        void centerHorisontally();
460
461
        /**
462
         * Overrideable functionality for when the window is to close. This
463
         * allows for class implementations to clean up or do certain actions
464
         * on window close they couldn't do otherwise.
465
         */
466
        virtual void close();
467
468
         /**
469
         * Allows the windows modal status to change
470
         */
471
        void setModal(const Modal modal);
472
473
        Rect getWindowArea() const A_WARN_UNUSED;
474
475
        bool isResizeAllowed(const MouseEvent &event) const A_WARN_UNUSED;
476
477
        void setCaptionFont(Font *font)
478
        { mCaptionFont = font; }
479
480
        void enableVisibleSound(bool b)
481
44
        { mPlayVisibleSound = b; }
482
483
        bool isWindowVisible() const noexcept2 A_WARN_UNUSED
484
16
        { return mVisible == Visible_true; }
485
486
        /**
487
         * Sets the padding of the window. The padding is the distance between the
488
         * window border and the content.
489
         *
490
         * @param padding The padding of the window.
491
         * @see getPadding
492
         */
493
        void setPadding(int padding)
494
126
        { mPadding = padding; }
495
496
        /**
497
         * Gets the padding of the window. The padding is the distance between the
498
         * window border and the content.
499
         *
500
         * @return The padding of the window.
501
         * @see setPadding
502
         */
503
        int getPadding() const
504
        { return mPadding; }
505
506
        /**
507
         * Sets the title bar height.
508
         *
509
         * @param height The title height value.
510
         * @see getTitleBarHeight
511
         */
512
        void setTitleBarHeight(unsigned int height)
513
131
        { mTitleBarHeight = height; }
514
515
        /**
516
         * Gets the title bar height.
517
         *
518
         * @return The title bar height.
519
         * @see setTitleBarHeight
520
         */
521
        unsigned int getTitleBarHeight() const
522
        { return mTitleBarHeight; }
523
524
        /**
525
         * Sets the caption of the window.
526
         *
527
         * @param caption The caption of the window.
528
         * @see getCaption
529
         */
530
        void setCaption(const std::string& caption)
531
14
        { mCaption = caption; mTextChanged = true; }
532
533
        /**
534
         * Gets the caption of the window.
535
         *
536
         * @return the caption of the window.
537
         * @see setCaption
538
         */
539
        const std::string& getCaption() const
540
1
        { return mCaption; }
541
542
        /**
543
         * Sets the alignment of the caption.
544
         *
545
         * @param alignment The alignment of the caption.
546
         * @see getAlignment, Graphics
547
         */
548
        void setAlignment(Graphics::Alignment alignment)
549
        { mAlignment = alignment; }
550
551
        /**
552
         * Gets the alignment of the caption.
553
         *
554
         * @return The alignment of caption.
555
         * @see setAlignment, Graphics
556
         */
557
        Graphics::Alignment getAlignment() const
558
        { return mAlignment; }
559
560
        /**
561
         * Sets the window to be moveble or not.
562
         *
563
         * @param movable True if the window should be movable, false otherwise.
564
         * @see isMovable
565
         */
566
        void setMovable(Move movable)
567
1
        { mMovable = movable; }
568
569
        /**
570
         * Checks if the window is movable.
571
         *
572
         * @return True if the window is movable, false otherwise.
573
         * @see setMovable
574
         */
575
        bool isMovable() const
576
        { return mMovable == Move_true; }
577
578
        Rect getChildrenArea() override;
579
580
        /**
581
         * Resizes the window to fit the content.
582
         */
583
        virtual void resizeToContent();
584
585
#ifdef USE_PROFILER
586
        virtual void logic();
587
#endif  // USE_PROFILER
588
589
    protected:
590
        bool canMove() const A_WARN_UNUSED;
591
592
        int getOption(const std::string &name,
593
                      const int def) const A_WARN_UNUSED;
594
595
        bool getOptionBool(const std::string &name,
596
                           const bool def) const A_WARN_UNUSED;
597
598
        void setTitlePadding(const int p) noexcept2
599
        { mTitlePadding = p; }
600
601
        int getTitlePadding() const noexcept2 A_WARN_UNUSED
602
5
        { return mTitlePadding; }
603
604
        /**
605
         * Holds the caption of the window.
606
         */
607
        std::string mCaption;
608
609
        /**
610
         * Holds the alignment of the caption.
611
         */
612
        Graphics::Alignment mAlignment;
613
614
        /**
615
         * Holds the padding of the window.
616
         */
617
        int mPadding;
618
619
        /**
620
         * Holds the title bar height of the window.
621
         */
622
        unsigned int mTitleBarHeight;
623
624
        /**
625
         * True if the window is movable, false otherwise.
626
         */
627
        Move mMovable;
628
629
        /**
630
         * Holds a drag offset as an x 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 mDragOffsetX;
635
636
        /**
637
         * Holds a drag offset as an y coordinate where the drag of the window
638
         * started if the window is being dragged. It's used to move the window
639
         * correctly when dragged.
640
         */
641
        int mDragOffsetY;
642
643
        /**
644
         * True if the window is being moved, false otherwise.
645
         */
646
        bool mMoved;
647
648
        Skin *mSkin;                  /**< Skin in use by this window */
649
        int mDefaultX;                /**< Default window X position */
650
        int mDefaultY;                /**< Default window Y position */
651
        int mDefaultWidth;            /**< Default window width */
652
        int mDefaultHeight;           /**< Default window height */
653
        int mCaptionOffsetX;
654
        int mCaptionOffsetY;
655
        bool mShowTitle;              /**< Window has a title bar */
656
        bool mLastRedraw;
657
658
    private:
659
        enum ResizeHandles
660
        {
661
            TOP    = 0x01,
662
            RIGHT  = 0x02,
663
            BOTTOM = 0x04,
664
            LEFT   = 0x08,
665
            CLOSE  = 0x10
666
        };
667
668
        /**
669
         * Ensures the window is on the screen, moving it if necessary. This is
670
         * used by loadWindowState and setVisible(true), and when the screen
671
         * is resized.
672
         */
673
        void ensureOnScreen();
674
675
        void adjustSizeToScreen();
676
677
        /**
678
         * Determines if the mouse is in a resize area and returns appropriate
679
         * resize handles. Also initializes drag offset in case the resize
680
         * grip is used.
681
         *
682
         * @see ResizeHandles
683
         */
684
        int getResizeHandles(const MouseEvent &event) A_WARN_UNUSED;
685
686
        Image *mGrip;                 /**< Resize grip */
687
        Window *mParentWindow;        /**< The parent window */
688
        Layout *mLayout;              /**< Layout handler */
689
        Rect mCloseRect;    /**< Close button rectangle */
690
        Rect mStickyRect;   /**< Sticky button rectangle */
691
        Rect mGripRect;     /**< Resize grip rectangle */
692
        TextChunk mTextChunk;
693
        std::string mWindowName;      /**< Name of the window */
694
        int mMinWinWidth;             /**< Minimum window width */
695
        int mMinWinHeight;            /**< Minimum window height */
696
        int mMaxWinWidth;             /**< Maximum window width */
697
        int mMaxWinHeight;            /**< Maximum window height */
698
699
        static int mouseResize;       /**< Active resize handles */
700
        static int windowInstances;   /**< Number of Window instances */
701
702
703
        /**
704
         * The width of the resize border. Is independent of the actual window
705
         * border width, and determines mostly the size of the corner area
706
         * where two borders are moved at the same time.
707
         */
708
        static const unsigned resizeBorderWidth = 10;
709
        ImageCollection *mVertexes A_NONNULLPOINTER;
710
        Graphics::Alignment mCaptionAlign;
711
        int mTitlePadding;
712
        int mGripPadding;
713
        int mResizeHandles;
714
        int mOldResizeHandles;
715
        int mClosePadding;
716
        int mStickySpacing;
717
        int mStickyPadding;
718
        Font *mCaptionFont A_NONNULLPOINTER;
719
        Modal mModal;                 /**< Window is modal */
720
        bool mCloseWindowButton;      /**< Window has a close button */
721
        bool mDefaultVisible;         /**< Window's default visibility */
722
        bool mSaveVisible;            /**< Window will save visibility */
723
        bool mStickyButton;           /**< Window has a sticky button */
724
        bool mSticky;                 /**< Window resists hiding*/
725
        bool mStickyButtonLock;       /**< Window locked if sticky enabled*/
726
        bool mPlayVisibleSound;
727
        bool mInit;
728
        bool mTextChanged;
729
        bool mAllowClose;
730
};
731
732
#endif  // GUI_WIDGETS_WINDOW_H