DrawTrace.hpp 14.2 KB
Newer Older
1 2 3 4 5 6 7
/*!
 *\file DrawTrace.hpp
 */

#ifndef DRAW_TRACE_HPP
#define DRAW_TRACE_HPP

8 9
#include <string>

10 11
#include "resource.hpp"

12
//#include "../render/render_opengl.hpp"
13
#include "../message/Message.hpp"
14

Clément Vuchener's avatar
Clément Vuchener committed
15
#include "DrawTree.hpp"
16 17

/*!
18 19
 * \class DrawTrace
 * \brief Browse the trace and call back T drawing methods
20 21 22 23 24 25 26 27
 */
template<class T>
class DrawTrace 
{

protected:

    //  Interface_graphic* _window;
28 29 30
    std::list<const Container *> _entity_containers; // Containers with states or events
    std::list<const Container *> _link_containers; // Containers with links
    std::list<const Container *> _variable_containers; // Containers with variables
31
    std::map<const Container *, Element_pos, std::less<const Container *> > _container_positions;
32 33
   
    /*!
34 35 36
     * \brief The default height for containers.
     */
    static const float _DRAWING_CONTAINER_HEIGHT_DEFAULT = 1.2f;
37
     
38 39 40 41
    /*!
     * \brief The default width for containers.
     */
    static const float _DRAWING_CONTAINER_WIDTH_DEFAULT = 2.5f;
42

43 44 45 46
    /*!
     * \brief The default horizontal space between containers.
     */
    static const float _DRAWING_CONTAINER_H_SPACE_DEFAULT = 0.1f;
47

48 49 50 51
    /*!
     * \brief The default vertical space between containers.
     */
    static const float _DRAWING_CONTAINER_V_SPACE_DEFAULT = 0.2f;
52 53 54


    /*!
55 56 57
     * \brief The default height for states.
     */
    static const float _DRAWING_STATE_HEIGHT_DEFAULT = 1.2f;
58
 
59 60 61 62
    /*!
     * \brief The default vertical space between states.
     */
    static const float _DRAWING_STATE_V_SPACE_DEFAULT = 0.2f;
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87


    /*!
     * \brief Geometrical informations about the trace shape.
     */
    Element_pos _container_width;
    Element_pos _container_height;
    Element_pos _container_h_space;
    Element_pos _container_v_space;
    
    Element_pos _state_height;
    Element_pos _state_v_space;
 

public:

    /***********************************
     *
     * Constructor and destructor.
     *
     **********************************/

    /*!
     * \brief The default constructor
     */
88
    DrawTrace() {
89 90

        //   _window = NULL;
Olivier Lagrasse's avatar
Olivier Lagrasse committed
91 92 93 94
        _container_width = _DRAWING_CONTAINER_WIDTH_DEFAULT;
        _container_height = _DRAWING_CONTAINER_HEIGHT_DEFAULT;
        _container_h_space = _DRAWING_CONTAINER_H_SPACE_DEFAULT;
        _container_v_space = _DRAWING_CONTAINER_V_SPACE_DEFAULT;
95
        
Olivier Lagrasse's avatar
Olivier Lagrasse committed
96 97
        _state_height = _DRAWING_STATE_HEIGHT_DEFAULT;
        _state_v_space = _DRAWING_STATE_V_SPACE_DEFAULT;
98 99 100 101 102 103 104

    }


    /*!
     * \brief The destructor
     */
105 106
    virtual ~DrawTrace() {
    
107 108 109 110 111 112 113 114 115 116 117 118 119 120
    }



    /***********************************
      *
      * Building functions.
      *
      **********************************/


    /*!
     * \brief The trace building function.
     * \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
121
     * \param trace the trace data.
122
     */
123
    void build(T* draw_object, Trace* trace) {
124 125 126 127

        draw_object->start_draw();

        draw_object->start_draw_containers();
128
        browse_container_tree(draw_object, trace);
129 130
        draw_object->end_draw_containers();

131
        browse_entities(draw_object);
132 133 134 135 136 137 138 139 140 141 142

        draw_object->end_draw();
    }


    /***********************************
     *
     * Browsing functions.
     *
     **********************************/
    
143
    inline void browse_container_tree(T* draw_object, Trace* trace){
144
        /*** Drawing containers ***/
145
        int position = 0;
146
        
147 148
        const list<Container *> *root_containers = trace->get_root_containers();
        if (root_containers->empty()) {
149
            *Message::get_instance() << "There is no container. The trace can not be drawn." << Message::endw;
150
        }
151
        else
152 153 154 155 156
            for (list<Container *>::const_iterator i = root_containers->begin();
                i != root_containers->end();
                i++)
                position += browse_container(draw_object, *i, position, 0);
        
157
    }/* end browse_container_tree */
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
    
    int browse_container(T* draw_object, const Container *container, int position, int depth) {
        int size = 0;
        
        // Draw children
        const list<Container *> *children = container->get_children();
        for (list<Container *>::const_iterator i = children->begin();
            i != children->end();
            i++) {
            size += browse_container(draw_object, (*i), position+size, depth+1);
        }
        
        // Store the position to draw links
        _container_positions[container] = position + size; // First line after children
        
        // Use one line for states and events
        if (!container->get_states()->empty() || !container->get_events()->empty()) {
            size++;
            _entity_containers.push_back(container);
        }
        
179
        // Use one line for each variable
180 181 182 183 184 185 186 187 188 189 190 191 192 193
        if (container->get_variable_number() > 0) {
            _variable_containers.push_back(container);
            size += container->get_variable_number();
        }
        
        // Push containers with links to draw
        if (!container->get_links()->empty())
            _link_containers.push_back(container);
        
        // Draw this container
        draw_container(draw_object, position, size, depth, container->get_name().to_string());
        
        return size;
    }
194

195 196 197 198 199 200 201 202
    /*!
     * \brief Draw a container
     * \param draw_object Object that contains drawing methods to call
     * \param position Starting line of the container
     * \param size Height of the container in number of line
     * \param depth Depth of container in the tree
     * \param text Name of the container
     */
203 204 205 206 207 208 209
    inline void draw_container(T* draw_object, int position, int size, int depth, const std::string &text) {
        Element_pos x = depth*(_container_width+_container_h_space) + _container_h_space/2;
        Element_pos y = position*(_container_height+_container_v_space) + _container_v_space/2;
        Element_pos height = size*(_container_height+_container_v_space) - _container_v_space;
        draw_object->draw_container(x, y, _container_width, height);
        draw_object->draw_container_text(x, y+height/2, text);
    }
210

Clément Vuchener's avatar
Clément Vuchener committed
211 212 213
    /*!
     * \brief Browse the states list and draw them
     */
214 215
    inline void browse_entities(T* draw_object) {
        const Container *container;
216
        BinaryTree<State> *state_tree;//MODIF
Clément Vuchener's avatar
Clément Vuchener committed
217
        BinaryTree<Event> *event_tree;
218 219
        const list<Link *> *link_list;
        Link *link;
220 221 222
        const map<VariableType *, Variable *> *variable_map;
        Variable *var;
        const list<pair<Date, Double> > *variable_values;
223 224
        //        const map<std::string, Value *> *extra_fields;
        //        const Color *color;
225
        int position;
226
        
227 228 229 230 231 232
        draw_object->start_draw_states();
        for (list<const Container *>::const_iterator c = _entity_containers.begin();
            c != _entity_containers.end();
            c++) {
            container = *c;
            position = _container_positions[container];
233
	        
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
            state_tree = container->get_states();
            event_tree = container->get_events();
            if (!state_tree->empty() || !event_tree->empty()) {
                // Browse states

        
                DrawTree<T, State>(draw_object, position, 0.0,
                                   _container_height, _container_v_space, _state_height, _state_v_space)
                    .draw_tree(state_tree, &Interval(Date(0.0), Date(500.0)));
                /*
                  for (list<State *>::const_iterator i = state_list->begin();
                  i != state_list->end();
                  i++) {
	          
                  state = *i;
                  map<std::string, Value *>::const_iterator field;
                  
                  // Search the color
                  if (state->get_value() &&
                  !state->get_value()->get_extra_fields()->empty() &&
                  ((field = state->get_value()->get_extra_fields()->find(std::string("Color"))) != extra_fields->end())) {
                  /* Call the object state drawing function with the state color */ 
                /*                        color = (const Color *)(*field).second;
                                          draw_state(draw_object, state->get_start_time().get_value(), state->get_end_time().get_value(), position,
                                          color->get_red(), color->get_green(), color->get_blue());
                                          }
                                          else {
                                          /* Call the object state drawing function with default color */ 
                /*                        draw_state(draw_object, state->get_start_time().get_value(), state->get_end_time().get_value(), position, 0.7, 0.7, 0.75);             
                                          }
                                          }/* end for */
Clément Vuchener's avatar
Clément Vuchener committed
265
                
266
                // Browse events
Clément Vuchener's avatar
Clément Vuchener committed
267
                DrawTree<T, Event>(draw_object, position, 0.0,
268 269
                                   _container_height, _container_v_space, _state_height, _state_v_space)
                    .draw_tree(event_tree, &Interval(Date(0.0), Date(500.0)));
Clément Vuchener's avatar
Clément Vuchener committed
270
                /*for (list<Event *>::const_iterator i = event_list->begin();
271 272 273 274
                    i != event_list->end();
                    i++) {
    	               
                    event = *i;
Clément Vuchener's avatar
Clément Vuchener committed
275
                    // Call the object state drawing function 
276
                     draw_event(draw_object, event->get_time().get_value(), position); 
Clément Vuchener's avatar
Clément Vuchener committed
277
                }*/
278 279
            }
            
Clément Vuchener's avatar
Clément Vuchener committed
280 281
            
            
282
        }/* end while (!_stack_states.empty()) */
Olivier Lagrasse's avatar
Olivier Lagrasse committed
283 284

        draw_object->end_draw_states();
285
        
Olivier Lagrasse's avatar
Olivier Lagrasse committed
286 287 288

        draw_object->start_draw_arrows();

289 290 291 292
        for (list<const Container *>::const_iterator c = _link_containers.begin();
            c != _link_containers.end();
            c++) {
            container = *c;
293 294 295 296 297 298 299 300
	        
	        // Browse links
	        link_list = container->get_links();
            for (list<Link *>::const_iterator it = link_list->begin();
                it != link_list->end();
                it++) {
	               
                link = *it;
301 302
                 draw_link(draw_object, link->get_start_time().get_value(), link->get_end_time().get_value(), 
                  _container_positions[link->get_source()], _container_positions[link->get_destination()]); 
303 304 305 306
            }/* end for */
            

        }/* end while (!_stack_states.empty()) */
Olivier Lagrasse's avatar
Olivier Lagrasse committed
307 308

        draw_object->end_draw_arrows();
309
        
310
        draw_object->start_draw_counter();
311
     
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
        for (list<const Container *>::const_iterator c = _entity_containers.begin();
            c != _entity_containers.end();
            c++) {
            container = *c;
            position = _container_positions[container];
            if (!container->get_states()->empty() || !container->get_events()->empty())
                position++;
            // Browse variables
	        variable_map = container->get_variables();
            for (map<VariableType *, Variable *>::const_iterator i = variable_map->begin();
                i != variable_map->end();
                i++) {
    	        
    	        var = (*i).second;
                double min = var->get_min().get_value();
                double max = var->get_max().get_value();
                variable_values = var->get_values();
                
330
                draw_variable_value(draw_object, 0.0, 0.0, position);
331 332 333 334 335 336
                for (list<pair<Date, Double> >::const_iterator value = variable_values->begin();
                    value != variable_values->end();
                    value++) {
                    /* Call the object state drawing function */ 
                    draw_variable_value(draw_object, (*value).first.get_value(), ((*value).second.get_value()-min)/(max-min), position); 
                }
337
                draw_variable_value(draw_object, 0.0, 0.0, position);
338 339
                position++; // One line was used
            }/* end for */
340
        }
341
        draw_object->end_draw_counter();
342 343 344

    }
    
345 346 347 348 349 350 351 352 353 354
    /*!
     * \brief Draw a state
     * \param draw_object Object that contains the drawing methods
     * \param starttime Time when the state begins
     * \param endtime Time when the state ends
     * \param position Line where the state is drawn
     * \param r Red value of the state color
     * \param g Green value of the state color
     * \param b Blue value of the state color
     */
355
    /*    inline void draw_state(T *draw_object, double starttime, double endtime, int position, double r, double g, double b) {
356 357
        Element_pos y = position*(_container_height+_container_v_space) + _container_v_space/2;
        draw_object->draw_state(starttime, endtime, y, _state_height, r, g, b);
358
        }*/
359
    
360 361 362 363 364 365
    /*!
     * \brief Draw an event
     * \param draw_object Object that contains the drawing methods
     * \param time Time of the event
     * \param position Line where the event is drawn
     */
Clément Vuchener's avatar
Clément Vuchener committed
366
    /*inline void draw_event(T *draw_object, double time, int position) {
367 368
        Element_pos y = position*(_container_height+_container_v_space) + _container_v_space/2;
        draw_object->draw_event(time, y, _state_height);
Clément Vuchener's avatar
Clément Vuchener committed
369
    }*/
370
    
371 372 373 374 375 376 377
    /*!
     * \brief Draw a point of a variable curve
     * \param draw_object Object that contains the drawing methods
     * \param time Time of the point
     * \param value Value of of the variable (between 0.0 and 1.0)
     * \param position Line where the variable is drawn
     */
378 379 380 381 382 383
    inline void draw_variable_value(T *draw_object, double time, double value, int position) {
        Element_pos y = (position+1)*(_container_height+_container_v_space) - _container_v_space/2 -
            value*_container_height;
        draw_object->draw_counter(time, y);
    }
    
384 385 386 387 388 389 390 391
    /*!
     * \brief Draw a link
     * \param draw_object Object that contains the drawing methods
     * \param starttime Time of the start of the link
     * \param endtime Time of the end of the link
     * \param start Line of the start of the link
     * \param end Line of the end of the link
     */
392 393 394 395 396
    inline void draw_link(T *draw_object, double starttime, double endtime, int start, int end) {
        Element_pos y1 = ((double)start+0.5)*(_container_height+_container_v_space);
        Element_pos y2 = ((double)end+0.5)*(_container_height+_container_v_space);
        draw_object->draw_arrow(starttime, endtime, y1, y2);
    }
397 398 399
};

#endif