4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "TwoWidgets.hpp"
28 TwoWidgets::~TwoWidgets()
35 TwoWidgets::UpdateLayout()
37 const auto layout
= CalculateLayout(rc
);
38 first
->Move(layout
.first
);
39 second
->Move(layout
.second
);
44 CalculateSplit(int top
, int bottom
, unsigned min_a
,
45 unsigned min_b
, unsigned max_b
)
47 assert(bottom
>= top
);
48 assert(min_b
<= max_b
);
50 const unsigned height
= bottom
- top
;
52 if (min_a
<= 0 || min_b
<= 0)
53 /* at least one Widet doesn't know its minimums size; there may be
54 better solutions for this, but this workaround is good enough
55 for fixing the assertion failure in DevicesConfigPanel */
56 return (top
+ bottom
) / 2;
57 else if (height
>= min_a
+ max_b
)
58 /* more than enough space: align the second Widget at the bottom
59 and give the rest to the first Widget */
60 return bottom
- max_b
;
61 else if (height
>= min_a
+ min_b
)
62 /* still somewhat enough space */
63 return bottom
- min_b
;
65 /* give the best for the rest */
66 const PixelScalar first_height
=
67 std::min(min_a
, height
/ 2);
68 return top
+ first_height
;
73 TwoWidgets::CalculateSplit(const PixelRect
&rc
) const
75 const PixelSize min_a
= first
->GetMinimumSize();
76 const PixelSize min_b
= second
->GetMinimumSize();
77 const PixelSize max_b
= second
->GetMaximumSize();
80 ? ::CalculateSplit(rc
.top
, rc
.bottom
, min_a
.cy
,
82 : ::CalculateSplit(rc
.left
, rc
.right
, min_a
.cx
,
86 std::pair
<PixelRect
,PixelRect
>
87 TwoWidgets::CalculateLayout(const PixelRect
&rc
) const
89 PixelRect a
= rc
, b
= rc
;
91 a
.bottom
= b
.top
= CalculateSplit(rc
);
93 a
.right
= b
.left
= CalculateSplit(rc
);
94 return std::make_pair(a
, b
);
98 TwoWidgets::GetMinimumSize() const
100 const PixelSize a
= first
->GetMinimumSize();
101 const PixelSize b
= second
->GetMinimumSize();
104 ? PixelSize
{ std::max(a
.cx
, b
.cx
), a
.cy
+ b
.cy
}
105 : PixelSize
{ a
.cx
+ b
.cx
, std::max(a
.cy
, b
.cy
) };
109 TwoWidgets::GetMaximumSize() const
111 const PixelSize a
= first
->GetMaximumSize();
112 const PixelSize b
= second
->GetMaximumSize();
115 ? PixelSize
{ std::max(a
.cx
, b
.cx
), a
.cy
+ b
.cy
}
116 : PixelSize
{ a
.cx
+ b
.cx
, std::max(a
.cy
, b
.cy
) };
120 * Calculates a "dummy" layout that is splitted in the middle. In
121 * TwoWidgets::Initialise() and TwoWidgets::Prepare(), we are not
122 * allowed to call Widget::GetMinimumSize() yet.
125 static std::pair
<PixelRect
,PixelRect
>
126 DummyLayout(const PixelRect rc
, bool vertical
)
128 PixelRect a
= rc
, b
= rc
;
130 a
.bottom
= b
.top
= (rc
.top
+ rc
.bottom
) / 2;
132 a
.right
= b
.left
= (rc
.left
+ rc
.right
) / 2;
133 return std::make_pair(a
, b
);
137 TwoWidgets::Initialise(ContainerWindow
&parent
, const PixelRect
&rc
)
140 const auto layout
= DummyLayout(rc
, vertical
);
141 first
->Initialise(parent
, layout
.first
);
142 second
->Initialise(parent
, layout
.second
);
146 TwoWidgets::Prepare(ContainerWindow
&parent
, const PixelRect
&rc
)
149 const auto layout
= DummyLayout(rc
, vertical
);
150 first
->Prepare(parent
, layout
.first
);
151 second
->Prepare(parent
, layout
.second
);
155 TwoWidgets::Unprepare()
162 TwoWidgets::Save(bool &changed
)
164 return first
->Save(changed
) && second
->Save(changed
);
170 return first
->Click() || second
->Click();
174 TwoWidgets::ReClick()
181 TwoWidgets::Show(const PixelRect
&rc
)
184 const auto layout
= CalculateLayout(rc
);
185 first
->Show(layout
.first
);
186 second
->Show(layout
.second
);
192 return first
->Leave() && second
->Leave();
203 TwoWidgets::Move(const PixelRect
&rc
)
206 const auto layout
= CalculateLayout(rc
);
207 first
->Move(layout
.first
);
208 second
->Move(layout
.second
);
212 TwoWidgets::SetFocus()
214 return first
->SetFocus() || second
->SetFocus();