diff options
author | Philip Chimento <philip@endlessm.com> | 2013-08-01 13:12:16 -0700 |
---|---|---|
committer | Philip Chimento <philip@endlessm.com> | 2013-08-01 19:04:13 -0700 |
commit | c1dc661f6ea250306c6191e476d61ae58941c2c7 (patch) | |
tree | 95870a7f084ae5cbaeb031fb92cf8e483790d7fb | |
parent | cd175cbb4a0d9a221be65b6aac314bbfeaac0363 (diff) |
Add top bar edge finishing
Add a highlight and shadow, on the bottom of the top bar; two pixels
go over the top bar, and two pixels go over the app content.
Added a smoke test with a button that turns red on press, in order to
test that the two pixels on top of the app content do not catch input
events.
[endlessm/eos-sdk#197]
-rw-r--r-- | endless/eostopbar.c | 25 | ||||
-rw-r--r-- | endless/eoswindow.c | 50 | ||||
-rw-r--r-- | test/smoke-tests/large-content.js | 42 |
3 files changed, 117 insertions, 0 deletions
diff --git a/endless/eostopbar.c b/endless/eostopbar.c index eb0b13e..1b78ecf 100644 --- a/endless/eostopbar.c +++ b/endless/eostopbar.c @@ -66,6 +66,30 @@ eos_top_bar_get_preferred_height (GtkWidget *widget, *natural = _EOS_TOP_BAR_HEIGHT_PX; } +/* Draw the edge finishing on the two lines inside the topbar; see +after_draw_cb() in eoswindow.c for the two lines outside the topbar */ +static gboolean +eos_top_bar_draw (GtkWidget *self_widget, + cairo_t *cr) +{ + GTK_WIDGET_CLASS (eos_top_bar_parent_class)->draw (self_widget, cr); + + gint width = gtk_widget_get_allocated_width (self_widget); + cairo_set_line_width (cr, 1.0); + /* Highlight: #ffffff, opacity 5% */ + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.05); + cairo_move_to (cr, 0, _EOS_TOP_BAR_HEIGHT_PX - 2); + cairo_rel_line_to (cr, width, 0); + cairo_stroke (cr); + /* Baseline: #0a0a0a, opacity 100% */ + cairo_set_source_rgb (cr, 0.039, 0.039, 0.039); + cairo_move_to (cr, 0, _EOS_TOP_BAR_HEIGHT_PX - 1); + cairo_rel_line_to (cr, width, 0); + cairo_stroke (cr); + + return GDK_EVENT_PROPAGATE; +} + static void eos_top_bar_class_init (EosTopBarClass *klass) { @@ -75,6 +99,7 @@ eos_top_bar_class_init (EosTopBarClass *klass) g_type_class_add_private (klass, sizeof (EosTopBarPrivate)); widget_class->get_preferred_height = eos_top_bar_get_preferred_height; + widget_class->draw = eos_top_bar_draw; /* * Emitted when the minimize button has been activated. diff --git a/endless/eoswindow.c b/endless/eoswindow.c index 33f2c79..b9dadf1 100644 --- a/endless/eoswindow.c +++ b/endless/eoswindow.c @@ -50,6 +50,8 @@ #define CSS_TEMPLATE "#%s %s #%s %s" +#define _EOS_TOP_BAR_EDGE_FINISHING_HEIGHT_PX 2 + G_DEFINE_TYPE (EosWindow, eos_window, GTK_TYPE_APPLICATION_WINDOW) #define WINDOW_PRIVATE(o) \ @@ -62,6 +64,7 @@ struct _EosWindowPrivate GtkWidget *top_bar; GtkWidget *main_area; GtkWidget *overlay; + GtkWidget *edge_finishing; GtkWidget *current_background; GtkWidget *next_background; GtkWidget *background_stack; @@ -567,6 +570,39 @@ on_close_clicked_cb (GtkWidget* top_bar, } } +/* Make sure that the edge finishing does not catch input events */ +static void +after_edge_finishing_realize_cb (GtkWidget *edge_finishing) +{ + cairo_rectangle_int_t empty = { 0, 0, 0, 0 }; + cairo_region_t *empty_region = cairo_region_create_rectangle (&empty); + gdk_window_input_shape_combine_region (gtk_widget_get_window (edge_finishing), + empty_region, 0, 0); + cairo_region_destroy (empty_region); +} + +/* Draw the edge finishing on the two lines on top of the window's content; +see eos_top_bar_draw() for the two lines inside the top bar */ +static gboolean +on_edge_finishing_draw_cb (GtkWidget *edge_finishing, + cairo_t *cr) +{ + gint width = gtk_widget_get_allocated_width (edge_finishing); + cairo_set_line_width (cr, 1.0); + /* Shadow 1: #000000, opacity 15% */ + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.15); + cairo_move_to (cr, 0, 0); + cairo_rel_line_to (cr, width, 0); + cairo_stroke (cr); + /* Shadow 2: #000000, opacity 5% */ + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.05); + cairo_move_to (cr, 0, 1); + cairo_rel_line_to (cr, width, 0); + cairo_stroke (cr); + + return GDK_EVENT_PROPAGATE; +} + static void eos_window_init (EosWindow *self) { @@ -604,6 +640,20 @@ eos_window_init (EosWindow *self) self->priv->main_area = eos_main_area_new (); gtk_overlay_add_overlay (GTK_OVERLAY (self->priv->overlay), self->priv->main_area); + self->priv->edge_finishing = gtk_drawing_area_new (); + gtk_widget_set_vexpand (self->priv->edge_finishing, FALSE); + gtk_widget_set_valign (self->priv->edge_finishing, GTK_ALIGN_START); + /* has_window == FALSE is necessary for not catching input events */ + gtk_widget_set_has_window (self->priv->edge_finishing, FALSE); + gtk_widget_set_size_request (self->priv->edge_finishing, + -1, _EOS_TOP_BAR_EDGE_FINISHING_HEIGHT_PX); + g_signal_connect_after (self->priv->edge_finishing, "realize", + G_CALLBACK (after_edge_finishing_realize_cb), NULL); + g_signal_connect (self->priv->edge_finishing, "draw", + G_CALLBACK (on_edge_finishing_draw_cb), NULL); + gtk_overlay_add_overlay (GTK_OVERLAY (self->priv->overlay), + self->priv->edge_finishing); + gtk_window_set_decorated (GTK_WINDOW (self), FALSE); gtk_window_maximize (GTK_WINDOW (self)); diff --git a/test/smoke-tests/large-content.js b/test/smoke-tests/large-content.js new file mode 100644 index 0000000..da34f53 --- /dev/null +++ b/test/smoke-tests/large-content.js @@ -0,0 +1,42 @@ +// Copyright 2013 Endless Mobile, Inc. + +const Lang = imports.lang; +const Endless = imports.gi.Endless; +const Gdk = imports.gi.Gdk; +const Gtk = imports.gi.Gtk; +const GObject = imports.gi.GObject; + +const TEST_APPLICATION_ID = 'com.endlessm.example.test'; + +const TestApplication = new Lang.Class ({ + Name: 'TestApplication', + Extends: Endless.Application, + + vfunc_startup: function() { + this.parent(); + + let big_button = new Gtk.Button({ + label: "BIG OL BUTTON" + }); + big_button.override_background_color(Gtk.StateFlags.NORMAL, + new Gdk.RGBA({ red: 0, green: 0, blue: 1, alpha: 1 })); + big_button.override_background_color(Gtk.StateFlags.ACTIVE, + new Gdk.RGBA({ red: 1, green: 0, blue: 0, alpha: 1 })); + //big_button.set_size_request(9999, 9999); + + let window = new Endless.Window({ + application: this + }); + window.get_page_manager().add(big_button); + // window.connect("size-allocate", function(w, alloc) { + // print("Win width", alloc.width); + // print("Win height", alloc.height); + // }); + + window.show_all(); + } +}); + +let app = new TestApplication({ application_id: TEST_APPLICATION_ID, + flags: 0 }); +app.run(ARGV); |