2 Copyright 2009 by Hans Baier
11 public abstract class DisplayBase
: DrawingArea
{
12 private Cairo
.Surface? cache_surface
= null;
26 public double inner_x
{
28 return _show_glass_rim ?
7.5 : 3.5;
32 public double inner_y
{
34 return _show_glass_rim ?
6.5 : 3.5;
38 private bool _show_glass_rim
= true;
39 public bool show_glass_rim
{
40 get { return _show_glass_rim
; }
42 _show_glass_rim
= value
;
48 public double inner_width
{
50 return _show_glass_rim ?
(_width
- 14) : (_width
- 6);
54 public double inner_height
{
56 return _show_glass_rim ?
(_height
- 13) : (_height
- 6);
60 protected int _width
= 383;
61 protected int _height
= 72;
63 private bool _show_matrix
= true;
64 [Description(nick
="show matrix", blurb
="Whether a pixel matrix should be drawn in the display background (much faster if false)")]
65 public bool show_matrix
{
66 get { return _show_matrix
; }
75 add_events (Gdk
.EventMask
.BUTTON_PRESS_MASK
76 | Gdk
.EventMask
.BUTTON_RELEASE_MASK
77 | Gdk
.EventMask
.POINTER_MOTION_MASK
);
78 draw
.connect(on_draw
);
81 public static void outer_rim_for_display(Cairo
.Context cr
, double x
, double y
, double w
, double h
, Color outside
, double rounded_corner_radius
= 5.0) {
88 Color
.parse("#010101", out inside
);
89 Color
.parse("#525357", out inside_left
);
90 Color
.parse("#444444", out inside_top
);
91 inside_right
= outside
;
92 inside_bottom
= outside
;
94 var horiz_rim_left_x
= rounded_corner_radius
- 1;
95 var horiz_rim_right_x
= w
- rounded_corner_radius
+ 2;
97 var bottom_rim_y
= h
- 1.5;
99 var vert_rim_top_y
= rounded_corner_radius
- 1;
100 var vert_rim_bottom_y
= h
- rounded_corner_radius
+ 1;
101 var right_rim_x
= w
- 0.5;
102 var left_rim_x
= 1.5;
105 rounded_rect (cr
, 1, 1, w
- 2, h
- 2, rounded_corner_radius
, rounded_corner_radius
);
106 set_source_color(cr
, inside
);
110 cr
.move_to (horiz_rim_left_x
, top_rim_y
);
111 cr
.line_to (horiz_rim_right_x
, top_rim_y
);
112 set_source_color(cr
, inside_top
);
116 cr
.move_to (right_rim_x
, vert_rim_top_y
);
117 cr
.line_to (right_rim_x
, vert_rim_bottom_y
);
118 set_source_color (cr
, inside_right
);
122 cr
.move_to (horiz_rim_right_x
, bottom_rim_y
);
123 cr
.line_to (horiz_rim_left_x
, bottom_rim_y
);
124 set_source_color (cr
, inside_bottom
);
128 cr
.move_to (left_rim_x
, vert_rim_bottom_y
);
129 cr
.line_to (left_rim_x
, vert_rim_top_y
);
130 set_source_color (cr
, inside_left
);
134 public static const string matrix_dot_base_color
= "#41403e";
135 public static Gdk
.Color
matrix_dot_color () {
136 return shade_color (color_from_string (matrix_dot_base_color
), 0.5);
139 public static void dot_matrix(Cairo
.Context cr
, double x
, double y
, double w
, double h
, Gdk
.Color color
) {
141 set_source_color (cr
, color
);
142 for (double i
= x
+ 1; i
< x
+ w
; i
++) {
143 for (double j
= y
+ 1; j
< y
+ h
; j
++) {
144 if (((long)i
% 2) == 0 && ((long)j
% 2) == 1) {
145 cr
.move_to (i
- 0.5, j
);
146 cr
.line_to (i
+ 0.5, j
);
154 public static void inner_glass_rim(Cairo
.Context cr
, double x
, double y
, double w
, double h
, double radius
= 4.0) {
156 Color rim_left_bottom1
;
158 Color rim_left_bottom2
;
160 Color rim_right_bottom
;
165 Color
.parse("#2a282d", out rim_left_top1
);
166 Color
.parse("#2b2c2e", out rim_left_bottom1
);
167 Color
.parse("#1b191c", out rim_left_top2
);
168 Color
.parse("#1d181f", out rim_left_bottom2
);
169 Color
.parse("#3d3b3c", out rim_right_top
);
170 Color
.parse("#3a4036", out rim_right_bottom
);
171 Color
.parse("#605b5f", out rim_top1
);
172 Color
.parse("#2f2e33", out rim_top2
);
173 Color
.parse("#3e403d", out rim_bottom
);
176 Color
.parse("#ff0000", out test
);
178 double ARC_TO_BEZIER
= 0.55228475;
180 if (radius
> w
- radius
)
182 if (radius
> h
- radius
)
185 // approximate (quite close) the arc using a bezier curve
186 var c
= ARC_TO_BEZIER
* radius
;
188 cr
.set_line_width(1.0);
191 cr
.move_to ( x
+ radius
, y
);
192 cr
.rel_line_to ( w
- 2 * radius
, 0.0);
193 set_source_color (cr
, rim_top1
);
197 cr
.move_to ( x
+ radius
, y
+ 1);
198 cr
.rel_line_to ( w
- 2 * radius
, 0.0);
199 set_source_color(cr
, rim_top2
);
203 cr
.move_to (x
+ w
- radius
, y
);
204 cr
.rel_curve_to ( c
, 0.0, radius
, c
, radius
, radius
);
205 set_source_color (cr
, rim_top1
);
209 cr
.move_to (x
+ w
, y
+ radius
);
210 var dy
= h
- 2 * radius
;
211 cr
.set_source (create_gradient(0, 0, 0, dy
, rim_right_top
, rim_right_bottom
));
212 cr
.rel_line_to (0, dy
);
215 // right bottom corner
216 cr
.move_to (x
+ w
, y
+ h
- radius
);
217 cr
.rel_curve_to ( 0.0, c
, c
- radius
, radius
, -radius
, radius
);
218 set_source_color (cr
, rim_right_bottom
);
222 cr
.move_to (x
+ w
- radius
, y
+ h
);
223 cr
.rel_line_to (-w
+ 2 * radius
, 0);
224 set_source_color (cr
, rim_bottom
);
227 // bottom left corner
228 cr
.move_to (x
+ radius
, y
+ h
);
229 cr
.rel_curve_to ( -c
, 0, -radius
, -c
, -radius
, -radius
);
230 set_source_color (cr
, rim_left_bottom1
);
234 cr
.move_to (x
, y
+ h
- radius
);
235 cr
.set_source (create_gradient(0, 0, 0, y
, rim_left_top1
, rim_left_bottom1
));
236 cr
.rel_line_to (0, -h
+ 2 * radius
);
240 cr
.move_to (x
+ 1, y
+ h
- radius
);
241 cr
.set_source (create_gradient(0, 0, 0, y
, rim_left_top2
, rim_left_bottom2
));
242 cr
.rel_line_to (0, -h
+ 2 * radius
);
246 cr
.move_to (x
, y
+ radius
);
247 cr
.rel_curve_to (0.0, -c
, radius
- c
, -radius
, radius
, -radius
);
248 set_source_color (cr
, rim_top1
);
251 // top left corner (adding thickness)
252 cr
.move_to (x
+ 1, y
+ radius
);
253 cr
.rel_curve_to (0.0, -c
, radius
- c
, -radius
, radius
, -radius
+ 1);
254 set_source_color (cr
, rim_top1
);
259 public static const string text_color_default
= "#9fc717";
261 public static void set_font (
264 string family
= "FreeSans",
265 Cairo
.FontSlant slant
= Cairo
.FontSlant
.NORMAL
,
266 Cairo
.FontWeight weight
= Cairo
.FontWeight
.NORMAL
) {
268 cr
.select_font_face (family
, slant
, weight
);
269 cr
.set_font_size (size
);
272 public static void text (Cairo
.Context cr
, string text
, double x
, double y
, double size
, string color
= text_color_default
) {
274 Color
.parse (color
, out text_color
);
275 set_source_color (cr
, text_color
);
282 public static void lcd(Cairo
.Context cr
, double w
, double h
, double radius
= 5.0) {
284 Color green_rim_bottom
;
285 Color
.parse ("#2c4329", out green_rim_top
);
286 Color
.parse ("#101d09", out green_rim_bottom
);
287 cr
.set_source (create_gradient (0.0, 0.0, 0.0, h
, green_rim_top
, green_rim_bottom
, 1.0, 1.0));
288 rounded_rect (cr
, 0.0, 0.0, w
, h
, radius
, radius
);
291 cr
.set_source (create_gradient (0.0, 0.0, 0.0, h
, green_rim_top
, green_rim_bottom
, 0.5, 0.5));
292 rounded_rect (cr
, 0.0, 0.0, w
, h
, radius
, radius
);
296 public static void reflection(Cairo
.Context cr
, double w
, double h
, double reflection_start
= -1) {
298 if (reflection_start
< 0)
299 reflection_start
= h
- 3;
302 cr
.move_to (0.0, 0.0);
303 cr
.line_to (0.0, reflection_start
);
304 cr
.curve_to (w
/ 3.0, h
/ 3.0, w
* 2.0 / 3.0, 17.0 * h
/ 59.0, w
, 15.0 * h
/ 59.0);
307 cr
.set_source_rgba(0.8, 0.9, 0.1, 0.06);
311 /* Widget is asked to draw itself */
312 public bool on_draw (Cairo
.Context c
) {
313 //Color test_color = color_from_string ("#ff0000");
314 Gtk
.Allocation allocation
;
315 get_allocation(out allocation
);
317 if (_width
!= allocation
.width
|| _height
!= allocation
.height
) {
318 _width
= allocation
.width
;
319 _height
= allocation
.height
;
320 cache_surface
= null;
323 // Create a Cairo context
324 var cr
= Gdk
.cairo_create (this
.get_window());
325 set_line_width_from_device (cr
);
328 if (cache_surface
== null) {
329 cache_surface
= new Cairo
.Surface
.similar (cr
.get_target (),
330 Cairo
.Content
.COLOR_ALPHA
,
334 Cairo
.Context cache_cr
= new Cairo
.Context ( cache_surface
);
336 set_line_width_from_device (cache_cr
);
338 DisplayBase
.outer_rim_for_display (cache_cr
, 0, 0, _width
, _height
, style
.bg
[(int)Gtk
.StateType
.NORMAL
]);
340 if (show_glass_rim
) {
341 cache_cr
.translate (4.5, 3.5);
342 inner_glass_rim (cache_cr
, 0, 0, _width
- 8, _height
- 9, 2);
345 cache_cr
.translate (3.0, 3.0);
347 lcd(cache_cr
, inner_width
, inner_height
, _height
> 30 ?
5.0 : 3.0);
350 dot_matrix (cache_cr
, _show_glass_rim ?
0 : 0.5, _show_glass_rim ?
0 : 0.5, inner_width
, inner_height
, matrix_dot_color ());
354 cr
.set_source_surface (cache_surface
, 0, 0);
357 cr
.translate (inner_x
, inner_y
);
361 reflection(cr
, inner_width
, inner_height
);
367 protected abstract bool draw_contents(Cairo
.Context cr
);
370 } // namespace Prolooks