source: trunk/src/gui/gui_environment.cc @ 268

Last change on this file since 268 was 268, checked in by epyon, 11 years ago
  • gui::element completely independent of object
  • gui::element is pure data
File size: 5.5 KB
Line 
1// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
2// http://chaosforge.org/
3//
4// This file is part of NV Libraries.
5// For conditions of distribution and use, see copyright notice in nv.hh
6
7#include "nv/gui/gui_environment.hh"
8
9#include "nv/gui/gui_renderer.hh"
10
11
12        /*
13
14        TODO: parse a lua stylesheet as per Trac wiki
15
16        IDEA: Store everything in std::unordered_maps, with lua_value's?
17
18        A lua_value is a variant stores strings as const char* that deletes them on destructor?
19        Question is that there might not be much gained on speed anyway, due to Lua's speed.
20        Special function field allows delayed per parse execution?
21
22        */
23
24#include "nv/gfx/sliced_buffer.hh"
25#include "nv/gfx/texture_atlas.hh"
26
27nv::gui::environment::environment( window* w, const std::string& shader_path )
28        : m_renderer( nullptr ), m_window( w ), m_screen( nullptr )
29{
30        m_area.dim( dimension( w->get_width(), w->get_height() ) );
31        m_screen = new element( m_area );
32        m_renderer = new renderer( w, shader_path );
33}
34
35void nv::gui::environment::load_style( const std::string& filename )
36{
37        m_renderer->load_style( filename );
38}
39
40nv::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;
44        add_child( parent, result );
45        return result;
46}
47
48void nv::gui::environment::destroy_element( element* e )
49{
50        destroy_children( e );
51        if ( e->m_parent )
52        {
53                remove_child( e->m_parent, e );
54        }
55        delete e;
56}
57
58void 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 )
64                {
65                        update( i, elapsed );
66                }
67        }
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
75void 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 )
82                {
83                        draw(i);
84                }
85        }
86}
87
88void nv::gui::environment::update()
89{
90        update( m_screen, 0 );
91}
92
93void nv::gui::environment::draw()
94{
95        draw( m_screen );
96        m_renderer->draw();
97}
98
99void nv::gui::environment::add_child( element* child )
100{
101        add_child( m_screen, child );
102}
103
104void 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 );
111                }
112                child->m_parent = parent;
113                parent->m_children.push_back( child );
114                parent->m_child_count++;
115        }
116}
117
118void nv::gui::environment::destroy_children( element* e )
119{
120        while ( !e->m_children.empty() )
121        {
122                destroy_element( e->m_children.front() );
123        }
124}
125
126
127nv::gui::environment::~environment()
128{
129        destroy_element( m_screen );
130        delete m_renderer;
131}
132
133bool nv::gui::environment::process_io_event( const io_event& )
134{
135        return false;
136}
137
138bool 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
143nv::gui::element* nv::gui::environment::get_element( const position& p )
144{
145        return get_deepest_child( m_screen, p );
146}
147
148nv::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() )
156        {
157                result = get_deepest_child( *it, p );
158                if ( result ) return result;
159                ++it;
160        }
161
162        if ( e->m_absolute.contains(p) ) return e;
163        return nullptr;
164}
165
166void nv::gui::environment::move_to_top( element* child )
167{
168        element* parent = child->m_parent;
169        if ( parent )
170        {
171                auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child );
172                if ( it != parent->m_children.end() )
173                {
174                        parent->m_children.erase( it );
175                        parent->m_children.push_back( child );
176                        parent->m_dirty = true;
177                }       
178        }
179}
180
181void nv::gui::environment::move_to_bottom( element* child )
182{
183        element* parent = child->m_parent;
184        if ( parent )
185        {
186                auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child );
187                if ( it != parent->m_children.end() )
188                {
189                        parent->m_children.erase( it );
190                        parent->m_children.push_front( child );
191                        parent->m_dirty = true;
192                }
193        }
194}
195
196void 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
203void 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
208void 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 )
220        {
221                recalculate_absolute( o );
222        }
223}
224
225void nv::gui::environment::set_class( element* e, const string& text )
226{
227        e->m_class = text;
228        e->m_dirty = true;
229}
230
231void nv::gui::environment::set_text( element* e, const string& text )
232{
233        e->m_text = text;
234        e->m_dirty = true;
235}
236
237void 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
Note: See TracBrowser for help on using the repository browser.