1 /***********************************************************************
2 	created:	13/4/2004
3 	author:		Paul D Turner
4 
5 	purpose:	Implementation of FrameWindow base class
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #include "CEGUI/widgets/FrameWindow.h"
30 #include "CEGUI/widgets/Titlebar.h"
31 #include "CEGUI/widgets/PushButton.h"
32 #include "CEGUI/MouseCursor.h"
33 #include "CEGUI/WindowManager.h"
34 #include "CEGUI/Exceptions.h"
35 #include "CEGUI/ImageManager.h"
36 #include "CEGUI/CoordConverter.h"
37 
38 // URGENT FIXME: I commented instances of PixelAligned in here, I think they are not necessary but it should be checked!
39 
40 // Start of CEGUI namespace section
41 namespace CEGUI
42 {
43 const String FrameWindow::EventNamespace("FrameWindow");
44 const String FrameWindow::WidgetTypeName("CEGUI/FrameWindow");
45 
46 /*************************************************************************
47 	Constants
48 *************************************************************************/
49 // additional event names for this window
50 const String FrameWindow::EventRollupToggled( "RollupToggled" );
51 const String FrameWindow::EventCloseClicked( "CloseClicked" );
52 const String FrameWindow::EventDragSizingStarted("DragSizingStarted");
53 const String FrameWindow::EventDragSizingEnded("DragSizingEnded");
54 
55 // other bits
56 const float FrameWindow::DefaultSizingBorderSize	= 8.0f;
57 
58 /*************************************************************************
59     Child Widget name constants
60 *************************************************************************/
61 const String FrameWindow::TitlebarName( "__auto_titlebar__" );
62 const String FrameWindow::CloseButtonName( "__auto_closebutton__" );
63 
64 
65 /*************************************************************************
66 	Constructor
67 *************************************************************************/
FrameWindow(const String & type,const String & name)68 FrameWindow::FrameWindow(const String& type, const String& name) :
69 	Window(type, name)
70 {
71 	d_frameEnabled		= true;
72 	d_rollupEnabled		= true;
73 	d_rolledup			= false;
74 	d_sizingEnabled		= true;
75 	d_beingSized		= false;
76 	d_dragMovable		= true;
77 
78 	d_borderSize		= DefaultSizingBorderSize;
79 
80 	d_nsSizingCursor = d_ewSizingCursor = d_neswSizingCursor = d_nwseSizingCursor = 0;
81 
82 	addFrameWindowProperties();
83 }
84 
85 
86 /*************************************************************************
87 	Destructor
88 *************************************************************************/
~FrameWindow(void)89 FrameWindow::~FrameWindow(void)
90 {
91 }
92 
93 
94 /*************************************************************************
95 	Initialises the Window based object ready for use.
96 *************************************************************************/
initialiseComponents(void)97 void FrameWindow::initialiseComponents(void)
98 {
99     // get component windows
100     Titlebar* titlebar = getTitlebar();
101     PushButton* closeButton = getCloseButton();
102 
103     // configure titlebar
104     titlebar->setDraggingEnabled(d_dragMovable);
105     titlebar->setText(getText());
106 
107     // ban some properties on components, since they are linked to settings
108     // defined here.
109     titlebar->banPropertyFromXML("Text");
110     titlebar->banPropertyFromXML("Visible");
111     titlebar->banPropertyFromXML("Disabled");
112     closeButton->banPropertyFromXML("Visible");
113     closeButton->banPropertyFromXML("Disabled");
114 
115     // bind handler to close button 'Click' event
116     closeButton->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&CEGUI::FrameWindow::closeClickHandler, this));
117 
118     performChildWindowLayout();
119 }
120 
121 
122 /*************************************************************************
123     Return whether the title bar for this window is enabled.
124 *************************************************************************/
isTitleBarEnabled(void) const125 bool FrameWindow::isTitleBarEnabled(void) const
126 {
127     return !getTitlebar()->isDisabled();
128 }
129 
130 
131 /*************************************************************************
132     Return whether this close button for this window is enabled.
133 *************************************************************************/
isCloseButtonEnabled(void) const134 bool FrameWindow::isCloseButtonEnabled(void) const
135 {
136     return !getCloseButton()->isDisabled();
137 }
138 
139 
140 /*************************************************************************
141 	Enables or disables sizing for this window.
142 *************************************************************************/
setSizingEnabled(bool setting)143 void FrameWindow::setSizingEnabled(bool setting)
144 {
145 	d_sizingEnabled = setting;
146 }
147 
148 
149 /*************************************************************************
150 	Enables or disables the frame for this window.
151 *************************************************************************/
setFrameEnabled(bool setting)152 void FrameWindow::setFrameEnabled(bool setting)
153 {
154 	d_frameEnabled = setting;
155 	invalidate();
156 }
157 
158 
159 /*************************************************************************
160 	Enables or disables the title bar for the frame window.
161 *************************************************************************/
setTitleBarEnabled(bool setting)162 void FrameWindow::setTitleBarEnabled(bool setting)
163 {
164     Window* titlebar = getTitlebar();
165     titlebar->setEnabled(setting);
166     titlebar->setVisible(setting);
167 }
168 
169 
170 /*************************************************************************
171 	Enables or disables the close button for the frame window.
172 *************************************************************************/
setCloseButtonEnabled(bool setting)173 void FrameWindow::setCloseButtonEnabled(bool setting)
174 {
175     Window* closebtn = getCloseButton();
176     closebtn->setEnabled(setting);
177     closebtn->setVisible(setting);
178 }
179 
180 
181 /*************************************************************************
182 	Enables or disables roll-up (shading) for this window.
183 *************************************************************************/
setRollupEnabled(bool setting)184 void FrameWindow::setRollupEnabled(bool setting)
185 {
186 	if ((setting == false) && isRolledup())
187 	{
188 		toggleRollup();
189 	}
190 
191 	d_rollupEnabled = setting;
192 }
193 
194 
195 /*************************************************************************
196 	Toggles the state of the window between rolled-up (shaded) and normal
197 	sizes.  This requires roll-up to be enabled.
198 *************************************************************************/
toggleRollup(void)199 void FrameWindow::toggleRollup(void)
200 {
201     if (isRollupEnabled())
202     {
203         d_rolledup ^= true;
204 
205         // event notification.
206         WindowEventArgs args(this);
207         onRollupToggled(args);
208 
209         getGUIContext().updateWindowContainingMouse();
210     }
211 
212 }
213 
setRolledup(bool val)214 void FrameWindow::setRolledup(bool val)
215 {
216     if(val != isRolledup())
217     {
218         toggleRollup();
219     }
220 }
221 
222 /*************************************************************************
223 	Move the window by the pixel offsets specified in 'offset'.
224 *************************************************************************/
offsetPixelPosition(const Vector2f & offset)225 void FrameWindow::offsetPixelPosition(const Vector2f& offset)
226 {
227     UVector2 uOffset(cegui_absdim(/*PixelAligned(*/offset.d_x/*)*/),
228                      cegui_absdim(/*PixelAligned(*/offset.d_y/*)*/));
229 
230     setPosition(d_area.getPosition() + uOffset);
231 }
232 
233 
234 /*************************************************************************
235 	check local pixel co-ordinate point 'pt' and return one of the
236 	SizingLocation enumerated values depending where the point falls on
237 	the sizing border.
238 *************************************************************************/
getSizingBorderAtPoint(const Vector2f & pt) const239 FrameWindow::SizingLocation FrameWindow::getSizingBorderAtPoint(const Vector2f& pt) const
240 {
241 	Rectf frame(getSizingRect());
242 
243 	// we can only size if the frame is enabled and sizing is on
244 	if (isSizingEnabled() && isFrameEnabled())
245 	{
246 		// point must be inside the outer edge
247 		if (frame.isPointInRect(pt))
248 		{
249 			// adjust rect to get inner edge
250 			frame.d_min.d_x += d_borderSize;
251 			frame.d_min.d_y += d_borderSize;
252 			frame.d_max.d_x -= d_borderSize;
253 			frame.d_max.d_y -= d_borderSize;
254 
255 			// detect which edges we are on
256 			bool top = (pt.d_y < frame.d_min.d_y);
257 			bool bottom = (pt.d_y >= frame.d_max.d_y);
258 			bool left = (pt.d_x < frame.d_min.d_x);
259 			bool right = (pt.d_x >= frame.d_max.d_x);
260 
261 			// return appropriate 'SizingLocation' value
262 			if (top && left)
263 			{
264 				return SizingTopLeft;
265 			}
266 			else if (top && right)
267 			{
268 				return SizingTopRight;
269 			}
270 			else if (bottom && left)
271 			{
272 				return SizingBottomLeft;
273 			}
274 			else if (bottom && right)
275 			{
276 				return SizingBottomRight;
277 			}
278 			else if (top)
279 			{
280 				return SizingTop;
281 			}
282 			else if (bottom)
283 			{
284 				return SizingBottom;
285 			}
286 			else if (left)
287 			{
288 				return SizingLeft;
289 			}
290 			else if (right)
291 			{
292 				return SizingRight;
293 			}
294 
295 		}
296 
297 	}
298 
299 	// deafult: None.
300 	return SizingNone;
301 }
302 
303 
304 /*************************************************************************
305 	move the window's left edge by 'delta'.  The rest of the window
306 	does not move, thus this changes the size of the Window.
307 *************************************************************************/
moveLeftEdge(float delta,URect & out_area)308 bool FrameWindow::moveLeftEdge(float delta, URect& out_area)
309 {
310     float orgWidth = d_pixelSize.d_width;
311 
312     // ensure that we only size to the set constraints.
313     //
314     // NB: We are required to do this here due to our virtually unique sizing nature; the
315     // normal system for limiting the window size is unable to supply the information we
316     // require for updating our internal state used to manage the dragging, etc.
317     float maxWidth(CoordConverter::asAbsolute(d_maxSize.d_width, getRootContainerSize().d_width));
318     float minWidth(CoordConverter::asAbsolute(d_minSize.d_width, getRootContainerSize().d_width));
319     float newWidth = orgWidth - delta;
320 
321     if (maxWidth != 0.0f && newWidth > maxWidth)
322         delta = orgWidth - maxWidth;
323     else if (newWidth < minWidth)
324         delta = orgWidth - minWidth;
325 
326     // ensure adjustment will be whole pixel
327     float adjustment = /*PixelAligned(*/delta/*)*/;
328 
329     if (d_horizontalAlignment == HA_RIGHT)
330     {
331         out_area.d_max.d_x.d_offset -= adjustment;
332     }
333     else if (d_horizontalAlignment == HA_CENTRE)
334     {
335         out_area.d_max.d_x.d_offset -= adjustment * 0.5f;
336         out_area.d_min.d_x.d_offset += adjustment * 0.5f;
337     }
338     else
339     {
340         out_area.d_min.d_x.d_offset += adjustment;
341     }
342 
343     return d_horizontalAlignment == HA_LEFT;
344 }
345 /*************************************************************************
346 	move the window's right edge by 'delta'.  The rest of the window
347 	does not move, thus this changes the size of the Window.
348 *************************************************************************/
moveRightEdge(float delta,URect & out_area)349 bool FrameWindow::moveRightEdge(float delta, URect& out_area)
350 {
351     // store this so we can work out how much size actually changed
352     float orgWidth = d_pixelSize.d_width;
353 
354     // ensure that we only size to the set constraints.
355     //
356     // NB: We are required to do this here due to our virtually unique sizing nature; the
357     // normal system for limiting the window size is unable to supply the information we
358     // require for updating our internal state used to manage the dragging, etc.
359     float maxWidth(CoordConverter::asAbsolute(d_maxSize.d_width, getRootContainerSize().d_width));
360     float minWidth(CoordConverter::asAbsolute(d_minSize.d_width, getRootContainerSize().d_width));
361     float newWidth = orgWidth + delta;
362 
363     if (maxWidth != 0.0f && newWidth > maxWidth)
364         delta = maxWidth - orgWidth;
365     else if (newWidth < minWidth)
366         delta = minWidth - orgWidth;
367 
368     // ensure adjustment will be whole pixel
369     float adjustment = /*PixelAligned(*/delta/*)*/;
370 
371     out_area.d_max.d_x.d_offset += adjustment;
372 
373     if (d_horizontalAlignment == HA_RIGHT)
374     {
375         out_area.d_max.d_x.d_offset += adjustment;
376         out_area.d_min.d_x.d_offset += adjustment;
377     }
378     else if (d_horizontalAlignment == HA_CENTRE)
379     {
380         out_area.d_max.d_x.d_offset += adjustment * 0.5f;
381         out_area.d_min.d_x.d_offset += adjustment * 0.5f;
382     }
383 
384     // move the dragging point so mouse remains 'attached' to edge of window
385     d_dragPoint.d_x += adjustment;
386 
387     return d_horizontalAlignment == HA_RIGHT;
388 }
389 
390 /*************************************************************************
391 	move the window's top edge by 'delta'.  The rest of the window
392 	does not move, thus this changes the size of the Window.
393 *************************************************************************/
moveTopEdge(float delta,URect & out_area)394 bool FrameWindow::moveTopEdge(float delta, URect& out_area)
395 {
396     float orgHeight = d_pixelSize.d_height;
397 
398     // ensure that we only size to the set constraints.
399     //
400     // NB: We are required to do this here due to our virtually unique sizing nature; the
401     // normal system for limiting the window size is unable to supply the information we
402     // require for updating our internal state used to manage the dragging, etc.
403     float maxHeight(CoordConverter::asAbsolute(d_maxSize.d_height, getRootContainerSize().d_height));
404     float minHeight(CoordConverter::asAbsolute(d_minSize.d_height, getRootContainerSize().d_height));
405     float newHeight = orgHeight - delta;
406 
407     if (maxHeight != 0.0f && newHeight > maxHeight)
408         delta = orgHeight - maxHeight;
409     else if (newHeight < minHeight)
410         delta = orgHeight - minHeight;
411 
412     // ensure adjustment will be whole pixel
413     float adjustment = /*PixelAligned(*/delta/*)*/;
414 
415     if (d_verticalAlignment == VA_BOTTOM)
416     {
417         out_area.d_max.d_y.d_offset -= adjustment;
418     }
419     else if (d_verticalAlignment == VA_CENTRE)
420     {
421         out_area.d_max.d_y.d_offset -= adjustment * 0.5f;
422         out_area.d_min.d_y.d_offset += adjustment * 0.5f;
423     }
424     else
425     {
426         out_area.d_min.d_y.d_offset += adjustment;
427     }
428 
429     return d_verticalAlignment == VA_TOP;
430 }
431 
432 
433 /*************************************************************************
434 	move the window's bottom edge by 'delta'.  The rest of the window
435 	does not move, thus this changes the size of the Window.
436 *************************************************************************/
moveBottomEdge(float delta,URect & out_area)437 bool FrameWindow::moveBottomEdge(float delta, URect& out_area)
438 {
439     // store this so we can work out how much size actually changed
440     float orgHeight = d_pixelSize.d_height;
441 
442     // ensure that we only size to the set constraints.
443     //
444     // NB: We are required to do this here due to our virtually unique sizing nature; the
445     // normal system for limiting the window size is unable to supply the information we
446     // require for updating our internal state used to manage the dragging, etc.
447     float maxHeight(CoordConverter::asAbsolute(d_maxSize.d_height, getRootContainerSize().d_height));
448     float minHeight(CoordConverter::asAbsolute(d_minSize.d_height, getRootContainerSize().d_height));
449     float newHeight = orgHeight + delta;
450 
451     if (maxHeight != 0.0f && newHeight > maxHeight)
452         delta = maxHeight - orgHeight;
453     else if (newHeight < minHeight)
454         delta = minHeight - orgHeight;
455 
456     // ensure adjustment will be whole pixel
457     float adjustment = /*PixelAligned(*/delta/*)*/;
458 
459     out_area.d_max.d_y.d_offset += adjustment;
460 
461     if (d_verticalAlignment == VA_BOTTOM)
462     {
463         out_area.d_max.d_y.d_offset += adjustment;
464         out_area.d_min.d_y.d_offset += adjustment;
465     }
466     else if (d_verticalAlignment == VA_CENTRE)
467     {
468         out_area.d_max.d_y.d_offset += adjustment * 0.5f;
469         out_area.d_min.d_y.d_offset += adjustment * 0.5f;
470     }
471 
472     // move the dragging point so mouse remains 'attached' to edge of window
473     d_dragPoint.d_y += adjustment;
474 
475     return d_verticalAlignment == VA_BOTTOM;
476 }
477 
478 
479 /*************************************************************************
480 	Handler to map close button clicks to FrameWindow 'CloseCliked' events
481 *************************************************************************/
closeClickHandler(const EventArgs &)482 bool FrameWindow::closeClickHandler(const EventArgs&)
483 {
484     WindowEventArgs args(this);
485 	onCloseClicked(args);
486 
487 	return true;
488 }
489 
490 
491 /*************************************************************************
492 	Set the appropriate mouse cursor for the given window-relative pixel
493 	point.
494 *************************************************************************/
setCursorForPoint(const Vector2f & pt) const495 void FrameWindow::setCursorForPoint(const Vector2f& pt) const
496 {
497 	switch(getSizingBorderAtPoint(pt))
498 	{
499 	case SizingTop:
500 	case SizingBottom:
501 		getGUIContext().
502             getMouseCursor().setImage(d_nsSizingCursor);
503 		break;
504 
505 	case SizingLeft:
506 	case SizingRight:
507 		getGUIContext().
508             getMouseCursor().setImage(d_ewSizingCursor);
509 		break;
510 
511 	case SizingTopLeft:
512 	case SizingBottomRight:
513 		getGUIContext().
514             getMouseCursor().setImage(d_nwseSizingCursor);
515 		break;
516 
517 	case SizingTopRight:
518 	case SizingBottomLeft:
519 		getGUIContext().
520             getMouseCursor().setImage(d_neswSizingCursor);
521 		break;
522 
523 	default:
524 		getGUIContext().
525             getMouseCursor().setImage(getMouseCursor());
526 		break;
527 	}
528 
529 }
530 
531 
532 /*************************************************************************
533 	Event generated internally whenever the roll-up / shade state of the
534 	window changes.
535 *************************************************************************/
onRollupToggled(WindowEventArgs & e)536 void FrameWindow::onRollupToggled(WindowEventArgs& e)
537 {
538     invalidate(true);
539     notifyScreenAreaChanged();
540     ElementEventArgs size_args(e.window);
541     onSized(size_args);
542 
543 	fireEvent(EventRollupToggled, e, EventNamespace);
544 }
545 
546 
547 /*************************************************************************
548 	Event generated internally whenever the close button is clicked.
549 *************************************************************************/
onCloseClicked(WindowEventArgs & e)550 void FrameWindow::onCloseClicked(WindowEventArgs& e)
551 {
552 	fireEvent(EventCloseClicked, e, EventNamespace);
553 }
554 
555 
556 /*************************************************************************
557 	Handler for mouse move events
558 *************************************************************************/
onMouseMove(MouseEventArgs & e)559 void FrameWindow::onMouseMove(MouseEventArgs& e)
560 {
561 	// default processing (this is now essential as it controls event firing).
562 	Window::onMouseMove(e);
563 
564 	// if we are not the window containing the mouse, do NOT change the cursor
565 	if (getGUIContext().getWindowContainingMouse() != this)
566 	{
567 		return;
568 	}
569 
570 	if (isSizingEnabled())
571 	{
572 		Vector2f localMousePos(CoordConverter::screenToWindow(*this, e.position));
573 
574 		if (d_beingSized)
575 		{
576 			SizingLocation dragEdge = getSizingBorderAtPoint(d_dragPoint);
577 
578 			// calculate sizing deltas...
579 			float	deltaX = localMousePos.d_x - d_dragPoint.d_x;
580 			float	deltaY = localMousePos.d_y - d_dragPoint.d_y;
581 
582             URect new_area(d_area);
583             bool top_left_sizing = false;
584 			// size left or right edges
585 			if (isLeftSizingLocation(dragEdge))
586 			{
587 				top_left_sizing |= moveLeftEdge(deltaX, new_area);
588 			}
589 			else if (isRightSizingLocation(dragEdge))
590 			{
591 				top_left_sizing |= moveRightEdge(deltaX, new_area);
592 			}
593 
594 			// size top or bottom edges
595 			if (isTopSizingLocation(dragEdge))
596 			{
597 				top_left_sizing |= moveTopEdge(deltaY, new_area);
598 			}
599 			else if (isBottomSizingLocation(dragEdge))
600 			{
601 				top_left_sizing |= moveBottomEdge(deltaY, new_area);
602 			}
603 
604             setArea_impl(new_area.d_min, new_area.getSize(), top_left_sizing);
605 		}
606 		else
607 		{
608 			setCursorForPoint(localMousePos);
609 		}
610 
611 	}
612 
613 	// mark event as handled
614 	++e.handled;
615 }
616 
617 
618 /*************************************************************************
619 	Handler for mouse button down events
620 *************************************************************************/
onMouseButtonDown(MouseEventArgs & e)621 void FrameWindow::onMouseButtonDown(MouseEventArgs& e)
622 {
623 	// default processing (this is now essential as it controls event firing).
624 	Window::onMouseButtonDown(e);
625 
626 	if (e.button == LeftButton)
627 	{
628 		if (isSizingEnabled())
629 		{
630 			// get position of mouse as co-ordinates local to this window.
631 			Vector2f localPos(CoordConverter::screenToWindow(*this, e.position));
632 
633 			// if the mouse is on the sizing border
634 			if (getSizingBorderAtPoint(localPos) != SizingNone)
635 			{
636 				// ensure all inputs come to us for now
637 				if (captureInput())
638 				{
639 					// setup the 'dragging' state variables
640 					d_beingSized = true;
641 					d_dragPoint = localPos;
642 
643                     // do drag-sizing started notification
644                     WindowEventArgs args(this);
645                     onDragSizingStarted(args);
646 
647 					++e.handled;
648 				}
649 
650 			}
651 
652 		}
653 
654 	}
655 
656 }
657 
658 
659 /*************************************************************************
660 	Handler for mouse button up events
661 *************************************************************************/
onMouseButtonUp(MouseEventArgs & e)662 void FrameWindow::onMouseButtonUp(MouseEventArgs& e)
663 {
664 	// default processing (this is now essential as it controls event firing).
665 	Window::onMouseButtonUp(e);
666 
667 	if (e.button == LeftButton && isCapturedByThis())
668 	{
669 		// release our capture on the input data
670 		releaseInput();
671 		++e.handled;
672 	}
673 
674 }
675 
676 
677 /*************************************************************************
678 	Handler for when mouse capture is lost
679 *************************************************************************/
onCaptureLost(WindowEventArgs & e)680 void FrameWindow::onCaptureLost(WindowEventArgs& e)
681 {
682 	// default processing (this is now essential as it controls event firing).
683 	Window::onCaptureLost(e);
684 
685 	// reset sizing state
686 	d_beingSized = false;
687 
688     // do drag-sizing ended notification
689     WindowEventArgs args(this);
690     onDragSizingEnded(args);
691 
692 	++e.handled;
693 }
694 
695 
696 /*************************************************************************
697     Handler for when text changes
698 *************************************************************************/
onTextChanged(WindowEventArgs & e)699 void FrameWindow::onTextChanged(WindowEventArgs& e)
700 {
701     Window::onTextChanged(e);
702     // pass this onto titlebar component.
703     getTitlebar()->setText(getText());
704     // maybe the user is using a fontdim for titlebar dimensions ;)
705     performChildWindowLayout();
706 }
707 
708 
709 /*************************************************************************
710     Handler for when this Window is activated
711 *************************************************************************/
onActivated(ActivationEventArgs & e)712 void FrameWindow::onActivated(ActivationEventArgs& e)
713 {
714 	Window::onActivated(e);
715 	getTitlebar()->invalidate();
716 }
717 
718 
719 /*************************************************************************
720     Handler for when this Window is deactivated
721 *************************************************************************/
onDeactivated(ActivationEventArgs & e)722 void FrameWindow::onDeactivated(ActivationEventArgs& e)
723 {
724 	Window::onDeactivated(e);
725 	getTitlebar()->invalidate();
726 }
727 
728 
729 /*************************************************************************
730 	Set whether this FrameWindow can be moved by dragging the title bar.
731 *************************************************************************/
setDragMovingEnabled(bool setting)732 void FrameWindow::setDragMovingEnabled(bool setting)
733 {
734 	if (d_dragMovable != setting)
735 	{
736 		d_dragMovable = setting;
737 
738         getTitlebar()->setDraggingEnabled(setting);
739     }
740 
741 }
742 
743 
744 /*************************************************************************
745 	Add properties for this class
746 *************************************************************************/
addFrameWindowProperties(void)747 void FrameWindow::addFrameWindowProperties(void)
748 {
749     const String& propertyOrigin = WidgetTypeName;
750 
751     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
752         "SizingEnabled", "Property to get/set the state of the sizable setting for the FrameWindow. Value is either \"true\" or \"false\".",
753         &FrameWindow::setSizingEnabled, &FrameWindow::isSizingEnabled, true
754     );
755 
756     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
757         "FrameEnabled", "Property to get/set the setting for whether the window frame will be displayed. Value is either \"true\" or \"false\".",
758         &FrameWindow::setFrameEnabled, &FrameWindow::isFrameEnabled, true
759     );
760 
761     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
762         "TitlebarEnabled", "Property to get/set the setting for whether the window title-bar will be enabled (or displayed depending upon choice of final widget type). Value is either \"true\" or \"false\".",
763         &FrameWindow::setTitleBarEnabled, &FrameWindow::isTitleBarEnabled, true
764     ); // TODO: Inconsistency between Titlebar and TitleBar
765 
766     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
767         "CloseButtonEnabled", "Property to get/set the setting for whether the window close button will be enabled (or displayed depending upon choice of final widget type). Value is either \"true\" or \"false\".",
768         &FrameWindow::setCloseButtonEnabled, &FrameWindow::isCloseButtonEnabled, true
769     );
770 
771     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
772         "RollUpEnabled", "Property to get/set the setting for whether the user is able to roll-up / shade the window. Value is either \"true\" or \"false\".",
773         &FrameWindow::setRollupEnabled, &FrameWindow::isRollupEnabled, true
774     ); // TODO: Inconsistency between RollUp and Rollup
775 
776     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
777         "RollUpState", "Property to get/set the roll-up / shade state of the window.  Value is either \"true\" or \"false\".",
778         &FrameWindow::setRolledup, &FrameWindow::isRolledup, false /* TODO: Inconsistency */
779     );
780 
781     CEGUI_DEFINE_PROPERTY(FrameWindow, bool,
782         "DragMovingEnabled", "Property to get/set the setting for whether the user may drag the window around by its title bar. Value is either \"true\" or \"false\".",
783         &FrameWindow::setDragMovingEnabled, &FrameWindow::isDragMovingEnabled, true
784     );
785 
786     CEGUI_DEFINE_PROPERTY(FrameWindow, float,
787         "SizingBorderThickness", "Property to get/set the setting for the sizing border thickness. Value is a float specifying the border thickness in pixels.",
788         &FrameWindow::setSizingBorderThickness, &FrameWindow::getSizingBorderThickness, 8.0f
789     );
790 
791     CEGUI_DEFINE_PROPERTY(FrameWindow, Image*,
792         "NSSizingCursorImage", "Property to get/set the N-S (up-down) sizing cursor image for the FrameWindow. Value should be \"set:[imageset name] image:[image name]\".",
793         &FrameWindow::setNSSizingCursorImage, &FrameWindow::getNSSizingCursorImage, 0
794     );
795 
796     CEGUI_DEFINE_PROPERTY(FrameWindow, Image*,
797         "EWSizingCursorImage", "Property to get/set the E-W (left-right) sizing cursor image for the FrameWindow. Value should be \"set:[imageset name] image:[image name]\".",
798         &FrameWindow::setEWSizingCursorImage, &FrameWindow::getEWSizingCursorImage, 0
799     );
800 
801     CEGUI_DEFINE_PROPERTY(FrameWindow, Image*,
802         "NWSESizingCursorImage", "Property to get/set the NW-SE diagonal sizing cursor image for the FrameWindow. Value should be \"set:[imageset name] image:[image name]\".",
803         &FrameWindow::setNWSESizingCursorImage, &FrameWindow::getNWSESizingCursorImage, 0
804     );
805 
806     CEGUI_DEFINE_PROPERTY(FrameWindow, Image*,
807         "NESWSizingCursorImage", "Property to get/set the NE-SW diagonal sizing cursor image for the FramwWindow. Value should be \"set:[imageset name] image:[image name]\".",
808         &FrameWindow::setNESWSizingCursorImage, &FrameWindow::getNESWSizingCursorImage, 0
809     );
810 }
811 
812 /*************************************************************************
813     return the image used for the north-south sizing cursor.
814 *************************************************************************/
getNSSizingCursorImage() const815 const Image* FrameWindow::getNSSizingCursorImage() const
816 {
817     return d_nsSizingCursor;
818 }
819 
820 /*************************************************************************
821     return the image used for the east-west sizing cursor.
822 *************************************************************************/
getEWSizingCursorImage() const823 const Image* FrameWindow::getEWSizingCursorImage() const
824 {
825     return d_ewSizingCursor;
826 }
827 
828 /*************************************************************************
829     return the image used for the northwest-southeast sizing cursor.
830 *************************************************************************/
getNWSESizingCursorImage() const831 const Image* FrameWindow::getNWSESizingCursorImage() const
832 {
833     return d_nwseSizingCursor;
834 }
835 
836 /*************************************************************************
837     return the image used for the northeast-southwest sizing cursor.
838 *************************************************************************/
getNESWSizingCursorImage() const839 const Image* FrameWindow::getNESWSizingCursorImage() const
840 {
841     return d_neswSizingCursor;
842 }
843 
844 /*************************************************************************
845     set the image used for the north-south sizing cursor.
846 *************************************************************************/
setNSSizingCursorImage(const Image * image)847 void FrameWindow::setNSSizingCursorImage(const Image* image)
848 {
849     d_nsSizingCursor = image;
850 }
851 
852 /*************************************************************************
853     set the image used for the east-west sizing cursor.
854 *************************************************************************/
setEWSizingCursorImage(const Image * image)855 void FrameWindow::setEWSizingCursorImage(const Image* image)
856 {
857     d_ewSizingCursor = image;
858 }
859 
860 /*************************************************************************
861     set the image used for the northwest-southeast sizing cursor.
862 *************************************************************************/
setNWSESizingCursorImage(const Image * image)863 void FrameWindow::setNWSESizingCursorImage(const Image* image)
864 {
865     d_nwseSizingCursor = image;
866 }
867 
868 /*************************************************************************
869     set the image used for the northeast-southwest sizing cursor.
870 *************************************************************************/
setNESWSizingCursorImage(const Image * image)871 void FrameWindow::setNESWSizingCursorImage(const Image* image)
872 {
873     d_neswSizingCursor = image;
874 }
875 
876 /*************************************************************************
877     set the image used for the north-south sizing cursor.
878 *************************************************************************/
setNSSizingCursorImage(const String & name)879 void FrameWindow::setNSSizingCursorImage(const String& name)
880 {
881     d_nsSizingCursor = &ImageManager::getSingleton().get(name);
882 }
883 
884 /*************************************************************************
885     set the image used for the east-west sizing cursor.
886 *************************************************************************/
setEWSizingCursorImage(const String & name)887 void FrameWindow::setEWSizingCursorImage(const String& name)
888 {
889     d_ewSizingCursor = &ImageManager::getSingleton().get(name);
890 }
891 
892 /*************************************************************************
893     set the image used for the northwest-southeast sizing cursor.
894 *************************************************************************/
setNWSESizingCursorImage(const String & name)895 void FrameWindow::setNWSESizingCursorImage(const String& name)
896 {
897     d_nwseSizingCursor = &ImageManager::getSingleton().get(name);
898 }
899 
900 /*************************************************************************
901     set the image used for the northeast-southwest sizing cursor.
902 *************************************************************************/
setNESWSizingCursorImage(const String & name)903 void FrameWindow::setNESWSizingCursorImage(const String& name)
904 {
905     d_neswSizingCursor = &ImageManager::getSingleton().get(name);
906 }
907 
908 /*************************************************************************
909     Return a pointer to the Titlebar component widget for this FrameWindow.
910 *************************************************************************/
getTitlebar() const911 Titlebar* FrameWindow::getTitlebar() const
912 {
913     return static_cast<Titlebar*>(getChild(TitlebarName));
914 }
915 
916 /*************************************************************************
917     Return a pointer to the close button component widget for this
918     FrameWindow.
919 *************************************************************************/
getCloseButton() const920 PushButton* FrameWindow::getCloseButton() const
921 {
922     return static_cast<PushButton*>(getChild(CloseButtonName));
923 }
924 
925 //----------------------------------------------------------------------------//
onDragSizingStarted(WindowEventArgs & e)926 void FrameWindow::onDragSizingStarted(WindowEventArgs& e)
927 {
928 	fireEvent(EventDragSizingStarted, e, EventNamespace);
929 }
930 
931 //----------------------------------------------------------------------------//
onDragSizingEnded(WindowEventArgs & e)932 void FrameWindow::onDragSizingEnded(WindowEventArgs& e)
933 {
934 	fireEvent(EventDragSizingEnded, e, EventNamespace);
935 }
936 
937 //----------------------------------------------------------------------------//
938 
939 } // End of  CEGUI namespace section
940 
941