Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 344)
+++ trunk/src/gui/gui_environment.cc	(revision 351)
@@ -29,11 +29,6 @@
 {
 	m_area.dim( dimension( w->get_width(), w->get_height() ) );
-	
-	m_screen           = m_elements.create();
-	element* screen    = m_elements.get( m_screen );
-	screen->m_absolute = m_area;
-	screen->m_relative = m_area;
-
 	m_renderer = new renderer( w );
+	m_screen   = create_element( handle(), m_area );
 }
 
@@ -51,4 +46,5 @@
 {
 	if ( parent.is_nil() ) parent = m_screen;
+
 	handle result = m_elements.create();
 	element* e    = m_elements.get( result );
@@ -58,7 +54,14 @@
 	if ( ar.ul.y < 0 ) { ar.ul.y += m_area.lr.y; ar.lr.y += m_area.lr.y; }
 
+	e->m_child_count = 0;
+	e->m_flags[ENABLED] = true;
+	e->m_flags[VISIBLE] = true;
+	e->m_flags[DIRTY]   = true;
+	e->m_render_data    = nullptr;
 	e->m_absolute = ar;
 	e->m_relative = ar;
-	add_child( parent, result );
+
+	if ( !parent.is_nil() ) // screen creation
+		add_child( parent, result );
 	return result;
 }
@@ -83,5 +86,17 @@
 	if ( !el ) return;
 	//	el->on_update( elapsed );
-	if ( el->m_visible )
+	if ( el->m_flags[ENABLED] )
+	{
+		bool hover     = el->m_flags[HOVER];
+		bool new_hover = el->m_absolute.contains( m_mouse_position );
+		if ( hover != new_hover )
+		{
+			el->m_flags[HOVER] = new_hover;
+			// gain loose hover event
+			m_renderer->on_hover_change( el, hover );
+		}
+	}
+
+	if ( el->m_flags[VISIBLE] )
 	{
 		for ( handle i : el->m_children )
@@ -90,8 +105,8 @@
 		}
 	}
-	if ( el->m_dirty || el->m_render_data == nullptr )
+	if ( el->m_flags[DIRTY] || el->m_render_data == nullptr )
 	{
 		m_renderer->redraw( el, elapsed );
-		el->m_dirty = false;
+		el->m_flags[DIRTY] = false;
 	}
 }
@@ -101,5 +116,5 @@
 	element* el = m_elements.get( e );
 	if ( !el ) return;
-	if ( el->m_visible )
+	if ( el->m_flags[VISIBLE] )
 	{
 //		el->on_draw();
@@ -160,6 +175,46 @@
 }
 
-bool nv::gui::environment::process_io_event( const io_event& )
-{
+bool nv::gui::environment::process_io_event( const io_event& ev )
+{
+	switch ( ev.type )
+	{
+//	case EV_KEY          :
+	case EV_MOUSE_BUTTON :
+		if ( ev.mbutton.pressed && ev.mbutton.button == MOUSE_LEFT )
+		{ 
+			handle h = get_element( position( ev.mbutton.x, ev.mbutton.y ) );
+			set_selected( h );
+			return true;
+		}
+		return false;
+	case EV_MOUSE_MOVE:
+		m_mouse_position = position( ev.mmove.x, ev.mmove.y );
+		return false;
+//	case EV_MOUSE_WHEEL  :
+	default:
+		break;
+	}
+	return false;
+}
+
+bool nv::gui::environment::set_selected( handle e )
+{
+	if ( e != m_selected )
+	{
+		element* eold = m_elements.get( m_selected );
+		element* el   = m_elements.get( e );
+		if ( eold )
+		{
+			eold->m_flags[SELECTED] = false;
+			m_renderer->on_select_change( eold, false );
+		}
+		if ( el )
+		{
+			el->m_flags[SELECTED] = true;
+			m_renderer->on_select_change( el, true );
+		}
+		m_selected = e;
+		return true;
+	}
 	return false;
 }
@@ -179,5 +234,5 @@
 {
 	element* el = m_elements.get(e);
-	if ( !el && !el->m_visible ) return handle();
+	if ( !el && !el->m_flags[VISIBLE] ) return handle();
 
 	handle result;
@@ -206,5 +261,5 @@
 			parent->m_children.erase( it );
 			parent->m_children.push_back( child );
-			parent->m_dirty = true;
+			parent->m_flags[DIRTY] = true;
 		}	
 	}
@@ -222,5 +277,5 @@
 			parent->m_children.erase( it );
 			parent->m_children.push_front( child );
-			parent->m_dirty = true;
+			parent->m_flags[DIRTY] = true;
 		}
 	}
@@ -232,6 +287,6 @@
 	if ( el )
 	{
-		el->m_dirty    = true;
-		el->m_relative = r;
+		el->m_flags[DIRTY] = true;
+		el->m_relative     = r;
 		recalculate_absolute( e );
 	}
@@ -264,6 +319,6 @@
 	if ( ep != nullptr )
 	{
-		ep->m_class = text;
-		ep->m_dirty = true;
+		ep->m_class        = text;
+		ep->m_flags[DIRTY] = true;
 	}
 }
@@ -274,6 +329,6 @@
 	if ( ep != nullptr )
 	{
-		ep->m_text = text;
-		ep->m_dirty = true;
+		ep->m_text         = text;
+		ep->m_flags[DIRTY] = true;
 	}
 }
