1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #ifndef INCLUDED_VCL_LAYOUT_HXX
11 #define INCLUDED_VCL_LAYOUT_HXX
12 
13 #include <vcl/dllapi.h>
14 #include <vcl/button.hxx>
15 #include <vcl/help.hxx>
16 #include <vcl/scrbar.hxx>
17 #include <vcl/split.hxx>
18 #include <vcl/svapp.hxx>
19 #include <vcl/window.hxx>
20 #include <vcl/settings.hxx>
21 #include <vcl/event.hxx>
22 #include <vcl/vclptr.hxx>
23 #include <vcl/IContext.hxx>
24 #include <vcl/commandevent.hxx>
25 #include <set>
26 
27 class VCL_DLLPUBLIC VclContainer : public vcl::Window,
28                                    public vcl::IContext
29 {
30 public:
31     VclContainer(vcl::Window *pParent, WinBits nStyle = WB_HIDE | WB_CLIPCHILDREN);
32 
33     //These take into account the external margins of the rWindow widget
34     //while GetOptimalSize/get_preferred_size and SetPosSizePixel are
35     //oblivious to them
36     static Size getLayoutRequisition(const vcl::Window &rWindow);
37     static void setLayoutPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize);
38 
39     //applies the allocation pos and size onto rWindow via setLayoutPosSize taking into account
40     //the rWindows alignment desires within that allocation
41     static void setLayoutAllocation(vcl::Window &rWindow, const Point &rPos, const Size &rSize);
42 
43     virtual void queue_resize(StateChangedType eReason = StateChangedType::Layout) override;
44 protected:
45     //these are the two that need to be implemented by
46     //containers, figure out how much space you want...
47     virtual Size calculateRequisition() const = 0;
48     //..and decide what to do when set to this size
49     virtual void setAllocation(const Size &rAllocation) = 0;
50 
51     virtual sal_uInt16 getDefaultAccessibleRole() const override;
52 
53     // support for screenshot context menu
54     virtual void Command(const CommandEvent& rCEvt) override;
55 
56 public:
57     //you don't want to override these
58     virtual Size GetOptimalSize() const override;
59     virtual void SetPosSizePixel(const Point& rNewPos, const Size& rNewSize) override;
60     virtual void SetPosPixel(const Point& rAllocPos) override;
61     virtual void SetSizePixel(const Size& rAllocation) override;
62 private:
63     bool m_bLayoutDirty;
64 };
65 
66 class VCL_DLLPUBLIC VclBox : public VclContainer
67 {
68 protected:
69     bool m_bHomogeneous;
70     bool m_bVerticalContainer;
71     int m_nSpacing;
72 public:
VclBox(vcl::Window * pParent,bool bHomogeneous,int nSpacing)73     VclBox(vcl::Window *pParent, bool bHomogeneous, int nSpacing)
74         : VclContainer(pParent)
75         , m_bHomogeneous(bHomogeneous)
76         , m_bVerticalContainer(false)
77         , m_nSpacing(nSpacing)
78     {
79     }
set_spacing(int nSpacing)80     void set_spacing(int nSpacing)
81     {
82         m_nSpacing = nSpacing;
83     }
get_spacing() const84     int get_spacing() const
85     {
86         return m_nSpacing;
87     }
set_homogeneous(bool bHomogeneous)88     void set_homogeneous(bool bHomogeneous)
89     {
90         m_bHomogeneous = bHomogeneous;
91     }
92     virtual bool set_property(const OString &rKey, const OUString &rValue) override;
93     virtual boost::property_tree::ptree DumpAsPropertyTree() override;
94 protected:
95     virtual sal_uInt16 getDefaultAccessibleRole() const override;
96     void accumulateMaxes(const Size &rChildSize, Size &rSize) const;
97     Size finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const;
98 
99     virtual Size calculateRequisition() const override;
100     virtual void setAllocation(const Size &rAllocation) override;
101 
102     virtual long getPrimaryDimension(const Size &rSize) const = 0;
103     virtual void setPrimaryDimension(Size &rSize, long) const = 0;
104     virtual long getPrimaryCoordinate(const Point &rPos) const = 0;
105     virtual void setPrimaryCoordinate(Point &rPos, long) const = 0;
106     virtual long getSecondaryDimension(const Size &rSize) const = 0;
107     virtual void setSecondaryDimension(Size &rSize, long) const = 0;
108 
109     virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const = 0;
110 };
111 
112 class VCL_DLLPUBLIC VclVBox : public VclBox
113 {
114 public:
VclVBox(vcl::Window * pParent,bool bHomogeneous=false,int nSpacing=0)115     VclVBox(vcl::Window *pParent, bool bHomogeneous = false, int nSpacing = 0)
116         : VclBox(pParent, bHomogeneous, nSpacing)
117     {
118         m_bVerticalContainer = true;
119     }
120 protected:
getPrimaryDimension(const Size & rSize) const121     virtual long getPrimaryDimension(const Size &rSize) const override
122     {
123         return rSize.getHeight();
124     }
setPrimaryDimension(Size & rSize,long nHeight) const125     virtual void setPrimaryDimension(Size &rSize, long nHeight) const override
126     {
127         rSize.setHeight(nHeight);
128     }
getPrimaryCoordinate(const Point & rPos) const129     virtual long getPrimaryCoordinate(const Point &rPos) const override
130     {
131         return rPos.getY();
132     }
setPrimaryCoordinate(Point & rPos,long nPos) const133     virtual void setPrimaryCoordinate(Point &rPos, long nPos) const override
134     {
135         rPos.setY(nPos);
136     }
getSecondaryDimension(const Size & rSize) const137     virtual long getSecondaryDimension(const Size &rSize) const override
138     {
139         return rSize.getWidth();
140     }
setSecondaryDimension(Size & rSize,long nWidth) const141     virtual void setSecondaryDimension(Size &rSize, long nWidth) const override
142     {
143         rSize.setWidth(nWidth);
144     }
getPrimaryDimensionChildExpand(const vcl::Window & rWindow) const145     virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const override
146     {
147         return rWindow.get_expand() || rWindow.get_vexpand();
148     }
149 };
150 
151 class VCL_DLLPUBLIC VclHBox : public VclBox
152 {
153 public:
VclHBox(vcl::Window * pParent,bool bHomogeneous=false,int nSpacing=0)154     VclHBox(vcl::Window *pParent, bool bHomogeneous = false, int nSpacing = 0)
155         : VclBox(pParent, bHomogeneous, nSpacing)
156     {
157         m_bVerticalContainer = false;
158     }
159 protected:
getPrimaryDimension(const Size & rSize) const160     virtual long getPrimaryDimension(const Size &rSize) const override
161     {
162         return rSize.getWidth();
163     }
setPrimaryDimension(Size & rSize,long nWidth) const164     virtual void setPrimaryDimension(Size &rSize, long nWidth) const override
165     {
166         rSize.setWidth(nWidth);
167     }
getPrimaryCoordinate(const Point & rPos) const168     virtual long getPrimaryCoordinate(const Point &rPos) const override
169     {
170         return rPos.getX();
171     }
setPrimaryCoordinate(Point & rPos,long nPos) const172     virtual void setPrimaryCoordinate(Point &rPos, long nPos) const override
173     {
174         rPos.setX(nPos);
175     }
getSecondaryDimension(const Size & rSize) const176     virtual long getSecondaryDimension(const Size &rSize) const override
177     {
178         return rSize.getHeight();
179     }
setSecondaryDimension(Size & rSize,long nHeight) const180     virtual void setSecondaryDimension(Size &rSize, long nHeight) const override
181     {
182         rSize.setHeight(nHeight);
183     }
getPrimaryDimensionChildExpand(const vcl::Window & rWindow) const184     virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const override
185     {
186         return rWindow.get_expand() || rWindow.get_hexpand();
187     }
188 };
189 
190 enum class VclButtonBoxStyle
191 {
192     Default,
193     Spread,
194     Edge,
195     Start,
196     End,
197     Center
198 };
199 
200 class VCL_DLLPUBLIC VclButtonBox : public VclBox
201 {
202 public:
VclButtonBox(vcl::Window * pParent)203     VclButtonBox(vcl::Window *pParent)
204         : VclBox(pParent, false, Application::GetSettings().GetStyleSettings().GetDialogStyle().button_spacing)
205         , m_eLayoutStyle(VclButtonBoxStyle::Default)
206     {
207     }
208     virtual bool set_property(const OString &rKey, const OUString &rValue) override;
209     void sort_native_button_order();
210 protected:
211     virtual Size calculateRequisition() const override;
212     virtual void setAllocation(const Size &rAllocation) override;
213     Size addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const;
214 private:
215     VclButtonBoxStyle m_eLayoutStyle;
216     struct Requisition
217     {
218         std::vector<long> m_aMainGroupDimensions;
219         std::vector<long> m_aSubGroupDimensions;
220         Size m_aMainGroupSize;
221         Size m_aSubGroupSize;
222     };
223     Requisition calculatePrimarySecondaryRequisitions() const;
224     Size addReqGroups(const VclButtonBox::Requisition &rReq) const;
225 };
226 
227 class VCL_DLLPUBLIC VclVButtonBox : public VclButtonBox
228 {
229 public:
VclVButtonBox(vcl::Window * pParent)230     VclVButtonBox(vcl::Window *pParent)
231         : VclButtonBox(pParent)
232     {
233         m_bVerticalContainer = true;
234     }
235 protected:
getPrimaryDimension(const Size & rSize) const236     virtual long getPrimaryDimension(const Size &rSize) const override
237     {
238         return rSize.getHeight();
239     }
setPrimaryDimension(Size & rSize,long nHeight) const240     virtual void setPrimaryDimension(Size &rSize, long nHeight) const override
241     {
242         rSize.setHeight(nHeight);
243     }
getPrimaryCoordinate(const Point & rPos) const244     virtual long getPrimaryCoordinate(const Point &rPos) const override
245     {
246         return rPos.getY();
247     }
setPrimaryCoordinate(Point & rPos,long nPos) const248     virtual void setPrimaryCoordinate(Point &rPos, long nPos) const override
249     {
250         rPos.setY(nPos);
251     }
getSecondaryDimension(const Size & rSize) const252     virtual long getSecondaryDimension(const Size &rSize) const override
253     {
254         return rSize.getWidth();
255     }
setSecondaryDimension(Size & rSize,long nWidth) const256     virtual void setSecondaryDimension(Size &rSize, long nWidth) const override
257     {
258         rSize.setWidth(nWidth);
259     }
getPrimaryDimensionChildExpand(const vcl::Window & rWindow) const260     virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const override
261     {
262         return rWindow.get_expand() || rWindow.get_vexpand();
263     }
264 };
265 
266 class VCL_DLLPUBLIC VclHButtonBox final : public VclButtonBox
267 {
268 public:
VclHButtonBox(vcl::Window * pParent)269     VclHButtonBox(vcl::Window *pParent)
270         : VclButtonBox(pParent)
271     {
272         m_bVerticalContainer = false;
273     }
274 private:
getPrimaryDimension(const Size & rSize) const275     virtual long getPrimaryDimension(const Size &rSize) const override
276     {
277         return rSize.getWidth();
278     }
setPrimaryDimension(Size & rSize,long nWidth) const279     virtual void setPrimaryDimension(Size &rSize, long nWidth) const override
280     {
281         rSize.setWidth(nWidth);
282     }
getPrimaryCoordinate(const Point & rPos) const283     virtual long getPrimaryCoordinate(const Point &rPos) const override
284     {
285         return rPos.getX();
286     }
setPrimaryCoordinate(Point & rPos,long nPos) const287     virtual void setPrimaryCoordinate(Point &rPos, long nPos) const override
288     {
289         rPos.setX(nPos);
290     }
getSecondaryDimension(const Size & rSize) const291     virtual long getSecondaryDimension(const Size &rSize) const override
292     {
293         return rSize.getHeight();
294     }
setSecondaryDimension(Size & rSize,long nHeight) const295     virtual void setSecondaryDimension(Size &rSize, long nHeight) const override
296     {
297         rSize.setHeight(nHeight);
298     }
getPrimaryDimensionChildExpand(const vcl::Window & rWindow) const299     virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const override
300     {
301         return rWindow.get_expand() || rWindow.get_hexpand();
302     }
303 };
304 
305 class VCL_DLLPUBLIC VclGrid final : public VclContainer
306 {
307 private:
308     bool m_bRowHomogeneous;
309     bool m_bColumnHomogeneous;
310     int m_nRowSpacing;
311     int m_nColumnSpacing;
312 
313 public:
314     struct Value
315     {
316         long m_nValue;
317         bool m_bExpand;
ValueVclGrid::Value318         Value() : m_nValue(0), m_bExpand(false) {}
319     };
320 private:
321 
322     Size calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const;
323     virtual Size calculateRequisition() const override;
324     virtual void setAllocation(const Size &rAllocation) override;
325     virtual boost::property_tree::ptree DumpAsPropertyTree() override;
326 public:
VclGrid(vcl::Window * pParent)327     VclGrid(vcl::Window *pParent)
328         : VclContainer(pParent)
329         , m_bRowHomogeneous(false), m_bColumnHomogeneous(false)
330         , m_nRowSpacing(0), m_nColumnSpacing(0)
331     {
332     }
get_row_homogeneous() const333     bool get_row_homogeneous() const
334     {
335         return m_bRowHomogeneous;
336     }
get_column_homogeneous() const337     bool get_column_homogeneous() const
338     {
339         return m_bColumnHomogeneous;
340     }
set_row_spacing(int nSpacing)341     void set_row_spacing(int nSpacing)
342     {
343         m_nRowSpacing = nSpacing;
344     }
set_column_spacing(int nSpacing)345     void set_column_spacing(int nSpacing)
346     {
347         m_nColumnSpacing = nSpacing;
348     }
get_row_spacing() const349     int get_row_spacing() const
350     {
351         return m_nRowSpacing;
352     }
get_column_spacing() const353     int get_column_spacing() const
354     {
355         return m_nColumnSpacing;
356     }
357     virtual bool set_property(const OString &rKey, const OUString &rValue) override;
358 };
359 
360 class VCL_DLLPUBLIC VclBin : public VclContainer
361 {
362 public:
VclBin(vcl::Window * pParent,WinBits nStyle=WB_HIDE|WB_CLIPCHILDREN)363     VclBin(vcl::Window *pParent, WinBits nStyle = WB_HIDE | WB_CLIPCHILDREN)
364         : VclContainer(pParent, nStyle)
365     {
366     }
367     virtual vcl::Window *get_child();
368     virtual const vcl::Window *get_child() const;
369     virtual Size calculateRequisition() const override;
370     virtual void setAllocation(const Size &rAllocation) override;
371 };
372 
373 class VCL_DLLPUBLIC VclPaned : public VclContainer
374 {
375 protected:
376     VclPtr<Splitter> m_pSplitter;
377     long m_nPosition;
378 
379     VclPaned(vcl::Window *pParent, bool bVertical);
380 public:
~VclPaned()381     virtual ~VclPaned() override { disposeOnce(); }
382     virtual void dispose() override;
get_position() const383     long get_position() const { return m_nPosition; }
set_position(long nPosition)384     void set_position(long nPosition) { m_nPosition = nPosition; }
385 };
386 
387 class VCL_DLLPUBLIC VclVPaned final : public VclPaned
388 {
389 private:
390     DECL_LINK(SplitHdl, Splitter*, void);
391     void arrange(const Size& rAllocation, long nFirstHeight, long nSecondHeight);
392 
393 public:
394     VclVPaned(vcl::Window *pParent);
395     virtual Size calculateRequisition() const override;
396     virtual void setAllocation(const Size &rAllocation) override;
397 };
398 
399 class VCL_DLLPUBLIC VclHPaned final : public VclPaned
400 {
401 private:
402     DECL_LINK(SplitHdl, Splitter*, void);
403     void arrange(const Size& rAllocation, long nFirstHeight, long nSecondHeight);
404 
405 public:
406     VclHPaned(vcl::Window *pParent);
407     virtual Size calculateRequisition() const override;
408     virtual void setAllocation(const Size &rAllocation) override;
409 };
410 
411 class VCL_DLLPUBLIC VclFrame final : public VclBin
412 {
413 private:
414     VclPtr<vcl::Window> m_pLabel;
415 private:
416     friend class VclBuilder;
417     void designate_label(vcl::Window *pWindow);
418     DECL_LINK(WindowEventListener, VclWindowEvent&, void);
419 public:
VclFrame(vcl::Window * pParent)420     VclFrame(vcl::Window *pParent)
421         : VclBin(pParent)
422         , m_pLabel(nullptr)
423     {
424     }
425     virtual ~VclFrame() override;
426     virtual void dispose() override;
427     void set_label(const OUString &rLabel);
428     OUString get_label() const;
429     virtual vcl::Window *get_child() override;
430     virtual const vcl::Window *get_child() const override;
431     vcl::Window *get_label_widget();
432     const vcl::Window *get_label_widget() const;
433     virtual boost::property_tree::ptree DumpAsPropertyTree() override;
434 private:
435     virtual Size calculateRequisition() const override;
436     virtual void setAllocation(const Size &rAllocation) override;
437     virtual OUString getDefaultAccessibleName() const override;
438 };
439 
440 class VCL_DLLPUBLIC VclAlignment final : public VclBin
441 {
442 public:
VclAlignment(vcl::Window * pParent)443     VclAlignment(vcl::Window *pParent)
444         : VclBin(pParent)
445         , m_nBottomPadding(0)
446         , m_nLeftPadding(0)
447         , m_nRightPadding(0)
448         , m_nTopPadding(0)
449     {
450     }
451     virtual bool set_property(const OString &rKey, const OUString &rValue) override;
452 private:
453     virtual Size calculateRequisition() const override;
454     virtual void setAllocation(const Size &rAllocation) override;
455     sal_Int32 m_nBottomPadding;
456     sal_Int32 m_nLeftPadding;
457     sal_Int32 m_nRightPadding;
458     sal_Int32 m_nTopPadding;
459 };
460 
461 class VCL_DLLPUBLIC VclExpander final : public VclBin
462 {
463 public:
VclExpander(vcl::Window * pParent)464     VclExpander(vcl::Window *pParent)
465         : VclBin(pParent)
466         , m_bResizeTopLevel(true)
467         , m_pDisclosureButton(VclPtr<DisclosureButton>::Create(this))
468     {
469         m_pDisclosureButton->SetToggleHdl(LINK(this, VclExpander, ClickHdl));
470         m_pDisclosureButton->Show();
471     }
~VclExpander()472     virtual ~VclExpander() override { disposeOnce(); }
473     virtual void dispose() override;
474     virtual vcl::Window *get_child() override;
475     virtual const vcl::Window *get_child() const override;
476     virtual bool set_property(const OString &rKey, const OUString &rValue) override;
get_expanded() const477     bool get_expanded() const
478     {
479         return m_pDisclosureButton->IsChecked();
480     }
set_expanded(bool bExpanded)481     void set_expanded(bool bExpanded)
482     {
483         m_pDisclosureButton->Check(bExpanded);
484     }
set_label(const OUString & rLabel)485     void set_label(const OUString& rLabel)
486     {
487         m_pDisclosureButton->SetText(rLabel);
488     }
489     virtual void StateChanged(StateChangedType nType) override;
SetExpandedHdl(const Link<VclExpander &,void> & rLink)490     void  SetExpandedHdl( const Link<VclExpander&,void>& rLink ) { maExpandedHdl = rLink; }
491 private:
492     virtual Size calculateRequisition() const override;
493     virtual void setAllocation(const Size &rAllocation) override;
494     bool m_bResizeTopLevel;
495     VclPtr<DisclosureButton> m_pDisclosureButton;
496     Link<VclExpander&,void> maExpandedHdl;
497     DECL_DLLPRIVATE_LINK(ClickHdl, CheckBox&, void);
498 };
499 
500 class VCL_DLLPUBLIC VclScrolledWindow final : public VclBin
501 {
502 public:
503     VclScrolledWindow(vcl::Window *pParent );
~VclScrolledWindow()504     virtual ~VclScrolledWindow() override { disposeOnce(); }
505     virtual void dispose() override;
506     virtual vcl::Window *get_child() override;
507     virtual const vcl::Window *get_child() const override;
508     virtual bool set_property(const OString &rKey, const OUString &rValue) override;
509     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
getVertScrollBar()510     ScrollBar& getVertScrollBar() { return *m_pVScroll; }
getHorzScrollBar()511     ScrollBar& getHorzScrollBar() { return *m_pHScroll; }
512     Size getVisibleChildSize() const;
513     //set to true to disable the built-in scrolling callbacks to allow the user
514     //to override it
setUserManagedScrolling(bool bUserManagedScrolling)515     void setUserManagedScrolling(bool bUserManagedScrolling) { m_bUserManagedScrolling = bUserManagedScrolling;}
516     void doSetAllocation(const Size &rAllocation, bool bRetryOnFailure);
517 private:
518     virtual Size calculateRequisition() const override;
519     virtual void setAllocation(const Size &rAllocation) override;
520     DECL_LINK(ScrollBarHdl, ScrollBar*, void);
521     void InitScrollBars(const Size &rRequest);
522     virtual bool EventNotify(NotifyEvent& rNEvt) override;
523     bool m_bUserManagedScrolling;
524     VclPtr<ScrollBar> m_pVScroll;
525     VclPtr<ScrollBar> m_pHScroll;
526     VclPtr<ScrollBarBox> m_aScrollBarBox;
527 };
528 
529 class VCL_DLLPUBLIC VclViewport final : public VclBin
530 {
531 public:
VclViewport(vcl::Window * pParent)532     VclViewport(vcl::Window *pParent)
533         : VclBin(pParent, WB_HIDE | WB_CLIPCHILDREN)
534         , m_bInitialAllocation(true)
535     {
536     }
537 private:
538     virtual void setAllocation(const Size &rAllocation) override;
539     bool m_bInitialAllocation;
540 };
541 
542 //Enforces that its children are always the same size as itself.
543 //Intercepts any Commands intended for its children.
544 //
545 //by default the Commands are discarded, inherit from this
546 //and implement "Command" to get them
547 class VCL_DLLPUBLIC VclEventBox final : public VclBin
548 {
549 private:
550     //Any Commands an EventBoxHelper receives are forwarded to its parent
551     //The VclEventBox ensures that m_aEventBoxHelper is the
552     //first child and is transparent, but covers the rest of the children
553     class EventBoxHelper : public vcl::Window
554     {
555     public:
EventBoxHelper(vcl::Window * pParent)556         EventBoxHelper(vcl::Window* pParent)
557             : Window(pParent, 0)
558         {
559             SetSizePixel(pParent->GetSizePixel());
560             EnableChildTransparentMode();
561             SetPaintTransparent(true);
562             SetBackground();
563         }
Command(const CommandEvent & rCEvt)564         virtual void Command(const CommandEvent& rCEvt) override
565         {
566             GetParent()->Command(rCEvt);
567         }
568     };
569 
570     VclPtr<EventBoxHelper> m_aEventBoxHelper;
571     virtual void dispose() override;
572     virtual ~VclEventBox() override;
573 public:
VclEventBox(vcl::Window * pParent)574     VclEventBox(vcl::Window* pParent)
575         : VclBin(pParent)
576         , m_aEventBoxHelper(VclPtr<EventBoxHelper>::Create(this))
577     {
578         m_aEventBoxHelper->Show();
579     }
580     virtual vcl::Window *get_child() override;
581     virtual const vcl::Window *get_child() const override;
582     virtual Size calculateRequisition() const override;
583     virtual void setAllocation(const Size &rAllocation) override;
584 
585     virtual void Command(const CommandEvent& rCEvt) override;
586 };
587 
588 class VCL_DLLPUBLIC VclSizeGroup
589 {
590 private:
591     std::set< VclPtr<vcl::Window> > m_aWindows;
592     bool m_bIgnoreHidden;
593     VclSizeGroupMode m_eMode;
594 
595     void trigger_queue_resize();
596 public:
VclSizeGroup()597     VclSizeGroup()
598         : m_bIgnoreHidden(false)
599         , m_eMode(VclSizeGroupMode::Horizontal)
600     {
601     }
insert(vcl::Window * pWindow)602     void insert(vcl::Window *pWindow)
603     {
604         m_aWindows.insert(VclPtr<vcl::Window>(pWindow));
605     }
erase(vcl::Window * pWindow)606     void erase(vcl::Window *pWindow)
607     {
608         m_aWindows.erase(VclPtr<vcl::Window>(pWindow));
609     }
get_widgets() const610     const std::set< VclPtr<vcl::Window> >& get_widgets() const
611     {
612         return m_aWindows;
613     }
get_widgets()614     std::set< VclPtr<vcl::Window> >& get_widgets()
615     {
616         return m_aWindows;
617     }
618     void set_ignore_hidden(bool bIgnoreHidden);
get_ignore_hidden() const619     bool get_ignore_hidden() const
620     {
621         return m_bIgnoreHidden;
622     }
623     void set_mode(VclSizeGroupMode eMode);
get_mode() const624     VclSizeGroupMode get_mode() const
625     {
626         return m_eMode;
627     }
628     void set_property(const OString &rKey, const OUString &rValue);
629 };
630 
631 class VCL_DLLPUBLIC VclDrawingArea final : public Control
632 {
633 private:
634     FactoryFunction m_pFactoryFunction;
635     void* m_pUserData;
636     Link<std::pair<vcl::RenderContext&, const tools::Rectangle&>, void> m_aPaintHdl;
637     Link<const Size&, void> m_aResizeHdl;
638     Link<const MouseEvent&, bool> m_aMousePressHdl;
639     Link<const MouseEvent&, bool> m_aMouseMotionHdl;
640     Link<const MouseEvent&, bool> m_aMouseReleaseHdl;
641     Link<const KeyEvent&, bool> m_aKeyPressHdl;
642     Link<const KeyEvent&, bool> m_aKeyReleaseHdl;
643     Link<VclDrawingArea&, void> m_aStyleUpdatedHdl;
644     Link<const CommandEvent&, bool> m_aCommandHdl;
645     Link<tools::Rectangle&, OUString> m_aQueryTooltipHdl;
646 
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle & rRect)647     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override
648     {
649         m_aPaintHdl.Call(std::pair<vcl::RenderContext&, const tools::Rectangle&>(rRenderContext, rRect));
650     }
Resize()651     virtual void Resize() override
652     {
653         m_aResizeHdl.Call(GetOutputSizePixel());
654     }
MouseMove(const MouseEvent & rMEvt)655     virtual void MouseMove(const MouseEvent& rMEvt) override
656     {
657         if (!m_aMouseMotionHdl.Call(rMEvt))
658             Control::MouseMove(rMEvt);
659     }
MouseButtonDown(const MouseEvent & rMEvt)660     virtual void MouseButtonDown(const MouseEvent& rMEvt) override
661     {
662         if (!m_aMousePressHdl.Call(rMEvt))
663             Control::MouseButtonDown(rMEvt);
664     }
MouseButtonUp(const MouseEvent & rMEvt)665     virtual void MouseButtonUp(const MouseEvent& rMEvt) override
666     {
667         if (!m_aMouseReleaseHdl.Call(rMEvt))
668             Control::MouseButtonUp(rMEvt);
669     }
KeyInput(const KeyEvent & rKEvt)670     virtual void KeyInput(const KeyEvent& rKEvt) override
671     {
672         if (!m_aKeyPressHdl.Call(rKEvt))
673             Control::KeyInput(rKEvt);
674 
675     }
KeyUp(const KeyEvent & rKEvt)676     virtual void KeyUp(const KeyEvent& rKEvt) override
677     {
678         if (!m_aKeyReleaseHdl.Call(rKEvt))
679             Control::KeyUp(rKEvt);
680     }
StateChanged(StateChangedType nType)681     virtual void StateChanged(StateChangedType nType) override
682     {
683         Control::StateChanged(nType);
684         if (nType == StateChangedType::ControlForeground || nType == StateChangedType::ControlBackground)
685         {
686             m_aStyleUpdatedHdl.Call(*this);
687             Invalidate();
688         }
689     }
DataChanged(const DataChangedEvent & rDCEvt)690     virtual void DataChanged(const DataChangedEvent& rDCEvt) override
691     {
692         Control::DataChanged(rDCEvt);
693         if ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
694         {
695             m_aStyleUpdatedHdl.Call(*this);
696             Invalidate();
697         }
698     }
Command(const CommandEvent & rEvent)699     virtual void Command(const CommandEvent& rEvent) override
700     {
701         if (m_aCommandHdl.Call(rEvent))
702             return;
703         Control::Command(rEvent);
704     }
RequestHelp(const HelpEvent & rHelpEvent)705     virtual void RequestHelp(const HelpEvent& rHelpEvent) override
706     {
707         if (rHelpEvent.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON))
708         {
709             Point aPos(ScreenToOutputPixel(rHelpEvent.GetMousePosPixel()));
710             tools::Rectangle aHelpArea(aPos.X(), aPos.Y());
711             OUString sHelpTip = m_aQueryTooltipHdl.Call(aHelpArea);
712             if (sHelpTip.isEmpty())
713                 return;
714             Point aPt = OutputToScreenPixel(aHelpArea.TopLeft());
715             aHelpArea.SetLeft(aPt.X());
716             aHelpArea.SetTop(aPt.Y());
717             aPt = OutputToScreenPixel(aHelpArea.BottomRight());
718             aHelpArea.SetRight(aPt.X());
719             aHelpArea.SetBottom(aPt.Y());
720             // tdf#125369 recover newline support of tdf#101779
721             QuickHelpFlags eHelpWinStyle = sHelpTip.indexOf('\n') != -1 ? QuickHelpFlags::TipStyleBalloon : QuickHelpFlags::NONE;
722             Help::ShowQuickHelp(this, aHelpArea, sHelpTip, eHelpWinStyle);
723         }
724     }
GetUITestFactory() const725     virtual FactoryFunction GetUITestFactory() const override
726     {
727         if (m_pFactoryFunction)
728             return m_pFactoryFunction;
729         return Control::GetUITestFactory();
730     }
731 
732 public:
VclDrawingArea(vcl::Window * pParent,WinBits nStyle)733     VclDrawingArea(vcl::Window *pParent, WinBits nStyle)
734         : Control(pParent, nStyle)
735         , m_pFactoryFunction(nullptr)
736         , m_pUserData(nullptr)
737     {
738         SetBackground();
739     }
SetUITestFactory(FactoryFunction pFactoryFunction,void * pUserData)740     void SetUITestFactory(FactoryFunction pFactoryFunction, void* pUserData)
741     {
742         m_pFactoryFunction = pFactoryFunction;
743         m_pUserData = pUserData;
744     }
GetUserData() const745     void* GetUserData() const
746     {
747         return m_pUserData;
748     }
SetPaintHdl(const Link<std::pair<vcl::RenderContext &,const tools::Rectangle &>,void> & rLink)749     void SetPaintHdl(const Link<std::pair<vcl::RenderContext&, const tools::Rectangle&>, void>& rLink)
750     {
751         m_aPaintHdl = rLink;
752     }
SetResizeHdl(const Link<const Size &,void> & rLink)753     void SetResizeHdl(const Link<const Size&, void>& rLink)
754     {
755         m_aResizeHdl = rLink;
756     }
SetMousePressHdl(const Link<const MouseEvent &,bool> & rLink)757     void SetMousePressHdl(const Link<const MouseEvent&, bool>& rLink)
758     {
759         m_aMousePressHdl = rLink;
760     }
SetMouseMoveHdl(const Link<const MouseEvent &,bool> & rLink)761     void SetMouseMoveHdl(const Link<const MouseEvent&, bool>& rLink)
762     {
763         m_aMouseMotionHdl = rLink;
764     }
SetMouseReleaseHdl(const Link<const MouseEvent &,bool> & rLink)765     void SetMouseReleaseHdl(const Link<const MouseEvent&, bool>& rLink)
766     {
767         m_aMouseReleaseHdl = rLink;
768     }
SetKeyPressHdl(const Link<const KeyEvent &,bool> & rLink)769     void SetKeyPressHdl(const Link<const KeyEvent&, bool>& rLink)
770     {
771         m_aKeyPressHdl = rLink;
772     }
SetKeyReleaseHdl(const Link<const KeyEvent &,bool> & rLink)773     void SetKeyReleaseHdl(const Link<const KeyEvent&, bool>& rLink)
774     {
775         m_aKeyReleaseHdl = rLink;
776     }
SetStyleUpdatedHdl(const Link<VclDrawingArea &,void> & rLink)777     void SetStyleUpdatedHdl(const Link<VclDrawingArea&, void>& rLink)
778     {
779         m_aStyleUpdatedHdl = rLink;
780     }
SetCommandHdl(const Link<const CommandEvent &,bool> & rLink)781     void SetCommandHdl(const Link<const CommandEvent&, bool>& rLink)
782     {
783         m_aCommandHdl = rLink;
784     }
SetQueryTooltipHdl(const Link<tools::Rectangle &,OUString> & rLink)785     void SetQueryTooltipHdl(const Link<tools::Rectangle&, OUString>& rLink)
786     {
787         m_aQueryTooltipHdl = rLink;
788     }
789 };
790 
791 //Get first window of a pTopLevel window as
792 //if any intermediate layout widgets didn't exist
793 //i.e. acts like pChild = pChild->GetWindow(GetWindowType::FirstChild);
794 //in a flat hierarchy where dialogs only have one layer
795 //of children
796 vcl::Window* firstLogicalChildOfParent(const vcl::Window *pTopLevel);
797 
798 //Get last window of a pTopLevel window as
799 //if any intermediate layout widgets didn't exist
800 //i.e. acts like pChild = pChild->GetWindow(GetWindowType::LastChild);
801 //in a flat hierarchy where dialogs only have one layer
802 //of children
803 vcl::Window* lastLogicalChildOfParent(const vcl::Window *pTopLevel);
804 
805 //Get next window after pChild of a pTopLevel window as
806 //if any intermediate layout widgets didn't exist
807 //i.e. acts like pChild = pChild->GetWindow(GetWindowType::Next);
808 //in a flat hierarchy where dialogs only have one layer
809 //of children
810 vcl::Window* nextLogicalChildOfParent(const vcl::Window *pTopLevel, const vcl::Window *pChild);
811 
812 //Get previous window before pChild of a pTopLevel window as
813 //if any intermediate layout widgets didn't exist
814 //i.e. acts like pChild = pChild->GetWindow(GetWindowType::Prev);
815 //in a flat hierarchy where dialogs only have one layer
816 //of children
817 vcl::Window* prevLogicalChildOfParent(const vcl::Window *pTopLevel, const vcl::Window *pChild);
818 
819 //Returns true is the Window has a single child which is a container
820 VCL_DLLPUBLIC bool isLayoutEnabled(const vcl::Window *pWindow);
821 
isContainerWindow(const vcl::Window & rWindow)822 inline bool isContainerWindow(const vcl::Window &rWindow)
823 {
824     WindowType eType = rWindow.GetType();
825     return eType == WindowType::CONTAINER || eType == WindowType::SCROLLWINDOW ||
826            (eType == WindowType::DOCKINGWINDOW && ::isLayoutEnabled(&rWindow));
827 }
828 
isContainerWindow(const vcl::Window * pWindow)829 inline bool isContainerWindow(const vcl::Window *pWindow)
830 {
831     return pWindow && isContainerWindow(*pWindow);
832 }
833 
834 // retro-fitting utilities
835 
836 //Get a Size which is large enough to contain all children with
837 //an equal amount of space at top left and bottom right
838 Size getLegacyBestSizeForChildren(const vcl::Window &rWindow);
839 
840 //Get first parent which is not a layout widget
841 vcl::Window* getNonLayoutParent(vcl::Window *pParent);
842 
843 #endif
844 
845 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
846