Move things round a bit.
[dcpomatic.git] / src / gtk / alignment.cc
1 /*
2     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (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
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <iostream>
21 #include <gtkmm.h>
22 #include <cairomm/cairomm.h>
23 #include "alignment.h"
24
25 using namespace std;
26
27 class AlignmentWidget : public Gtk::DrawingArea
28 {
29 public:
30         void set_text_line (int n, string t)
31         {
32                 if (int(_text.size()) < (n + 1)) {
33                         _text.resize (n + 1);
34                 }
35                 
36                 _text[n] = t;
37                 queue_draw ();
38         }
39         
40 private:        
41         bool on_expose_event (GdkEventExpose* ev)
42         {
43                 if (!get_window ()) {
44                         return false;
45                 }
46                 
47                 Cairo::RefPtr<Cairo::Context> c = get_window()->create_cairo_context ();
48                 
49                 Gtk::Allocation a = get_allocation ();
50                 int const w = a.get_width ();
51                 int const h = a.get_height ();
52                 
53                 c->rectangle (0, 0, w, h);
54                 c->set_source_rgb (0, 0, 0);
55                 c->fill ();
56                 
57                 c->set_source_rgb (1, 1, 1);
58                 c->set_line_width (1);
59                 
60                 int const arrow_size = h / 8;
61                 int const head_size = h / 32;
62                 
63                 /* arrow to left edge */
64                 c->move_to (arrow_size, h / 2);
65                 c->line_to (0, h / 2);
66                 c->rel_line_to (head_size, head_size);
67                 c->move_to (0, h / 2);
68                 c->rel_line_to (head_size, -head_size);
69                 c->stroke ();
70                 
71                 /* arrow to right edge */
72                 c->move_to (w - arrow_size, h / 2);
73                 c->line_to (w, h / 2);
74                 c->rel_line_to (-head_size, head_size);
75                 c->move_to (w, h / 2);
76                 c->rel_line_to (-head_size, -head_size);
77                 c->stroke ();
78                 
79                 /* arrow to top edge */
80                 c->move_to (w / 2, arrow_size);
81                 c->line_to (w / 2, 0);
82                 c->rel_line_to (head_size, head_size);
83                 c->move_to (w / 2, 0);
84                 c->rel_line_to (-head_size, head_size);
85                 c->stroke ();
86                 
87                 /* arrow to bottom edge */
88                 c->move_to (w / 2, h - h / 8);
89                 c->line_to (w / 2, h);
90                 c->rel_line_to (head_size, -head_size);
91                 c->move_to (w / 2, h);
92                 c->rel_line_to (-head_size, -head_size);
93                 c->stroke ();
94                 
95                 /* arrow to top-left corner */
96                 c->move_to (arrow_size, arrow_size);
97                 c->line_to (0, 0);
98                 c->rel_line_to (head_size, 0);
99                 c->move_to (0, 0);
100                 c->rel_line_to (0, head_size);
101                 c->stroke ();
102                 
103                 /* arrow to top-right corner */
104                 c->move_to (w - arrow_size, arrow_size);
105                 c->line_to (w, 0);
106                 c->rel_line_to (0, head_size);
107                 c->move_to (w, 0);
108                 c->rel_line_to (-head_size, 0);
109                 c->stroke ();
110                 
111                 /* arrow to bottom-left corner */
112                 c->move_to (arrow_size, h - arrow_size);
113                 c->line_to (0, h);
114                 c->rel_line_to (head_size, 0);
115                 c->move_to (0, h);
116                 c->rel_line_to (0, -head_size);
117                 c->stroke ();
118                 
119                 /* arrow to bottom-right corner */
120                 c->move_to (w - arrow_size, h - arrow_size);
121                 c->line_to (w, h);
122                 c->rel_line_to (-head_size, 0);
123                 c->line_to (w, h);
124                 c->rel_line_to (0, -head_size);
125                 c->stroke ();
126                 
127                 /* text */
128                 int max_height = 0;
129                 for (vector<string>::iterator i = _text.begin(); i != _text.end(); ++i) {
130                         Cairo::TextExtents e;
131                         c->get_text_extents (*i, e);
132                         max_height = max (max_height, int (e.height));
133                 }
134                 
135                 int total_height = max_height * _text.size() * 2;
136                 
137                 for (vector<string>::size_type i = 0; i < _text.size(); ++i) {
138                         Cairo::TextExtents e;
139                         c->get_text_extents (_text[i], e);
140                         c->move_to ((w - e.width) / 2, ((h - total_height) / 2) + ((i * 2) + 1) *  max_height);
141                         c->text_path (_text[i]);
142                         c->stroke ();
143                 }
144                 
145                 return true;
146         }
147
148         std::vector<std::string> _text;
149 };
150
151 Alignment::Alignment (Position p, Size s)
152 {
153         _widget = Gtk::manage (new AlignmentWidget);
154         add (*_widget);
155         show_all ();
156         
157         set_decorated (false);
158         set_resizable (false);
159         set_size_request (s.width, s.height);
160         move (p.x, p.y);
161 }
162
163 void
164 Alignment::set_text_line (int n, string t)
165 {
166         _widget->set_text_line (n, t);
167 }