[gnome-documents] presentation: Show a thumbnail for each display
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-documents] presentation: Show a thumbnail for each display
- Date: Tue, 30 Sep 2014 15:00:47 +0000 (UTC)
commit a4a62a077542e794dcb32e82f3a180e425b44b41
Author: Debarshi Ray <debarshir gnome org>
Date: Mon Sep 29 17:14:46 2014 +0200
presentation: Show a thumbnail for each display
Based on cc-display-panel.c from gnome-control-center.
https://bugzilla.gnome.org/show_bug.cgi?id=737580
src/Makefile-lib.am | 3 +
src/lib/gd-display-preview.c | 250 ++++++++++++++++++++++++++++++++++++++++++
src/lib/gd-display-preview.h | 47 ++++++++
src/presentation.js | 57 ++++------
4 files changed, 320 insertions(+), 37 deletions(-)
---
diff --git a/src/Makefile-lib.am b/src/Makefile-lib.am
index 51347b5..33c14d5 100644
--- a/src/Makefile-lib.am
+++ b/src/Makefile-lib.am
@@ -14,6 +14,7 @@ gdprivate_source_h = \
lib/gd-nav-bar.h \
lib/gd-bookmark.h \
lib/gd-bookmarks.h \
+ lib/gd-display-preview.h \
lib/gd-places-page.h \
lib/gd-places-bookmarks.h \
lib/gd-places-links.h \
@@ -26,6 +27,7 @@ gdprivate_source_c = \
lib/gd-nav-bar.c \
lib/gd-bookmark.c \
lib/gd-bookmarks.c \
+ lib/gd-display-preview.c \
lib/gd-places-page.c \
lib/gd-places-bookmarks.c \
lib/gd-places-links.c \
@@ -59,6 +61,7 @@ GdPrivate_1_0_gir_CFLAGS = $(AM_CPPFLAGS) $(gdprivate_cflags)
GdPrivate_1_0_gir_SCANNERFLAGS = --warn-all --symbol-prefix=gd --identifier-prefix=Gd
GdPrivate_1_0_gir_INCLUDES = \
GData-0.0 \
+ GnomeDesktop-3.0 \
Goa-1.0 \
Gtk-3.0 \
EvinceDocument-3.0 \
diff --git a/src/lib/gd-display-preview.c b/src/lib/gd-display-preview.c
new file mode 100644
index 0000000..910f760
--- /dev/null
+++ b/src/lib/gd-display-preview.c
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gd-display-preview.h"
+
+#include <glib.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-rr.h>
+#include <libgnome-desktop/gnome-bg.h>
+
+struct _GdDisplayPreview {
+ GtkDrawingArea parent_instance;
+ GnomeRROutputInfo *info;
+ gboolean clone;
+ gint width;
+ gint height;
+};
+
+struct _GdDisplayPreviewClass {
+ GtkDrawingAreaClass parent_class;
+};
+
+G_DEFINE_TYPE (GdDisplayPreview, gd_display_preview, GTK_TYPE_DRAWING_AREA);
+
+#define TOP_BAR_HEIGHT 5
+#define DISPLAY_PREVIEW_LIST_HEIGHT 55
+
+enum {
+ PROP_CLONE = 1,
+ PROP_INFO,
+ NUM_PROPERTIES
+};
+
+static gboolean
+gd_display_preview_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GdDisplayPreview *self = GD_DISPLAY_PREVIEW (widget);
+ GdkPixbuf *pixbuf;
+ GnomeRRRotation rotation;
+ gboolean active;
+ gint allocated_height;
+ gint allocated_width;
+ gint height;
+ gint width;
+ gint x, y;
+
+ allocated_width = gtk_widget_get_allocated_width (widget);
+ allocated_height = gtk_widget_get_allocated_height (widget);
+ rotation = gnome_rr_output_info_get_rotation (self->info);
+
+ x = y = 0;
+ height = self->height;
+ width = self->width;
+
+ if ((rotation & GNOME_RR_ROTATION_90) || (rotation & GNOME_RR_ROTATION_270)) {
+ gint tmp;
+
+ /* swap width and height */
+ tmp = width;
+ width = height;
+ height = tmp;
+ }
+
+ /* scale to fit allocation */
+ if (width / (double) height < allocated_width / (double) allocated_height) {
+ width = allocated_height * (width / (double) height);
+ height = allocated_height;
+ } else {
+ height = allocated_width * (height / (double) width);
+ width = allocated_width;
+ }
+
+ x = (allocated_width / 2.0) - (width / 2.0);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+
+ if (gnome_rr_output_info_is_active (self->info)) {
+ GdkScreen *screen;
+ GnomeBG *bg;
+ GnomeDesktopThumbnailFactory *factory;
+ GSettings *settings;
+
+ bg = gnome_bg_new ();
+ settings = g_settings_new ("org.gnome.desktop.background");
+ gnome_bg_load_from_preferences (bg, settings);
+
+ factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+ screen = gdk_screen_get_default ();
+
+ pixbuf = gnome_bg_create_thumbnail (bg, factory, screen, width, height);
+
+ g_object_unref (factory);
+ g_object_unref (settings);
+ g_object_unref (bg);
+ } else {
+ pixbuf = NULL;
+ }
+
+ if (gnome_rr_output_info_get_primary (self->info) || self->clone) {
+ y += TOP_BAR_HEIGHT;
+ height -= TOP_BAR_HEIGHT;
+ }
+
+ if (pixbuf != NULL)
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, x + 1, y + 1);
+ else
+ cairo_set_source_rgb (cr, 0.3, 0.3, 0.3);
+
+ cairo_rectangle (cr, x + 1, y + 1, width - 2, height - 2);
+ cairo_fill (cr);
+
+ g_clear_object (&pixbuf);
+
+ return GDK_EVENT_STOP;
+}
+
+static void
+gd_display_preview_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdDisplayPreview *self = GD_DISPLAY_PREVIEW (object);
+
+ switch (prop_id) {
+ case PROP_CLONE:
+ self->clone = g_value_get_boolean (value);
+ break;
+ case PROP_INFO:
+ self->info = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gd_display_preview_constructed (GObject *object)
+{
+ GdDisplayPreview *self = GD_DISPLAY_PREVIEW (object);
+ gint height;
+ gint width;
+
+ G_OBJECT_CLASS (gd_display_preview_parent_class)->constructed (object);
+
+ if (gnome_rr_output_info_is_active (self->info)) {
+ gnome_rr_output_info_get_geometry (self->info, NULL, NULL, &width, &height);
+ } else {
+ width = gnome_rr_output_info_get_preferred_width (self->info);
+ height = gnome_rr_output_info_get_preferred_height (self->info);
+ }
+
+ gtk_widget_set_size_request (GTK_WIDGET (self),
+ DISPLAY_PREVIEW_LIST_HEIGHT * (width / (gdouble) height),
+ DISPLAY_PREVIEW_LIST_HEIGHT);
+ self->height = height;
+ self->width = width;
+}
+
+static void
+gd_display_preview_dispose (GObject *object)
+{
+ GdDisplayPreview *self = GD_DISPLAY_PREVIEW (object);
+
+ g_clear_object (&self->info);
+
+ G_OBJECT_CLASS (gd_display_preview_parent_class)->dispose (object);
+}
+
+static void
+gd_display_preview_class_init (GdDisplayPreviewClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ GtkWidgetClass *wclass = GTK_WIDGET_CLASS (class);
+
+ oclass->constructed = gd_display_preview_constructed;
+ oclass->dispose = gd_display_preview_dispose;
+ oclass->set_property = gd_display_preview_set_property;
+ wclass->draw = gd_display_preview_draw;
+
+ g_object_class_install_property (oclass,
+ PROP_CLONE,
+ g_param_spec_boolean ("clone",
+ "Clone",
+ "Whether this is part of a cloned
configuration",
+ FALSE,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (oclass,
+ PROP_INFO,
+ g_param_spec_object ("info",
+ "GnomeRROutputInfo",
+ "The info describing this display",
+ GNOME_TYPE_RR_OUTPUT_INFO,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gd_display_preview_init (GdDisplayPreview *self)
+{
+}
+
+/**
+ * gd_display_preview_new:
+ * @info:
+ * @clone:
+ *
+ * Creates a new display preview widget.
+ *
+ * Returns: a new #GdDisplayPreview object.
+ **/
+GtkWidget *
+gd_display_preview_new (GnomeRROutputInfo *info,
+ gboolean clone)
+{
+ return g_object_new (GD_TYPE_DISPLAY_PREVIEW,
+ "halign", GTK_ALIGN_CENTER,
+ "valign", GTK_ALIGN_CENTER,
+ "clone", clone,
+ "info", info,
+ NULL);
+}
diff --git a/src/lib/gd-display-preview.h b/src/lib/gd-display-preview.h
new file mode 100644
index 0000000..9399df2
--- /dev/null
+++ b/src/lib/gd-display-preview.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GD_DISPLAY_PREVIEW_H__
+#define __GD_DISPLAY_PREVIEW_H__
+
+#include <gtk/gtk.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-rr-config.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GdDisplayPreview GdDisplayPreview;
+typedef struct _GdDisplayPreviewClass GdDisplayPreviewClass;
+
+#define GD_TYPE_DISPLAY_PREVIEW (gd_display_preview_get_type ())
+#define GD_DISPLAY_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GD_TYPE_DISPLAY_PREVIEW,
GdDisplayPreview))
+#define GD_DISPLAY_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GD_TYPE_DISPLAY_PREVIEW,
GdDisplayPreviewClass))
+#define GD_IS_DISPLAY_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GD_TYPE_DISPLAY_PREVIEW))
+#define GD_IS_DISPLAY_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GD_TYPE_DISPLAY_PREVIEW))
+#define GD_DISPLAY_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GD_TYPE_DISPLAY_PREVIEW,
GdDisplayPreviewClass))
+
+GType gd_display_preview_get_type (void) G_GNUC_CONST;
+
+GtkWidget *gd_display_preview_new (GnomeRROutputInfo *info,
+ gboolean clone);
+
+G_END_DECLS
+
+#endif /* __GD_DISPLAY_PREVIEW_H__ */
diff --git a/src/presentation.js b/src/presentation.js
index 1251ecf..20e5b93 100644
--- a/src/presentation.js
+++ b/src/presentation.js
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 Red Hat, Inc.
+ * Copyright (c) 2013, 2014 Red Hat, Inc.
*
* Gnome Documents is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
@@ -72,7 +72,8 @@ const PresentationWindow = new Lang.Class({
},
setOutput: function(output) {
- this.window.move(output.x, output.y);
+ let [x, y, width, height] = output.get_geometry();
+ this.window.move(x, y);
},
_createView: function() {
@@ -125,6 +126,8 @@ const PresentationOutputChooser = new Lang.Class({
},
_populateList: function() {
+ let sizeGroup = new Gtk.SizeGroup({ mode: Gtk.SizeGroupMode.HORIZONTAL });
+
for (let i = 0; i < this._outputs.list.length; i++) {
let row = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
column_spacing: 12,
@@ -132,10 +135,13 @@ const PresentationOutputChooser = new Lang.Class({
this._box.add(row);
let output = this._outputs.list[i];
- let markup = '<b>' + output.display_name + '</b>';
- let label = new Gtk.Label({ label: markup,
- use_markup: true });
row.output = output;
+
+ let preview = new GdPrivate.DisplayPreview({ info: output, clone: this._outputs.clone });
+ sizeGroup.add_widget(preview);
+ row.add(preview);
+
+ let label = new Gtk.Label({ label: output.get_display_name() });
row.add(label);
if (this._outputs.list.length > 1) {
@@ -144,9 +150,9 @@ const PresentationOutputChooser = new Lang.Class({
if (this._outputs.clone)
// Translators: "Mirrored" describes when both displays show the same view
status = _("Mirrored");
- else if (output.is_primary)
+ else if (output.get_primary())
status = _("Primary");
- else if (!output.is_active)
+ else if (!output.is_active())
status = _("Off");
else
status = _("Secondary");
@@ -195,19 +201,6 @@ const PresentationOutputChooser = new Lang.Class({
});
Signals.addSignalMethods(PresentationOutputChooser.prototype);
-const PresentationOutput = new Lang.Class({
- Name: 'PresentationOutput',
- _init: function() {
- this.id = null;
- this.name = null;
- this.display_name = null;
- this.is_active = false;
- this.is_primary = false;
- this.x = 0;
- this.y = 0;
- }
-});
-
const PresentationOutputs = new Lang.Class({
Name: 'PresentationOutputs',
@@ -220,6 +213,7 @@ const PresentationOutputs = new Lang.Class({
this._config = GnomeDesktop.RRConfig.new_current(this._screen);
this.clone = this._config.get_clone();
+ this._infos = this._config.get_outputs();
this.load();
},
@@ -229,27 +223,16 @@ const PresentationOutputs = new Lang.Class({
},
load: function() {
- this._outputs = this._screen.list_outputs();
this.list = [];
- for (let idx in this._outputs) {
- let output = this._outputs[idx];
-
- let out = new PresentationOutput();
- out.name = output.get_name();
- out.display_name = output.get_display_name();
- out.is_primary = output.get_is_primary();
-
- if (output.get_crtc())
- out.is_active = true;
-
- let [x, y] = output.get_position();
- out.x = x;
- out.y = y;
+ for (let idx in this._infos) {
+ let info = this._infos[idx];
+ let name = info.get_name();
+ let output = this._screen.get_output_by_name(name);
if (output.is_builtin_display())
- this.list.unshift(out);
+ this.list.unshift(info);
else
- this.list.push(out);
+ this.list.push(info);
}
}
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]