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

Last change on this file since 318 was 318, checked in by epyon, 11 years ago
  • gui shader now embedded
File size: 6.6 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 )
28        : m_renderer( nullptr ), m_window( w )
29{
30        m_area.dim( dimension( w->get_width(), w->get_height() ) );
31       
32        m_screen           = m_elements.create();
33        element* screen    = m_elements.get( m_screen );
34        screen->m_absolute = m_area;
35        screen->m_relative = m_area;
36
37        m_renderer = new renderer( w );
38}
39
40void nv::gui::environment::load_style( const std::string& filename )
41{
42        m_renderer->load_style( filename );
43}
44
45nv::gui::handle nv::gui::environment::create_element( const rectangle& r )
46{
47        return create_element( m_screen, r );
48}
49
50nv::gui::handle nv::gui::environment::create_element( handle parent, const rectangle& r )
51{
52        if ( parent.is_nil() ) parent = m_screen;
53        handle result = m_elements.create();
54        element* e    = m_elements.get( result );
55        e->m_absolute = r;
56        e->m_relative = r;
57        add_child( parent, result );
58        return result;
59}
60
61void nv::gui::environment::destroy_element( handle e )
62{
63        element* dead_element = m_elements.get( e );
64        if ( dead_element == nullptr ) return;
65        destroy_children( e );
66        remove_child( dead_element->m_parent, e );
67
68        delete dead_element->m_render_data;
69        dead_element->m_render_data = nullptr;
70        dead_element->m_parent = handle();
71
72        m_elements.destroy( e );
73}
74
75void nv::gui::environment::update( handle e, uint32 elapsed )
76{
77        element* el = m_elements.get( e );
78        if ( !el ) return;
79        //      el->on_update( elapsed );
80        if ( el->m_visible )
81        {
82                for ( handle i : el->m_children )
83                {
84                        update( i, elapsed );
85                }
86        }
87        if ( el->m_dirty || el->m_render_data == nullptr )
88        {
89                m_renderer->redraw( el, elapsed );
90                el->m_dirty = false;
91        }
92}
93
94void nv::gui::environment::draw( handle e )
95{
96        element* el = m_elements.get( e );
97        if ( !el ) return;
98        if ( el->m_visible )
99        {
100//              el->on_draw();
101                m_renderer->draw( el );
102                for ( handle i : el->m_children )
103                {
104                        draw(i);
105                }
106        }
107}
108
109void nv::gui::environment::update()
110{
111        update( m_screen, 0 );
112}
113
114void nv::gui::environment::draw()
115{
116        draw( m_screen );
117        m_renderer->draw();
118}
119
120void nv::gui::environment::add_child( handle child )
121{
122        add_child( m_screen, child );
123}
124
125void nv::gui::environment::add_child( handle parent, handle child )
126{
127        element* e = m_elements.get( child );
128        element* p = m_elements.get( parent );
129        if ( e && p )
130        {
131                remove_child( e->m_parent, child );
132                e->m_parent = parent;
133                p->m_children.push_back( child );
134                p->m_child_count++;
135        }
136}
137
138void nv::gui::environment::destroy_children( handle e )
139{
140        element* parent = m_elements.get(e);
141        if ( parent )
142        {
143                while ( !parent->m_children.empty() )
144                {
145                        destroy_element( parent->m_children.front() );
146                }
147        }
148}
149
150
151nv::gui::environment::~environment()
152{
153        destroy_children( handle() );
154        delete m_renderer;
155}
156
157bool nv::gui::environment::process_io_event( const io_event& )
158{
159        return false;
160}
161
162bool nv::gui::environment::process_io_event( handle e, const io_event& ev )
163{
164        element* el = m_elements.get( e );
165        return el && el->m_parent.is_valid() ? process_io_event( el->m_parent, ev ) : false;
166}
167
168nv::gui::handle nv::gui::environment::get_element( const position& p )
169{
170        return get_deepest_child( m_screen, p );
171}
172
173nv::gui::handle nv::gui::environment::get_deepest_child( handle e, const position& p )
174{
175        element* el = m_elements.get(e);
176        if ( !el && !el->m_visible ) return handle();
177
178        handle result;
179        element::list::reverse_iterator it = el->m_children.rbegin();
180
181        while ( it != el->m_children.rend() )
182        {
183                result = get_deepest_child( *it, p );
184                if ( result.is_valid() ) return result;
185                ++it;
186        }
187
188        if ( el->m_absolute.contains(p) ) return e;
189        return handle();
190}
191
192void nv::gui::environment::move_to_top( handle child )
193{
194        element* e      = m_elements.get( child );
195        element* parent = m_elements.get( e->m_parent );
196        if ( e && parent )
197        {
198                auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child );
199                if ( it != parent->m_children.end() )
200                {
201                        parent->m_children.erase( it );
202                        parent->m_children.push_back( child );
203                        parent->m_dirty = true;
204                }       
205        }
206}
207
208void nv::gui::environment::move_to_bottom( handle child )
209{
210        element* e      = m_elements.get( child );
211        element* parent = m_elements.get( e->m_parent );
212        if ( e && parent )
213        {
214                auto it = std::find( parent->m_children.begin(), parent->m_children.end(), child );
215                if ( it != parent->m_children.end() )
216                {
217                        parent->m_children.erase( it );
218                        parent->m_children.push_front( child );
219                        parent->m_dirty = true;
220                }
221        }
222}
223
224void nv::gui::environment::set_relative( handle e, const rectangle& r )
225{
226        element* el = m_elements.get(e);
227        if ( el )
228        {
229                el->m_dirty    = true;
230                el->m_relative = r;
231                recalculate_absolute( e );
232        }
233}
234
235void nv::gui::environment::set_relative( handle e, const position& p )
236{
237        element* el = m_elements.get(e);
238        if ( el )
239        {
240                set_relative( e, rectangle( p, p + el->m_relative.get_size() ) );
241        }
242}
243
244void nv::gui::environment::recalculate_absolute( handle e )
245{
246        element* el = m_elements.get(e);
247        rectangle pabsolute = m_elements.get( el->m_parent )->m_absolute;
248        el->m_absolute = el->m_relative + pabsolute.ul;
249
250        for ( handle o : el->m_children )
251        {
252                recalculate_absolute( o );
253        }
254}
255
256void nv::gui::environment::set_class( handle e, const string& text )
257{
258        element* ep = m_elements.get(e);
259        if ( ep != nullptr )
260        {
261                ep->m_class = text;
262                ep->m_dirty = true;
263        }
264}
265
266void nv::gui::environment::set_text( handle e, const string& text )
267{
268        element* ep = m_elements.get(e);
269        if ( ep != nullptr )
270        {
271                ep->m_text = text;
272                ep->m_dirty = true;
273        }
274}
275
276void nv::gui::environment::remove_child( handle parent, handle child )
277{
278        element* p = m_elements.get( parent );
279        if ( p )
280        {
281                auto it = std::find( p->m_children.begin(), p->m_children.end(), child );
282                if ( it != p->m_children.end() )
283                {
284                        element* e = m_elements.get( *it );
285                        e->m_parent = handle();
286                        p->m_children.erase(it);
287                }       
288        }
289}
290
Note: See TracBrowser for help on using the repository browser.