Changeset 269
- Timestamp:
- 06/21/14 19:38:56 (11 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/gui/gui_element.hh
r268 r269 23 23 namespace gui 24 24 { 25 26 class handle 27 { 28 public: 29 handle() : m_index(0), m_counter(0) {} 30 31 inline bool operator==(const handle& rhs){return m_index == rhs.m_index && m_counter == rhs.m_counter; } 32 inline bool operator!=(const handle& rhs){return !(*this == rhs);} 33 34 bool is_nil() { return m_index == 0 && m_counter == 0; } 35 bool is_valid() { return !is_nil(); } 36 private: 37 friend class environment; 38 39 explicit handle( uint16 a_index, uint16 a_counter ) : m_index( a_index ), m_counter(a_counter) {} 40 41 uint16 m_index; 42 uint16 m_counter; 43 }; 44 45 25 46 class element 26 47 { 27 p rotected:48 public: 28 49 /// List type 29 typedef std::list< element*> list;50 typedef std::list<handle> list; 30 51 31 52 32 e xplicit element( const rectangle& r)53 element() 33 54 : m_id( "" ) 34 , m_parent( nullptr ) 55 , m_this() 56 , m_parent() 35 57 , m_children() 36 58 , m_child_count(0) 37 59 , m_class("") 38 , m_relative( r)39 , m_absolute( r)60 , m_relative() 61 , m_absolute() 40 62 , m_enabled( true ) 41 63 , m_visible( true ) … … 43 65 , m_render_data( nullptr ) {} 44 66 45 protected:46 virtual ~element() { delete m_render_data; }47 protected:48 67 friend class environment; 49 68 friend class renderer; … … 51 70 52 71 string m_id; ///< id type of the object 53 element* m_parent; ///< pointer to parent 72 handle m_this; ///< pointer to parent 73 handle m_parent; ///< pointer to parent 54 74 list m_children; ///< children objects 55 75 size_t m_child_count; ///< number of children -
trunk/nv/gui/gui_environment.hh
r268 r269 26 26 namespace gui 27 27 { 28 class handle29 {30 31 };32 33 28 class environment 34 29 { … … 37 32 // temporary 38 33 void load_style( const std::string& filename ); 39 element* create_element( element* parent, const rectangle& r ); 40 void set_text( element* e, const string& text ); 41 void set_class( element* e, const string& text ); 34 handle create_element( const rectangle& r ); 35 handle create_element( handle parent, const rectangle& r ); 36 void set_text( handle e, const string& text ); 37 void set_class( handle e, const string& text ); 42 38 void update(); 43 39 void draw(); 44 void destroy_element( element*e );40 void destroy_element( handle e ); 45 41 bool process_io_event( const io_event& ev ); 46 42 virtual ~environment(); 47 43 protected: 48 element* get_element( const position& p ); 49 void add_child( element* child ); 50 void add_child( element* parent, element* child ); 51 void remove_child( element* parent, element* child ); 52 void destroy_children( element* e ); 53 void update( element* e, uint32 elapsed ); 54 void draw( element* e ); 55 bool process_io_event( element* e, const io_event& ev ); 56 element* get_deepest_child( element* e, const position& p ); 57 void move_to_top( element* child ); 58 void move_to_bottom( element* child ); 59 void set_relative( element* e, const rectangle& r ); 60 void set_relative( element* e, const position& p ); 61 void recalculate_absolute( element* e ); 44 handle create_handle(); 45 handle create_index( sint16 element_id ); 46 element* get_element( handle h ); 47 handle get_element( const position& p ); 48 void add_child( handle child ); 49 void add_child( handle parent, handle child ); 50 void remove_child( handle parent, handle child ); 51 void destroy_children( handle e ); 52 void update( handle e, uint32 elapsed ); 53 void draw( handle e ); 54 bool process_io_event( handle e, const io_event& ev ); 55 handle get_deepest_child( handle e, const position& p ); 56 void move_to_top( handle child ); 57 void move_to_bottom( handle child ); 58 void set_relative( handle e, const rectangle& r ); 59 void set_relative( handle e, const position& p ); 60 void recalculate_absolute( handle e ); 62 61 62 struct index 63 { 64 sint16 element_id; 65 uint16 counter; 66 sint32 next_free; 67 68 index() : element_id(0), counter(0), next_free(-1) {} 69 }; 70 uint16 get_free_index(); 71 void free_index( uint16 idx_index ); 72 73 sint32 m_first_free; 74 sint32 m_last_free; 75 76 std::vector< element > m_elements; 77 std::vector< index > m_indices; 78 63 79 renderer* m_renderer; 64 80 window* m_window; 65 element*m_screen;81 handle m_screen; 66 82 rectangle m_area; 67 83 }; -
trunk/src/gui/gui_environment.cc
r268 r269 26 26 27 27 nv::gui::environment::environment( window* w, const std::string& shader_path ) 28 : m_renderer( nullptr ), m_window( w ), m_ screen( nullptr)28 : m_renderer( nullptr ), m_window( w ), m_first_free(-1), m_last_free(-1) 29 29 { 30 30 m_area.dim( dimension( w->get_width(), w->get_height() ) ); 31 m_screen = new element( m_area ); 31 32 m_screen = create_handle(); 33 element* screen = get_element( m_screen ); 34 screen->m_absolute = m_area; 35 screen->m_relative = m_area; 36 32 37 m_renderer = new renderer( w, shader_path ); 33 38 } … … 38 43 } 39 44 40 nv::gui::element* nv::gui::environment::create_element( element* parent, const rectangle& r ) 41 { 42 element* result = new element( r ); 43 if ( parent == nullptr ) parent = m_screen; 45 nv::gui::handle nv::gui::environment::create_element( const rectangle& r ) 46 { 47 return create_element( m_screen, r ); 48 } 49 50 nv::gui::handle nv::gui::environment::create_element( handle parent, const rectangle& r ) 51 { 52 if ( parent.is_nil() ) parent = m_screen; 53 handle result = create_handle(); 54 element* e = get_element( result ); 55 e->m_absolute = r; 56 e->m_relative = r; 44 57 add_child( parent, result ); 45 58 return result; 46 59 } 47 60 48 void nv::gui::environment::destroy_element( element* e ) 49 { 61 nv::gui::handle nv::gui::environment::create_handle() 62 { 63 m_elements.emplace_back(); 64 m_elements.back().m_this = create_index( uint16( m_elements.size() - 1 ) ); 65 return m_elements.back().m_this; 66 } 67 68 nv::gui::handle nv::gui::environment::create_index( sint16 element_id ) 69 { 70 uint16 i = get_free_index(); 71 index& idx = m_indices[i]; 72 idx.element_id = element_id; 73 idx.counter++; 74 return handle( i, idx.counter ); 75 } 76 77 nv::uint16 nv::gui::environment::get_free_index() 78 { 79 if ( m_first_free != -1 ) 80 { 81 uint16 result = (uint16)m_first_free; 82 m_first_free = m_indices[result].next_free; 83 m_indices[result].next_free = -1; 84 if ( m_first_free == -1 ) m_last_free = -1; 85 return result; 86 } 87 m_indices.emplace_back(); 88 return uint16( m_indices.size() - 1 ); 89 } 90 91 void nv::gui::environment::free_index( uint16 idx_index ) 92 { 93 // TODO: reuse 94 index& idx = m_indices[ idx_index ]; 95 idx.element_id = -1; 96 idx.next_free = -1; 97 if ( m_last_free == -1 ) 98 { 99 m_first_free = m_last_free = idx_index; 100 } 101 else 102 { 103 m_indices[ m_last_free ].next_free = idx_index; 104 m_last_free = idx_index; 105 } 106 } 107 108 void nv::gui::environment::destroy_element( handle e ) 109 { 110 element* dead_element = get_element( e ); 111 if ( dead_element == nullptr ) return; 50 112 destroy_children( e ); 51 if ( e->m_parent ) 52 { 53 remove_child( e->m_parent, e ); 54 } 55 delete e; 56 } 57 58 void nv::gui::environment::update( element* e, uint32 elapsed ) 59 { 60 // e->on_update( elapsed ); 61 if ( e->m_visible ) 62 { 63 for ( element* i : e->m_children ) 113 remove_child( dead_element->m_parent, e ); 114 115 delete dead_element->m_render_data; 116 dead_element->m_render_data = nullptr; 117 dead_element->m_parent = handle(); 118 119 uint16 dead_index = m_indices[ e.m_index ].element_id; 120 if ( dead_index != m_elements.size()-1 ) 121 { 122 m_elements[ dead_index ] = m_elements.back(); 123 m_elements.pop_back(); 124 m_indices[ m_elements[ dead_index ].m_this.m_index ].element_id = dead_index; 125 } 126 else 127 m_elements.pop_back(); 128 free_index( e.m_index ); 129 } 130 131 void nv::gui::environment::update( handle e, uint32 elapsed ) 132 { 133 element* el = get_element( e ); 134 if ( !el ) return; 135 // el->on_update( elapsed ); 136 if ( el->m_visible ) 137 { 138 for ( handle i : el->m_children ) 64 139 { 65 140 update( i, elapsed ); 66 141 } 67 142 } 68 if ( e->m_dirty || e->m_render_data == nullptr ) 69 { 70 m_renderer->redraw( e, elapsed ); 71 e->m_dirty = false; 72 } 73 } 74 75 void nv::gui::environment::draw( element* e ) 76 { 77 if ( e->m_visible ) 78 { 79 // e->on_draw(); 80 m_renderer->draw( e ); 81 for ( element* i : e->m_children ) 143 if ( el->m_dirty || el->m_render_data == nullptr ) 144 { 145 m_renderer->redraw( el, elapsed ); 146 el->m_dirty = false; 147 } 148 } 149 150 void nv::gui::environment::draw( handle e ) 151 { 152 element* el = get_element( e ); 153 if ( !el ) return; 154 if ( el->m_visible ) 155 { 156 // el->on_draw(); 157 m_renderer->draw( el ); 158 for ( handle i : el->m_children ) 82 159 { 83 160 draw(i); … … 97 174 } 98 175 99 void nv::gui::environment::add_child( element*child )176 void nv::gui::environment::add_child( handle child ) 100 177 { 101 178 add_child( m_screen, child ); 102 179 } 103 180 104 void nv::gui::environment::add_child( element* parent, element* child ) 105 { 106 if ( child ) 107 { 108 if ( child->m_parent ) 109 { 110 remove_child( child->m_parent, child ); 181 void nv::gui::environment::add_child( handle parent, handle child ) 182 { 183 element* e = get_element( child ); 184 element* p = get_element( parent ); 185 if ( e && p ) 186 { 187 remove_child( e->m_parent, child ); 188 e->m_parent = parent; 189 p->m_children.push_back( child ); 190 p->m_child_count++; 191 } 192 } 193 194 void nv::gui::environment::destroy_children( handle e ) 195 { 196 element* parent = get_element(e); 197 if ( parent ) 198 { 199 while ( !parent->m_children.empty() ) 200 { 201 destroy_element( parent->m_children.front() ); 111 202 } 112 child->m_parent = parent;113 parent->m_children.push_back( child );114 parent->m_child_count++;115 }116 }117 118 void nv::gui::environment::destroy_children( element* e )119 {120 while ( !e->m_children.empty() )121 {122 destroy_element( e->m_children.front() );123 203 } 124 204 } … … 127 207 nv::gui::environment::~environment() 128 208 { 129 destroy_ element( m_screen);209 destroy_children( handle() ); 130 210 delete m_renderer; 131 211 } … … 136 216 } 137 217 138 bool nv::gui::environment::process_io_event( element* e, const io_event& ev ) 139 { 140 return e->m_parent ? process_io_event( e->m_parent, ev ) : false; 141 } 142 143 nv::gui::element* nv::gui::environment::get_element( const position& p ) 218 bool nv::gui::environment::process_io_event( handle e, const io_event& ev ) 219 { 220 element* el = get_element( e ); 221 return el && el->m_parent.m_index ? process_io_event( el->m_parent, ev ) : false; 222 } 223 224 nv::gui::handle nv::gui::environment::get_element( const position& p ) 144 225 { 145 226 return get_deepest_child( m_screen, p ); 146 227 } 147 228 148 nv::gui::element* nv::gui::environment::get_deepest_child( element* e, const position& p ) 149 { 150 if ( !e->m_visible ) return nullptr; 151 152 element* result = nullptr; 153 element::list::reverse_iterator it = e->m_children.rbegin(); 154 155 while ( it != e->m_children.rend() ) 229 nv::gui::element* nv::gui::environment::get_element( handle h ) 230 { 231 if ( h.is_nil() ) return nullptr; 232 const index& idx = m_indices[ h.m_index ]; 233 return idx.counter == h.m_counter && idx.element_id >= 0 ? &m_elements[ idx.element_id ] : nullptr; 234 } 235 236 nv::gui::handle nv::gui::environment::get_deepest_child( handle e, const position& p ) 237 { 238 element* el = get_element(e); 239 if ( !el && !el->m_visible ) return handle(); 240 241 handle result; 242 element::list::reverse_iterator it = el->m_children.rbegin(); 243 244 while ( it != el->m_children.rend() ) 156 245 { 157 246 result = get_deepest_child( *it, p ); 158 if ( result ) return result;247 if ( result.m_index ) return result; 159 248 ++it; 160 249 } 161 250 162 if ( e->m_absolute.contains(p) ) return e; 163 return nullptr; 164 } 165 166 void nv::gui::environment::move_to_top( element* child ) 167 { 168 element* parent = child->m_parent; 169 if ( parent ) 251 if ( el->m_absolute.contains(p) ) return e; 252 return handle(); 253 } 254 255 void nv::gui::environment::move_to_top( handle child ) 256 { 257 element* e = get_element( child ); 258 element* parent = get_element( e->m_parent ); 259 if ( e && parent ) 170 260 { 171 261 auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child ); … … 179 269 } 180 270 181 void nv::gui::environment::move_to_bottom( element* child ) 182 { 183 element* parent = child->m_parent; 184 if ( parent ) 271 void nv::gui::environment::move_to_bottom( handle child ) 272 { 273 element* e = get_element( child ); 274 element* parent = get_element( e->m_parent ); 275 if ( e && parent ) 185 276 { 186 277 auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child ); … … 194 285 } 195 286 196 void nv::gui::environment::set_relative( element* e, const rectangle& r ) 197 { 198 e->m_dirty = true; 199 e->m_relative = r; 200 recalculate_absolute( e ); 201 } 202 203 void nv::gui::environment::set_relative( element* e, const position& p ) 204 { 205 set_relative( e, rectangle( p, p + e->m_relative.get_size() ) ); 206 } 207 208 void nv::gui::environment::recalculate_absolute( element* e ) 209 { 210 rectangle pabsolute; 211 212 if ( e->m_parent ) 213 { 214 pabsolute = e->m_parent->m_absolute; 215 } 216 217 e->m_absolute = e->m_relative + pabsolute.ul; 218 219 for ( element* o : e->m_children ) 287 void nv::gui::environment::set_relative( handle e, const rectangle& r ) 288 { 289 element* el = get_element(e); 290 if ( el ) 291 { 292 el->m_dirty = true; 293 el->m_relative = r; 294 recalculate_absolute( e ); 295 } 296 } 297 298 void nv::gui::environment::set_relative( handle e, const position& p ) 299 { 300 element* el = get_element(e); 301 if ( el ) 302 { 303 set_relative( e, rectangle( p, p + el->m_relative.get_size() ) ); 304 } 305 } 306 307 void nv::gui::environment::recalculate_absolute( handle e ) 308 { 309 element* el = get_element(e); 310 rectangle pabsolute = get_element( el->m_parent )->m_absolute; 311 el->m_absolute = el->m_relative + pabsolute.ul; 312 313 for ( handle o : el->m_children ) 220 314 { 221 315 recalculate_absolute( o ); … … 223 317 } 224 318 225 void nv::gui::environment::set_class( element* e, const string& text ) 226 { 227 e->m_class = text; 228 e->m_dirty = true; 229 } 230 231 void nv::gui::environment::set_text( element* e, const string& text ) 232 { 233 e->m_text = text; 234 e->m_dirty = true; 235 } 236 237 void nv::gui::environment::remove_child( element* parent, element* child ) 238 { 239 if ( child->m_parent != parent ) 240 { 241 return; // signal error? 242 } 243 auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child ); 244 if ( it != parent->m_children.end() ) 245 { 246 (*it)->m_parent = nullptr; 247 parent->m_children.erase(it); 248 } 249 250 } 251 319 void nv::gui::environment::set_class( handle e, const string& text ) 320 { 321 element* ep = get_element(e); 322 if ( ep != nullptr ) 323 { 324 ep->m_class = text; 325 ep->m_dirty = true; 326 } 327 } 328 329 void nv::gui::environment::set_text( handle e, const string& text ) 330 { 331 element* ep = get_element(e); 332 if ( ep != nullptr ) 333 { 334 ep->m_text = text; 335 ep->m_dirty = true; 336 } 337 } 338 339 void nv::gui::environment::remove_child( handle parent, handle child ) 340 { 341 element* p = get_element( parent ); 342 if ( p ) 343 { 344 auto it = std::find( p->m_children.begin(), p->m_children.end(), child ); 345 if ( it != p->m_children.end() ) 346 { 347 element* e = get_element( *it ); 348 e->m_parent = handle(); 349 p->m_children.erase(it); 350 } 351 } 352 } 353 -
trunk/tests/gui_test/nv_gui_test.cc
r268 r269 23 23 nv::clear_state m_clear_state; 24 24 nv::gui::environment* m_guienv; 25 std::vector<nv::gui:: element*> m_windows;25 std::vector<nv::gui::handle> m_windows; 26 26 }; 27 27 … … 86 86 glm::ivec2 a( std::rand() % 600, std::rand() % 400 ); 87 87 glm::ivec2 b( std::rand() % 200 + 40, std::rand() % 200 + 40 ); 88 nv::gui:: element* e = m_guienv->create_element( nullptr,nv::rectangle(a).dim(b) );88 nv::gui::handle e = m_guienv->create_element( nv::rectangle(a).dim(b) ); 89 89 m_guienv->set_class( e, "window" ); 90 90 m_guienv->set_text( e, "Window "+nv::to_string(m_windows.size()+1) );
Note: See TracChangeset
for help on using the changeset viewer.