src/widget/widget_composite.cpp
author KUDr
Tue, 27 Feb 2007 22:47:59 +0000
branchcpp_gui
changeset 6264 9fc3b5467396
parent 6260 740c702f6871
child 6278 c09f5e53af9b
permissions -rw-r--r--
(svn r8931) [cpp_gui] -Add: first OO widget type (TextButton) added only with basic functionality
-Add: new gui events (C++)
-Add: dynamic event handlers introduced (see Widget::AddReflectHandlerT)
-Add: test window using the new features (intro_gui.cpp)
/* $Id$ */

#include "../stdafx.h"
#include <stdarg.h>
#include "../openttd.h"
#include "../debug.h"
#include "../functions.h"
#include "../map.h"
#include "../player.h"
#include "../window.h"
#include "../gfx.h"
#include "../viewport.h"
#include "../console.h"
#include "../variables.h"
#include "../table/sprites.h"
#include "../genworld.h"
#include "../helpers.hpp"
#include "window_events.hpp"

namespace gui {

void CompositeWidget::AddWidget(Widget *wd)
{
	WidgetId id = wd->GetId();
	std::pair<WidgetIterator, bool> pib = m_widgets.insert(Widgets::value_type(id, wd));
	assert(pib.second);
}

Widget* CompositeWidget::GetWidget(WidgetId id)
{
	WidgetIterator it = m_widgets.find(id);
	return (it != m_widgets.end()) ? (*it).second : NULL;
}

Widget* CompositeWidget::RemoveWidget(WidgetId id)
{
	WidgetIterator it = m_widgets.find(id);
	if (it == m_widgets.end()) return NULL;
	Widget *wd = (*it).second;
	assert(wd->m_container == this);
	wd->m_container = NULL;
	m_widgets.erase(it);
	return wd;
}

/*virtual*/ Widget* CompositeWidget::WidgetFromPt(const Point16 &pt_parent)
{
	Point16 pt_local = pt_parent - TopLeft();
	bool inside_me = m_rect.PtInRect(pt_parent);
	for (WidgetReverseIterator rit = m_widgets.rbegin(); rit != m_widgets.rend(); ++rit) {
		/* get next child */
		Widget *wd_child = (*rit).second;
		/* ask the child recursively */
		Widget *wd = wd_child->WidgetFromPt(pt_local);
		if (wd != NULL) {
			/* if the widget we found is inside me it is what we are searching for */
			if (inside_me) return wd;
			/* the point is outside me. The widget is clipped unless it is on-top widget */
			if (wd->m_dont_clip) return wd;
			/* try next child */
		}
	}
	return inside_me ? this : NULL;
}

/*virtual*/ void CompositeWidget::Close()
{
	/* mark all children as closed in safe way */
	for (WidgetReverseIterator rit_next = m_widgets.rbegin(); rit_next != m_widgets.rend(); ) {
		/* save the iterator (it can be invalidated) and move forward */
		WidgetReverseIterator rit = rit_next++;
		/* get child */
		Widget *wd_child = (*rit).second;
		/* tell him we are closing */
		wd_child->Close();
	}
	/* remove children */
	m_widgets.clear();
	/* mark self as closed */
	super::Close();
}

/*virtual*/ void CompositeWidget::OnPaint(EvtPaint &ev)
{
	/* paint background */
	DrawBackground(ev);

	/* paint all children */
	for (WidgetIterator it_next = m_widgets.begin(); it_next != m_widgets.end(); ) {
		/* save the iterator (it can be invalidated) and move forward */
		WidgetIterator it = it_next++;
		/* get child */
		Widget *wd_child = (*it).second;
		/* tell him we are closing */
		wd_child->OnPaint(ev);
	}
}

/*virtual*/ void CompositeWidget::OnLeftClick(EvtClick &ev)
{
	//Point16 pt(ev->we.click.pt.x, ev->we.click.pt.y);
	Widget *wd_child = WidgetFromPt(ev.m_pt);
	if (wd_child != NULL && wd_child != this) {
		wd_child->OnLeftClick(ev);
		return;
	}
	super::OnLeftClick(ev);
}

/*virtual*/ void CompositeWidget::OnRightClick(EvtRightClick &ev)
{
	//Point16 pt(ev->we.click.pt.x, ev->we.click.pt.y);
	Widget *wd_child = WidgetFromPt(ev.m_pt);
	if (wd_child != NULL && wd_child != this) {
		wd_child->OnRightClick(ev);
		return;
	}
	super::OnRightClick(ev);
}

}; // namespace gui