Index: trunk/src/gl/gl_enum.cc
===================================================================
--- trunk/src/gl/gl_enum.cc	(revision 350)
+++ trunk/src/gl/gl_enum.cc	(revision 351)
@@ -180,4 +180,6 @@
 	case RGB16F  : return GL_RGB;
 	case RGBA16F : return GL_RGBA;
+	case BGR     : return GL_BGR;
+	case BGRA    : return GL_BGRA;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
@@ -194,4 +196,6 @@
 	case RGB16F  : return GL_RGBA16F;
 	case RGBA16F : return GL_RGBA16F;
+	case BGR     : return GL_RGB8;
+	case BGRA    : return GL_RGBA8;
 	NV_RETURN_COVERED_DEFAULT( 0 );
 	}
Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 350)
+++ 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;
 	}
 }
Index: trunk/src/gui/gui_renderer.cc
===================================================================
--- trunk/src/gui/gui_renderer.cc	(revision 350)
+++ trunk/src/gui/gui_renderer.cc	(revision 351)
@@ -44,4 +44,16 @@
 using namespace nv;
 using namespace nv::gui;
+
+struct vertex
+{
+	ivec2 position;
+	vec2  texcoord;
+	vec4  color;
+	vertex() {}
+	vertex( const nv::ivec2& cr, const nv::vec2& tc, const nv::vec4& c )
+		: position( cr ), texcoord( tc ), color( c )
+	{
+	}
+};
 
 const ivec2 atlas_size = ivec2( 1024, 1024 );
@@ -239,6 +251,10 @@
 		std::string path;
 		std::string text;
-
-		if ( m_style.get( e, "skin", path ) )
+		const char* stext[] = { nullptr, "selected", "hover" };
+		const char* selector = stext[border];
+		if ( e->m_flags[HOVER] )    selector = stext[2];
+		if ( e->m_flags[SELECTED] ) selector = stext[1];
+
+		if ( m_style.get( e, "skin", selector, path ) )
 		{
 			size_t image_id = load_image( path );
@@ -286,5 +302,5 @@
 		{
 
-			if ( m_style.get( e, "border", border ) && m_style.get( e, "border_color", color ) )
+			if ( m_style.get( e, "border", selector, border ) && m_style.get( e, "border_color", selector, color ) )
 			{
 				rectangle inner = abs.shrinked( border );
@@ -296,5 +312,5 @@
 			}
 
-			if ( m_style.get( e, "background_color", color ) )
+			if ( m_style.get( e, "background_color", selector, color ) )
 			{
 				qvec.emplace_back( abs.ul, abs.lr, color );
@@ -305,5 +321,5 @@
 		if ( !text.empty() )
 		{
-			if ( m_style.get( e, "text_color", color ) && m_style.get( e, "text_font", path ) && m_style.get( e, "text_size", border ) )
+			if ( m_style.get( e, "text_color", selector, color ) && m_style.get( e, "text_font", selector, path ) && m_style.get( e, "text_size", selector, border ) )
 			{
 				size_t font_id = load_font( path, (uint16)border );
@@ -331,4 +347,19 @@
 }
 
+void renderer::on_hover_change( element* e, bool hover )
+{
+	// TODO: FIX
+	NV_LOG( nv::LOG_DEBUG, "on_hover_change" );
+	e->m_flags[DIRTY] = true;
+}
+
+void renderer::on_select_change( element* e, bool select )
+{
+	// TODO: FIX
+	NV_LOG( nv::LOG_DEBUG, "on_select_change" );
+	e->m_flags[DIRTY] = true;
+}
+
+
 void renderer::draw( element* e )
 {
Index: trunk/src/gui/gui_style.cc
===================================================================
--- trunk/src/gui/gui_style.cc	(revision 350)
+++ trunk/src/gui/gui_style.cc	(revision 351)
@@ -21,16 +21,16 @@
 }
 
-bool style::get( element* e, const char* centry, std::string& s )
+bool style::get( element* e, const char* centry, const char* cselector, std::string& s )
 {
 	lua::stack_guard guard( m_lua );
-	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), centry, LUA_TSTRING ) ) return false;
+	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), cselector, centry, LUA_TSTRING ) ) return false;
 	s = lua_tostring( m_lua, -1 );
 	return true;
 }
 
-bool style::get( element* e, const char* centry, vec4& vec )
+bool style::get( element* e, const char* centry, const char* cselector, vec4& vec )
 {
 	lua::stack_guard guard( m_lua );
-	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), centry, LUA_TTABLE ) ) return false;
+	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), cselector, centry, LUA_TTABLE ) ) return false;
 	vec = vec4();
 	for (size_t i = 0; i < 4; ++i )
@@ -44,16 +44,16 @@
 }
 
-bool style::get( element* e, const char* centry, int& i )
+bool style::get( element* e, const char* centry, const char* cselector, int& i )
 {
 	lua::stack_guard guard( m_lua );
-	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), centry, LUA_TNUMBER ) ) return false;
+	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), cselector, centry, LUA_TNUMBER ) ) return false;
 	i = static_cast< int >( lua_tointeger( m_lua, -1 ) );
 	return true;
 }
 
-bool style::get( element* e, const char* centry, double& d )
+bool style::get( element* e, const char* centry, const char* cselector, double& d )
 {
 	lua::stack_guard guard( m_lua );
-	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), centry, LUA_TNUMBER ) ) return false;
+	if ( !resolve( e->m_id.c_str(), e->m_class.c_str(), cselector, centry, LUA_TNUMBER ) ) return false;
 	d = lua_tonumber( m_lua, -1 );
 	return true;
@@ -64,5 +64,30 @@
 }
 
-bool style::resolve( const char* cid, const char* cclass, const char* centry, int type )
+bool style::find_entry( const char* cselector, const char* centry, int type )
+{
+	if ( lua_istable( m_lua, -1 ) )
+	{
+		if ( cselector )
+		{
+			lua_getfield( m_lua, -1, cselector );
+			if ( lua_istable( m_lua, -1 ) )
+			{
+				lua_getfield( m_lua, -1, centry );
+				if ( lua_type( m_lua, -1 ) == type ) 
+				{
+					return true;
+				}
+				lua_pop( m_lua, 1 );
+			}
+			lua_pop( m_lua, 1 );
+		}
+
+		lua_getfield( m_lua, -1, centry );
+		if ( lua_type( m_lua, -1 ) == type ) return true;
+	}
+	return false;
+}
+
+bool style::resolve( const char* cid, const char* cclass, const char* cselector, const char* centry, int type )
 {
 	lua_getglobal( m_lua, "default" );
@@ -71,23 +96,14 @@
 	// check id
 	lua_getfield( m_lua, -1, cid );
-	if ( lua_istable( m_lua, -1 ) )
-	{
-		lua_getfield( m_lua, -1, centry );
-		if ( lua_type( m_lua, -1 ) == type ) return true;
-	}
+	if ( find_entry( cselector, centry, type ) ) return true;
 	lua_settop( m_lua, global );
 
 	// check class
 	lua_getfield( m_lua, -1, cclass );
-	if ( lua_istable( m_lua, -1 ) )
-	{
-		lua_getfield( m_lua, -1, centry );
-		if ( lua_type( m_lua, -1 ) == type ) return true;
-	}
+	if ( find_entry( cselector, centry, type ) ) return true;
 	lua_settop( m_lua, global );
 
 	// check entry
-	lua_getfield( m_lua, -1, centry );
-	if ( lua_type( m_lua, -1 ) == type ) return true;
+	if ( find_entry( cselector, centry, type ) ) return true;
 	return false;
 }
