1/*
2* Copyright (c) 2018 (https://github.com/phase1geo/Minder)
3*
4* This program is free software; you can redistribute it and/or
5* modify it under the terms of the GNU General Public
6* License as published by the Free Software Foundation; either
7* version 2 of the License, or (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12* General Public License for more details.
13*
14* You should have received a copy of the GNU General Public
15* License along with this program; if not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17* Boston, MA 02110-1301 USA
18*
19* Authored by: Trevor Williams <phase1geo@gmail.com>
20*/
21
22using Cairo;
23using Gdk;
24
25public class Stickers {
26
27  private Array<Sticker> _stickers;
28
29  /* Constructor */
30  public Stickers() {
31    _stickers = new Array<Sticker>();
32  }
33
34  /* Clears all of the stored stickers */
35  public void clear() {
36    _stickers.remove_range( 0, _stickers.length );
37  }
38
39  /* Adds the given sticker to our list */
40  public void add_sticker( Sticker sticker ) {
41    _stickers.append_val( sticker );
42  }
43
44  /* Deletes the given sticker from this list */
45  public void remove_sticker( Sticker sticker ) {
46    for( int i=0; i<_stickers.length; i++ ) {
47      if( _stickers.index( i ) == sticker ) {
48        _stickers.remove_index( i );
49        return;
50      }
51    }
52  }
53
54  /* This should be called whenever we select a sticker */
55  public void select_sticker( Sticker sticker ) {
56    remove_sticker( sticker );
57    add_sticker( sticker );
58  }
59
60  /* Returns the sticker located at the given cursor position */
61  public Sticker? is_within( double x, double y ) {
62    for( int i=(int)(_stickers.length - 1); i>=0; i-- ) {
63      var s = _stickers.index( i );
64      if( Utils.is_within_bounds( x, y, s.posx, s.posy, s.width, s.height ) ) {
65        return( s );
66      }
67    }
68    return( null );
69  }
70
71  /* Handles a pan of the canvas */
72  public void pan( double diff_x, double diff_y ) {
73    for( int i=0; i<_stickers.length; i++ ) {
74      var s = _stickers.index( i );
75      s.posx += diff_x;
76      s.posy += diff_y;
77    }
78  }
79
80  /* Adds the sticker extents to the current extents */
81  public void add_extents( ref double x1, ref double y1, ref double x2, ref double y2 ) {
82    for( int i=0; i<_stickers.length; i++ ) {
83      var s = _stickers.index( i );
84      x1 = (s.posx < x1) ? s.posx : x1;
85      y1 = (s.posy < y1) ? s.posx : y1;
86      x2 = ((s.posx + s.width)  > x2) ? (s.posx + s.width)  : x2;
87      y2 = ((s.posy + s.height) > y2) ? (s.posy + s.height) : y2;
88    }
89  }
90
91  /* Saves the sticker to the XML tree */
92  public Xml.Node* save() {
93    Xml.Node* n = new Xml.Node( null, "stickers" );
94    for( int i=0; i<_stickers.length; i++ ) {
95      n->add_child( _stickers.index( i ).save() );
96    }
97    return( n );
98  }
99
100  /* Loads the sticker from the XML tree */
101  public void load( Xml.Node* n ) {
102    for( Xml.Node* it=n->children; it!=null; it=it->next ) {
103      if( (it->type == Xml.ElementType.ELEMENT_NODE) && (it->name == "sticker") ) {
104        var sticker = new Sticker.from_xml( it );
105        _stickers.append_val( sticker );
106      }
107    }
108  }
109
110  /* Draw the sticker on the mind map */
111  public void draw_all( Cairo.Context ctx, Theme theme, double opacity ) {
112    for( int i=0; i<_stickers.length; i++ ) {
113      _stickers.index( i ).draw( ctx, theme, opacity );
114    }
115  }
116
117}
118