1 /***********************************************************************
2 created:    11/6/2012
3 author:     Lukas E Meindl
4 *************************************************************************/
5 /***************************************************************************
6 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
7 *
8 *   Permission is hereby granted, free of charge, to any person obtaining
9 *   a copy of this software and associated documentation files (the
10 *   "Software"), to deal in the Software without restriction, including
11 *   without limitation the rights to use, copy, modify, merge, publish,
12 *   distribute, sublicense, and/or sell copies of the Software, and to
13 *   permit persons to whom the Software is furnished to do so, subject to
14 *   the following conditions:
15 *
16 *   The above copyright notice and this permission notice shall be
17 *   included in all copies or substantial portions of the Software.
18 *
19 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 *   OTHER DEALINGS IN THE SOFTWARE.
26 ***************************************************************************/
27 #include "SamplesBrowserManager.h"
28 
29 #include "SamplesFramework.h"
30 
31 #include "CEGUI/Window.h"
32 #include "CEGUI/SchemeManager.h"
33 #include "CEGUI/WindowManager.h"
34 #include "CEGUI/EventArgs.h"
35 #include "CEGUI/widgets/DefaultWindow.h"
36 #include "CEGUI/widgets/VerticalLayoutContainer.h"
37 #include "CEGUI/widgets/HorizontalLayoutContainer.h"
38 #include "CEGUI/widgets/FrameWindow.h"
39 #include "CEGUI/widgets/PushButton.h"
40 #include "CEGUI/Image.h"
41 #include "CEGUI/falagard/WidgetLookManager.h"
42 
43 using namespace CEGUI;
44 
45 const CEGUI::uint32 SamplesBrowserManager::d_sampleWindowFrameNormal(0xFFFFFFFF);
46 const CEGUI::uint32 SamplesBrowserManager::d_sampleWindowFrameSelected(0xFF77FFB6);
47 
SamplesBrowserManager(SamplesFramework * owner,CEGUI::Window * samplesWindow)48 SamplesBrowserManager::SamplesBrowserManager(SamplesFramework* owner, CEGUI::Window* samplesWindow)
49     : d_owner(owner),
50     d_root(samplesWindow),
51     d_childCount(0),
52     d_aspectRatio(1.0f),
53     d_selectedWindow(0)
54 {
55     init();
56 }
57 
58 
getWindow()59 CEGUI::Window* SamplesBrowserManager::getWindow()
60 {
61     return d_root;
62 }
63 
createSampleWindow(const CEGUI::String & name,const CEGUI::Image & image)64 CEGUI::FrameWindow* SamplesBrowserManager::createSampleWindow(const CEGUI::String& name, const CEGUI::Image& image)
65 {
66     CEGUI::VerticalLayoutContainer* root = createPreviewLayoutContainer();
67 
68     CEGUI::HorizontalLayoutContainer* header = createPreviewHeader();
69     root->addChild(header);
70 
71     CEGUI::DefaultWindow* windowName = createPreviewHeaderNameWindow(name);
72     header->addChild(windowName);
73 
74     CEGUI::PushButton* entryButton = createPreviewHeaderEnterButton();
75     windowName->addChild(entryButton);
76 
77     FrameWindow* sampleWindow = createPreviewSampleWindow(name, image);
78     root->addChild(sampleWindow);
79 
80     d_sampleWindows.push_back(sampleWindow);
81     d_buttonToSampleWindowMap[entryButton] = sampleWindow;
82 
83     d_verticalLayoutContainerSamples->addChild(root);
84 
85 
86     ++d_childCount;
87 
88     return sampleWindow;
89 }
90 
setWindowRatio(float aspectRatio)91 void SamplesBrowserManager::setWindowRatio(float aspectRatio)
92 {
93     d_aspectRatio = aspectRatio;
94 
95     updateWindows();
96 }
97 
updateWindows()98 void SamplesBrowserManager::updateWindows()
99 {
100     int max = d_sampleWindows.size();
101     for(int i = 0; i < max; ++i)
102     {
103         CEGUI::Window* window(d_sampleWindows[i]);
104 
105         window->setAspectRatio(d_aspectRatio);
106         window->setSize(USize(UDim(1.0f, -10.0f), cegui_absdim(1.0f)));
107     }
108 
109     d_root->setSize(USize(cegui_reldim(1.0f), cegui_reldim(1.0f)));
110 }
111 
handleMouseClickSampleWindow(const CEGUI::EventArgs & args)112 bool SamplesBrowserManager::handleMouseClickSampleWindow(const CEGUI::EventArgs& args)
113 {
114     const WindowEventArgs& winArgs(static_cast<const WindowEventArgs&>(args));
115 
116     CEGUI::Window* wnd(winArgs.window);
117 
118     d_owner->handleStartDisplaySample(wnd);
119 
120     return true;
121 }
122 
123 
handleMouseMoveSampleWindow(const CEGUI::EventArgs & args)124 bool SamplesBrowserManager::handleMouseMoveSampleWindow(const CEGUI::EventArgs& args)
125 {
126     const MouseEventArgs& mouseArgs(static_cast<const MouseEventArgs&>(args));
127 
128     CEGUI::Window* wnd(mouseArgs.window);
129 
130     if(d_selectedWindow != wnd)
131     {
132         selectSampleWindow(wnd);
133         d_owner->handleSampleSelection(wnd);
134     }
135 
136     const CEGUI::String& lookNFeel(wnd->getLookNFeel());
137     CEGUI::Rectf innerRectangle = CEGUI::WidgetLookManager::getSingleton().getWidgetLook(lookNFeel).getNamedArea("InnerArea").getArea().getPixelRect(*wnd);
138 
139     const CEGUI::Vector2f& mousePos(mouseArgs.position);
140 
141     const CEGUI::Rectf& windowDimensions(wnd->getUnclippedOuterRect().get());
142 
143     float relPosX = (mousePos.d_x - windowDimensions.left() - innerRectangle.getPosition().d_x) / innerRectangle.getWidth();
144     float relPosY = (mousePos.d_y - windowDimensions.top()  - innerRectangle.getPosition().d_y) / innerRectangle.getHeight();
145 
146     if(relPosX >= 0.0f && relPosX <= 1.0f && relPosY >= 0.0f && relPosY <= 1.0f)
147     {
148         SampleData* sampleData = d_owner->findSampleData(wnd);
149         const CEGUI::Sizef& contextSize(sampleData->getGuiContext()->getSurfaceSize());
150 
151         float absPosX = relPosX * contextSize.d_width;
152         float absPosY = relPosY * contextSize.d_height;
153 
154 
155         sampleData->getGuiContext()->injectMousePosition(absPosX, absPosY);
156         sampleData->getGuiContext()->markAsDirty();
157 
158         wnd->setMouseCursor("SampleBrowserSkin/MouseArrowHover");
159     }
160     else
161     {
162         wnd->setMouseCursor("SampleBrowserSkin/MouseArrow");
163     }
164 
165     return true;
166 }
167 
168 
handleLeaveSampleWindow(const CEGUI::EventArgs & args)169 bool SamplesBrowserManager::handleLeaveSampleWindow(const CEGUI::EventArgs& args)
170 {
171     const MouseEventArgs& mouseArgs(static_cast<const MouseEventArgs&>(args));
172 
173     CEGUI::Window* wnd(mouseArgs.window);
174     wnd->setMouseCursor("SampleBrowserSkin/MouseArrow");
175 
176     return true;
177 }
178 
selectSampleWindow(CEGUI::Window * wnd)179 void SamplesBrowserManager::selectSampleWindow(CEGUI::Window* wnd)
180 {
181     if(d_selectedWindow)
182     {
183         CEGUI::ColourRect colRectNormal = CEGUI::ColourRect(CEGUI::Colour(d_sampleWindowFrameNormal));
184         d_selectedWindow->setProperty("FrameColours", CEGUI::PropertyHelper<ColourRect>::toString(colRectNormal));
185     }
186 
187     d_selectedWindow = wnd;
188 
189     CEGUI::ColourRect colRectSelected = CEGUI::ColourRect(CEGUI::Colour(d_sampleWindowFrameSelected));
190     d_selectedWindow->setProperty("FrameColours", CEGUI::PropertyHelper<ColourRect>::toString(colRectSelected));
191 }
192 
init()193 void SamplesBrowserManager::init()
194 {
195     WindowManager& winMgr(WindowManager::getSingleton());
196 
197     d_verticalLayoutContainerSamples = static_cast<VerticalLayoutContainer*>(winMgr.createWindow("VerticalLayoutContainer"));
198 
199     d_verticalLayoutContainerSamples->setMargin(CEGUI::UBox(cegui_reldim(0.0f), cegui_reldim(0.1f), cegui_absdim(14.f), cegui_reldim(0.1f)));
200     d_verticalLayoutContainerSamples->setMouseInputPropagationEnabled(true);
201 
202     d_root->addChild(d_verticalLayoutContainerSamples);
203 
204 }
205 
createPreviewHeaderNameWindow(const CEGUI::String & name)206 CEGUI::DefaultWindow* SamplesBrowserManager::createPreviewHeaderNameWindow(const CEGUI::String& name)
207 {
208     WindowManager& winMgr(WindowManager::getSingleton());
209 
210     CEGUI::DefaultWindow* windowName = static_cast<DefaultWindow*>(winMgr.createWindow("SampleBrowserSkin/StaticText"));
211     windowName->setSize(CEGUI::USize(cegui_reldim(0.6f), cegui_absdim(44.f)));
212     windowName->setText(name);
213     windowName->setFont("DejaVuSans-12-NoScale");
214     windowName->setProperty("HorzFormatting", "Centre");
215     windowName->setMouseInputPropagationEnabled(true);
216 
217     return windowName;
218 }
219 
createPreviewLayoutContainer()220 CEGUI::VerticalLayoutContainer* SamplesBrowserManager::createPreviewLayoutContainer()
221 {
222     WindowManager& winMgr(WindowManager::getSingleton());
223 
224     CEGUI::VerticalLayoutContainer* root = static_cast<VerticalLayoutContainer*>(winMgr.createWindow("VerticalLayoutContainer"));
225     root->setSize(CEGUI::USize(cegui_reldim(0.8f), cegui_reldim(1.0f)));
226     root->setMouseInputPropagationEnabled(true);
227     root->setMargin(CEGUI::UBox(UDim(0.0f, 0.0f),UDim(0.0f, 0.0f),UDim(0.0f, 8.f), UDim(0.0f, 0.0f)));
228 
229     return root;
230 }
231 
createPreviewSampleWindow(const CEGUI::String & name,const CEGUI::Image & image)232 CEGUI::FrameWindow* SamplesBrowserManager::createPreviewSampleWindow(const CEGUI::String& name, const CEGUI::Image &image)
233 {
234     WindowManager& winMgr(WindowManager::getSingleton());
235 
236     FrameWindow* sampleWindow = static_cast<FrameWindow*>(winMgr.createWindow("SampleBrowserSkin/SampleWindow", name));
237     CEGUI::String imageName = image.getName();
238     sampleWindow->setProperty("Image", imageName);
239 
240     sampleWindow->setSize(USize(UDim(1.0f, -10.0f), cegui_absdim(1.0f)));
241     sampleWindow->setMouseInputPropagationEnabled(true);
242 
243     sampleWindow->subscribeEvent(Window::EventMouseMove, Event::Subscriber(&SamplesBrowserManager::handleMouseMoveSampleWindow, this));
244     sampleWindow->subscribeEvent(Window::EventMouseClick, Event::Subscriber(&SamplesBrowserManager::handleMouseClickSampleWindow, this));
245     sampleWindow->subscribeEvent(Window::EventMouseLeavesArea, Event::Subscriber(&SamplesBrowserManager::handleLeaveSampleWindow, this));
246 
247     CEGUI::ColourRect colRect((CEGUI::Colour(d_sampleWindowFrameNormal)));
248     sampleWindow->setProperty("FrameColours", CEGUI::PropertyHelper<ColourRect>::toString(colRect));
249 
250     sampleWindow->setAspectMode(AM_EXPAND);
251 
252     return sampleWindow;
253 }
254 
createPreviewHeader()255 CEGUI::HorizontalLayoutContainer* SamplesBrowserManager::createPreviewHeader()
256 {
257     WindowManager& winMgr(WindowManager::getSingleton());
258 
259     CEGUI::HorizontalLayoutContainer* header = static_cast<HorizontalLayoutContainer*>(winMgr.createWindow("HorizontalLayoutContainer"));
260     header->setSize(CEGUI::USize(cegui_reldim(1.0f), cegui_absdim(40.0f)));
261     header->setMouseInputPropagationEnabled(true);
262     header->setMargin(CEGUI::UBox(UDim(0.0f, 12.f),UDim(0.0f, 0.0f),UDim(0.0f, 0), UDim(0.0f, 0.0f)));
263     header->setHorizontalAlignment(HA_CENTRE);
264 
265     return header;
266 }
267 
createPreviewHeaderEnterButton()268 CEGUI::PushButton* SamplesBrowserManager::createPreviewHeaderEnterButton()
269 {
270     WindowManager& winMgr(WindowManager::getSingleton());
271 
272     CEGUI::PushButton* button = static_cast<CEGUI::PushButton*>(winMgr.createWindow("SampleBrowserSkin/Button", "SampleEntryButton"));
273 
274     button->setSize(CEGUI::USize(cegui_absdim(1.0f), cegui_reldim(0.7f)));
275     button->setAspectMode(AM_EXPAND);
276     button->setAspectRatio(1.0f);
277     button->setPosition(CEGUI::UVector2(cegui_absdim(-7.f), cegui_absdim(0.0f)));
278     button->setMouseInputPropagationEnabled(true);
279     button->setProperty("NormalImage", "SampleBrowserSkin/EntryButtonNormal");
280     button->setProperty("HoverImage", "SampleBrowserSkin/EntryButtonHover");
281     button->setProperty("PushedImage", "SampleBrowserSkin/EntryButtonClicked");
282     button->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&SamplesBrowserManager::handleSampleEnterButtonClicked, this));
283     button->setAlwaysOnTop(true);
284     button->setHorizontalAlignment(HA_RIGHT);
285     button->setVerticalAlignment(VA_CENTRE);
286     button->setAlwaysOnTop(true);
287 
288     return button;
289 }
290 
291 
handleSampleEnterButtonClicked(const CEGUI::EventArgs & args)292 bool SamplesBrowserManager::handleSampleEnterButtonClicked(const CEGUI::EventArgs& args)
293 {
294     const WindowEventArgs& winArgs(static_cast<const WindowEventArgs&>(args));
295 
296     CEGUI::Window* sampleWindow = d_buttonToSampleWindowMap[winArgs.window];
297     d_owner->handleStartDisplaySample(sampleWindow);
298 
299     return true;
300 }
301