Index: trunk/nv/gui/gui_ascii_renderer.hh
===================================================================
--- trunk/nv/gui/gui_ascii_renderer.hh	(revision 443)
+++ trunk/nv/gui/gui_ascii_renderer.hh	(revision 444)
@@ -33,6 +33,7 @@
 			virtual void draw( element* e );
 			virtual void draw();
-			virtual void on_hover_change( element* e, bool hover );
-			virtual void on_select_change( element* e, bool select );
+			virtual void on_style_change( element* e );
+			virtual void on_hover_change( element* e );
+			virtual void on_select_change( element* e );
 			virtual rectangle get_area() const;
 			virtual ~ascii_renderer();
Index: trunk/nv/gui/gui_common.hh
===================================================================
--- trunk/nv/gui/gui_common.hh	(revision 443)
+++ trunk/nv/gui/gui_common.hh	(revision 444)
@@ -29,4 +29,7 @@
 			SELECTED, //!< GUI element selected
 			HOVER,    //!< GUI element in hover zone
+
+			DIRTY_SELECT,
+			DIRTY_HOVER,
 		};
 
Index: trunk/nv/gui/gui_gfx_renderer.hh
===================================================================
--- trunk/nv/gui/gui_gfx_renderer.hh	(revision 443)
+++ trunk/nv/gui/gui_gfx_renderer.hh	(revision 444)
@@ -48,6 +48,7 @@
 			virtual void draw( element* e );
 			virtual void draw();
-			virtual void on_hover_change( element* e, bool hover );
-			virtual void on_select_change( element* e, bool select );
+			virtual void on_style_change( element* e );
+			virtual void on_hover_change( element* e );
+			virtual void on_select_change( element* e );
 			virtual rectangle get_area() const { return m_area; }
 			virtual ~gfx_renderer();
Index: trunk/nv/gui/gui_renderer.hh
===================================================================
--- trunk/nv/gui/gui_renderer.hh	(revision 443)
+++ trunk/nv/gui/gui_renderer.hh	(revision 444)
@@ -33,6 +33,7 @@
 			virtual void draw( element* e ) = 0;
 			virtual void draw() = 0;
-			virtual void on_hover_change( element* e, bool hover ) = 0;
-			virtual void on_select_change( element* e, bool select ) = 0;
+			virtual void on_style_change( element* e ) = 0;
+			virtual void on_hover_change( element* e ) = 0;
+			virtual void on_select_change( element* e ) = 0;
 			virtual rectangle get_area() const = 0;
 			virtual ~renderer() {}
Index: trunk/nv/gui/gui_style.hh
===================================================================
--- trunk/nv/gui/gui_style.hh	(revision 443)
+++ trunk/nv/gui/gui_style.hh	(revision 444)
@@ -33,6 +33,8 @@
 			bool get( element* e, const string_view& centry, const string_view& cselector, int& i );
 			bool get( element* e, const string_view& centry, const string_view& cselector, double& d );
+			void load_flags( element* e );
 			~style();
 		protected:
+			void add_flags( element* e );
 			bool find_entry( const string_view& cselector, const string_view& centry, int type );
 			bool resolve( shash64 cid, shash64 cclass, const string_view& cselector, const string_view& centry, int type );
Index: trunk/src/gui/gui_ascii_renderer.cc
===================================================================
--- trunk/src/gui/gui_ascii_renderer.cc	(revision 443)
+++ trunk/src/gui/gui_ascii_renderer.cc	(revision 444)
@@ -66,5 +66,5 @@
 			if ( m_style.get( e, "ascii_border_color", selector, border_color ) )
 				er->border_color = uint32( border_color );
-			for ( uint32 i = 0; i < 8 && i < path.length(); )
+			for ( uint32 i = 0; i < 8 && i < path.length(); i++ )
 				er->border_chars[i] = static_cast< uchar8 >( path[i] );
 		}
@@ -81,12 +81,12 @@
 		for ( int x = 0; x < abs.get_width(); ++x )
 		{
-			m_terminal->print( position( abs.ul.y, abs.ul.x + x ), er->border_color, er->border_chars[0] );
-			m_terminal->print( position( abs.lr.y, abs.ul.x + x ), er->border_color, er->border_chars[1] );
+			m_terminal->print( position( abs.ul.x + x, abs.ul.y ), er->border_color, er->border_chars[0] );
+			m_terminal->print( position( abs.ul.x + x, abs.lr.y ), er->border_color, er->border_chars[1] );
 		}
 
 		for ( int y = 0; y < abs.get_height(); ++y )
 		{
-			m_terminal->print( position( abs.ul.y + y, abs.ul.x ), er->border_color, er->border_chars[2] );
-			m_terminal->print( position( abs.ul.y + y, abs.lr.x ), er->border_color, er->border_chars[3] );
+			m_terminal->print( position( abs.ul.x, abs.ul.y + y ), er->border_color, er->border_chars[2] );
+			m_terminal->print( position( abs.lr.x, abs.ul.y + y ), er->border_color, er->border_chars[3] );
 		}
 
@@ -95,4 +95,5 @@
 		m_terminal->print( abs.ll(), er->border_color, er->border_chars[6] );
 		m_terminal->print( abs.lr,   er->border_color, er->border_chars[7] );
+		m_terminal->update();
 	}
 	if ( !e->m_text.empty() )
@@ -112,18 +113,17 @@
 }
 
-void nv::gui::ascii_renderer::on_hover_change( element* e, bool /*hover*/ )
+void nv::gui::ascii_renderer::on_style_change( element* e )
 {
-	// TODO: FIX
-	int fix_me;
-	NV_LOG_DEBUG( "on_hover_change" );
-	e->m_flags[DIRTY] = true;
+	m_style.load_flags( e );
 }
 
-void nv::gui::ascii_renderer::on_select_change( element* e, bool /*select*/ )
+void nv::gui::ascii_renderer::on_hover_change( element* e )
 {
-	// TODO: FIX
-	int fix_me;
-	NV_LOG_DEBUG( "on_select_change" );
-	e->m_flags[DIRTY] = true;
+	if ( e->m_flags[DIRTY_HOVER] ) e->m_flags[DIRTY] = true;
+}
+
+void nv::gui::ascii_renderer::on_select_change( element* e )
+{
+	if ( e->m_flags[DIRTY_SELECT] ) e->m_flags[DIRTY] = true;
 }
 
Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 443)
+++ trunk/src/gui/gui_environment.cc	(revision 444)
@@ -61,4 +61,5 @@
 	if ( !parent.is_nil() ) // screen creation
 		add_child( parent, result );
+
 	return result;
 }
@@ -91,5 +92,5 @@
 			el->m_flags[HOVER] = new_hover;
 			// gain lose hover event
-			m_renderer->on_hover_change( el, hover );
+			m_renderer->on_hover_change( el );
 		}
 	}
@@ -209,10 +210,10 @@
 		{
 			eold->m_flags[SELECTED] = false;
-			m_renderer->on_select_change( eold, false );
+			m_renderer->on_select_change( eold );
 		}
 		if ( el )
 		{
 			el->m_flags[SELECTED] = true;
-			m_renderer->on_select_change( el, true );
+			m_renderer->on_select_change( el );
 		}
 		m_selected = e;
@@ -307,4 +308,5 @@
 		ep->m_class        = m_strings.insert( text );
 		ep->m_flags[DIRTY] = true;
+		m_renderer->on_style_change( ep );
 	}
 }
@@ -315,4 +317,5 @@
 	if ( ep != nullptr )
 	{
+		// TODO : implement twine == operator
 		ep->m_text.assign( text );
 		ep->m_flags[DIRTY] = true;
Index: trunk/src/gui/gui_gfx_renderer.cc
===================================================================
--- trunk/src/gui/gui_gfx_renderer.cc	(revision 443)
+++ trunk/src/gui/gui_gfx_renderer.cc	(revision 444)
@@ -248,4 +248,5 @@
 		if ( e->m_flags[HOVER] )    selector = stext[2];
 		if ( e->m_flags[SELECTED] ) selector = stext[1];
+		NV_LOG_INFO( "redraw" );
 
 		if ( m_style.get( e, "skin", selector, path ) )
@@ -340,18 +341,20 @@
 }
 
-void gfx_renderer::on_hover_change( element* e, bool /*hover*/ )
-{
-	// TODO: FIX
-	int fix_me;
-	NV_LOG_DEBUG( "on_hover_change" );
-	e->m_flags[DIRTY] = true;
-}
-
-void gfx_renderer::on_select_change( element* e, bool /*select*/ )
-{
-	// TODO: FIX
-	int fix_me;
-	NV_LOG_DEBUG( "on_select_change" );
-	e->m_flags[DIRTY] = true;
+void gfx_renderer::on_hover_change( element* e )
+{
+	if ( e->m_flags[DIRTY_HOVER] )
+	{
+		NV_LOG_DEBUG( "on_hover_change" );
+		e->m_flags[DIRTY] = true;
+	}
+}
+
+void gfx_renderer::on_select_change( element* e )
+{
+	if ( e->m_flags[DIRTY_SELECT] )
+	{
+		NV_LOG_DEBUG( "on_select_change" );
+		e->m_flags[DIRTY] = true;
+	}
 }
 
@@ -394,2 +397,7 @@
 	}
 }
+
+void nv::gui::gfx_renderer::on_style_change( element* e )
+{
+	m_style.load_flags( e );
+}
Index: trunk/src/gui/gui_style.cc
===================================================================
--- trunk/src/gui/gui_style.cc	(revision 443)
+++ trunk/src/gui/gui_style.cc	(revision 444)
@@ -114,2 +114,47 @@
 	return false;
 }
+
+void nv::gui::style::load_flags( element* e )
+{
+	lua::stack_guard guard( m_lua );
+	lua_getglobal( m_lua, "default" );
+	int global = lua_gettop( m_lua );
+
+	// check id
+	string_view id( m_env->get_string( e->m_id ) );
+	if ( !id.empty() )
+	{
+		lua_getfield( m_lua, -1, id.data() );
+		add_flags( e );
+		lua_pop( m_lua, -1 );
+	}
+	// check class
+	string_view klass( m_env->get_string( e->m_class ) );
+	if ( !klass.empty() )
+	{
+		lua_getfield( m_lua, -1, klass.data() );
+		add_flags( e );
+		lua_pop( m_lua, -1 );
+	}
+	add_flags( e );
+}
+
+void nv::gui::style::add_flags( element* e )
+{
+	if ( lua_istable( m_lua, -1 ) )
+	{
+		lua_getfield( m_lua, -1, "hover" );
+		if ( lua_istable( m_lua, -1 ) )
+		{
+			e->m_flags[DIRTY_HOVER] = true;
+		}
+		lua_pop( m_lua, 1 );
+
+		lua_getfield( m_lua, -1, "selected" );
+		if ( lua_istable( m_lua, -1 ) )
+		{
+			e->m_flags[DIRTY_SELECT] = true;
+		}
+		lua_pop( m_lua, 1 );
+	}
+}
