Compare commits
	
		
			33 Commits
		
	
	
		
			3.1.91
			...
			nbtk-intro
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4f070317d2 | ||
| 
						 | 
					661100abe8 | ||
| 
						 | 
					3e90b11cfb | ||
| 
						 | 
					4b4a1be420 | ||
| 
						 | 
					1a4861ec4f | ||
| 
						 | 
					2ac82da232 | ||
| 
						 | 
					8f7e6f8117 | ||
| 
						 | 
					d2b98701be | ||
| 
						 | 
					faeda5dc8b | ||
| 
						 | 
					70cb8e180b | ||
| 
						 | 
					2232a92ba8 | ||
| 
						 | 
					4743a8e750 | ||
| 
						 | 
					e1390c7dd5 | ||
| 
						 | 
					49ba54820c | ||
| 
						 | 
					8ffa161a7f | ||
| 
						 | 
					0eca3efcb0 | ||
| 
						 | 
					9c3af62dc4 | ||
| 
						 | 
					db0c2b5959 | ||
| 
						 | 
					98215f497d | ||
| 
						 | 
					9dbafe156e | ||
| 
						 | 
					277dd7106a | ||
| 
						 | 
					431f299756 | ||
| 
						 | 
					d8d7f5f711 | ||
| 
						 | 
					a07af9fb14 | ||
| 
						 | 
					f1f11f1e76 | ||
| 
						 | 
					c60a6a49de | ||
| 
						 | 
					6687054474 | ||
| 
						 | 
					60819b3a79 | ||
| 
						 | 
					3e265b4bc6 | ||
| 
						 | 
					e2aa2a00f0 | ||
| 
						 | 
					1edc88a2bd | ||
| 
						 | 
					271e4ca07e | ||
| 
						 | 
					9f79296276 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -38,5 +38,7 @@ src/gnomeshell-taskpanel
 | 
			
		||||
src/gnome-shell
 | 
			
		||||
src/test-recorder
 | 
			
		||||
src/test-recorder.ogg
 | 
			
		||||
src/test-theme
 | 
			
		||||
stamp-h1
 | 
			
		||||
tests/run-test.sh
 | 
			
		||||
xmldocs.make
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,13 +1,22 @@
 | 
			
		||||
SUBDIRS = data js src po
 | 
			
		||||
SUBDIRS = data js src tests po
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST =		\
 | 
			
		||||
	.project	\
 | 
			
		||||
	.settings
 | 
			
		||||
	.settings	\
 | 
			
		||||
	autogen.sh
 | 
			
		||||
 | 
			
		||||
# These are files checked into Git that we don't want to distribute
 | 
			
		||||
DIST_EXCLUDE =					\
 | 
			
		||||
	.gitignore				\
 | 
			
		||||
	gnome-shell.doap			\
 | 
			
		||||
	MAINTAINERS				\
 | 
			
		||||
	tools/build/*
 | 
			
		||||
 | 
			
		||||
distcheck-hook:
 | 
			
		||||
	@echo "Checking disted javascript against files in git"
 | 
			
		||||
	@echo "Checking disted files against files in git"
 | 
			
		||||
	@failed=false; \
 | 
			
		||||
	for f in `cd $(srcdir) && git ls-files js` ; do \
 | 
			
		||||
	exclude=`(for p in $(DIST_EXCLUDE) ; do echo --exclude=$$p ; done)`; \
 | 
			
		||||
	for f in `cd $(srcdir) && git ls-files $$exclude` ; do \
 | 
			
		||||
		if ! test -e $(distdir)/$$f ; then \
 | 
			
		||||
			echo File missing from distribution: $$f ; \
 | 
			
		||||
			failed=true ; \
 | 
			
		||||
 
 | 
			
		||||
@@ -57,8 +57,10 @@ PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugin
 | 
			
		||||
                                 gnome-desktop-2.0 >= 2.26 libstartup-notification-1.0
 | 
			
		||||
                                 gobject-introspection-1.0 >= 0.6.5)
 | 
			
		||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
 | 
			
		||||
PKG_CHECK_MODULES(NBTK, clutter-1.0 gtk+-2.0 clutter-imcontext-0.1)
 | 
			
		||||
PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
 | 
			
		||||
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-2.0)
 | 
			
		||||
PKG_CHECK_MODULES(TOOLKIT, clutter-1.0 libcroco-0.6)
 | 
			
		||||
PKG_CHECK_MODULES(TRAY, gtk+-2.0)
 | 
			
		||||
 | 
			
		||||
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
 | 
			
		||||
@@ -128,5 +130,6 @@ AC_OUTPUT([
 | 
			
		||||
  js/misc/Makefile
 | 
			
		||||
  js/ui/Makefile
 | 
			
		||||
  src/Makefile
 | 
			
		||||
  tests/Makefile
 | 
			
		||||
  po/Makefile.in
 | 
			
		||||
])
 | 
			
		||||
 
 | 
			
		||||
@@ -12,18 +12,26 @@ gnome-shell.desktop.in: gnome-shell.desktop.in.in
 | 
			
		||||
gnome-shell.desktop: gnome-shell.desktop.in
 | 
			
		||||
	$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
 | 
			
		||||
 | 
			
		||||
imagedir = $(pkgdatadir)/images
 | 
			
		||||
 | 
			
		||||
dist_image_DATA =		\
 | 
			
		||||
	add-workspace.svg	\
 | 
			
		||||
	app-well-glow.png	\
 | 
			
		||||
        back.svg                \
 | 
			
		||||
	close.svg		\
 | 
			
		||||
	close-black.svg       \
 | 
			
		||||
	info.svg		\
 | 
			
		||||
	magnifier.svg  \
 | 
			
		||||
imagesdir = $(pkgdatadir)/images
 | 
			
		||||
dist_images_DATA =				\
 | 
			
		||||
	add-workspace.svg			\
 | 
			
		||||
	app-well-glow.png			\
 | 
			
		||||
	back.svg				\
 | 
			
		||||
	close.svg				\
 | 
			
		||||
	close-black.svg				\
 | 
			
		||||
	info.svg				\
 | 
			
		||||
	magnifier.svg				\
 | 
			
		||||
	remove-workspace.svg
 | 
			
		||||
 | 
			
		||||
themedir = $(pkgdatadir)/theme
 | 
			
		||||
dist_theme_DATA =				\
 | 
			
		||||
	theme/gnome-shell.css			\
 | 
			
		||||
	theme/scroll-button-down.png		\
 | 
			
		||||
	theme/scroll-button-down-hover.png	\
 | 
			
		||||
	theme/scroll-button-up.png		\
 | 
			
		||||
	theme/scroll-button-up-hover.png	\
 | 
			
		||||
	theme/scroll-vhandle.png
 | 
			
		||||
 | 
			
		||||
schemadir  = @GCONF_SCHEMA_FILE_DIR@
 | 
			
		||||
schema_DATA = gnome-shell.schemas
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								data/theme/gnome-shell.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								data/theme/gnome-shell.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
/* Copyright 2009, Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Portions adapted from NBTK's data/style/default.css
 | 
			
		||||
 *   Copyright 2009 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
NbtkScrollBar
 | 
			
		||||
{
 | 
			
		||||
  background-color: #354761;
 | 
			
		||||
  padding: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkScrollView
 | 
			
		||||
{
 | 
			
		||||
  scrollbar-width: 16px;
 | 
			
		||||
  scrollbar-height: 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton#up-stepper
 | 
			
		||||
{
 | 
			
		||||
  border-image: url("scroll-button-up.png") 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton#up-stepper:hover,
 | 
			
		||||
NbtkButton#up-stepper:active
 | 
			
		||||
{
 | 
			
		||||
  border-image: url("scroll-button-up-hover.png") 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton#down-stepper
 | 
			
		||||
{
 | 
			
		||||
  border-image: url("scroll-button-down.png") 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton#down-stepper:hover,
 | 
			
		||||
NbtkButton#down-stepper:active
 | 
			
		||||
{
 | 
			
		||||
  border-image: url("scroll-button-down-hover.png") 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkScrollBar NbtkButton#vhandle
 | 
			
		||||
{
 | 
			
		||||
  border-image: url("scroll-vhandle.png") 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkScrollBar NbtkButton#vhandle:hover
 | 
			
		||||
{
 | 
			
		||||
  border-image: url("scroll-vhandle.png") 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* LookingGlass */
 | 
			
		||||
 | 
			
		||||
#LookingGlassDialog
 | 
			
		||||
{
 | 
			
		||||
  background-color: rgba(0,0,0,0.85);
 | 
			
		||||
  spacing: 4px;
 | 
			
		||||
  padding: 4px;
 | 
			
		||||
  border: 1px solid rgba(0,0,172,0.85);
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
 | 
			
		||||
  color: #88ff66;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#LookingGlassDialog > #Toolbar
 | 
			
		||||
{
 | 
			
		||||
  border: 1px solid grey;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#LookingGlassDialog NbtkLabel
 | 
			
		||||
{
 | 
			
		||||
  color: #88ff66;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#LookingGlassDialog NbtkEntry
 | 
			
		||||
{
 | 
			
		||||
  color: #88ff66;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#LookingGlassDialog NbtkBoxLayout#EvalBox
 | 
			
		||||
{
 | 
			
		||||
  padding: 4px;
 | 
			
		||||
  spacing: 4px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								data/theme/scroll-button-down-hover.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/theme/scroll-button-down-hover.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 225 B  | 
							
								
								
									
										
											BIN
										
									
								
								data/theme/scroll-button-down.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/theme/scroll-button-down.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 225 B  | 
							
								
								
									
										
											BIN
										
									
								
								data/theme/scroll-button-up-hover.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/theme/scroll-button-up-hover.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 211 B  | 
							
								
								
									
										
											BIN
										
									
								
								data/theme/scroll-button-up.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/theme/scroll-button-up.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 211 B  | 
							
								
								
									
										
											BIN
										
									
								
								data/theme/scroll-vhandle.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/theme/scroll-vhandle.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 323 B  | 
@@ -9,6 +9,7 @@ dist_jsui_DATA =		\
 | 
			
		||||
	dash.js			\
 | 
			
		||||
	dnd.js			\
 | 
			
		||||
	docDisplay.js		\
 | 
			
		||||
	environment.js		\
 | 
			
		||||
	genericDisplay.js	\
 | 
			
		||||
	link.js			\
 | 
			
		||||
	lookingGlass.js		\
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								js/ui/environment.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								js/ui/environment.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
 | 
			
		||||
// "monkey patch" in some varargs ClutterContainer methods; we need
 | 
			
		||||
// to do this per-container class since there is no representation
 | 
			
		||||
// of interfaces in Javascript
 | 
			
		||||
function _patchContainerClass(containerClass) {
 | 
			
		||||
    // This one is a straightforward mapping of the C method
 | 
			
		||||
    containerClass.prototype.child_set = function(actor, props) {
 | 
			
		||||
        let meta = this.get_child_meta(actor);
 | 
			
		||||
        for (prop in props)
 | 
			
		||||
            meta[prop] = props[prop];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // clutter_container_add() actually is a an add-many-actors
 | 
			
		||||
    // method. We conveniently, but somewhat dubiously, take the
 | 
			
		||||
    // this opportunity to make it do something more useful.
 | 
			
		||||
    containerClass.prototype.add = function(actor, props) {
 | 
			
		||||
        this.add_actor(actor);
 | 
			
		||||
        if (props)
 | 
			
		||||
            this.child_set(actor, props);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_patchContainerClass(Nbtk.BoxLayout);
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
    Tweener.init();
 | 
			
		||||
}
 | 
			
		||||
@@ -4,6 +4,7 @@ const Big = imports.gi.Big;
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const Pango = imports.gi.Pango;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
@@ -12,18 +13,7 @@ const Mainloop = imports.mainloop;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
 | 
			
		||||
const LG_BORDER_COLOR = new Clutter.Color();
 | 
			
		||||
LG_BORDER_COLOR.from_pixel(0x0000aca0);
 | 
			
		||||
const LG_BACKGROUND_COLOR = new Clutter.Color();
 | 
			
		||||
LG_BACKGROUND_COLOR.from_pixel(0x000000d5);
 | 
			
		||||
const GREY = new Clutter.Color();
 | 
			
		||||
GREY.from_pixel(0xAFAFAFFF);
 | 
			
		||||
const MATRIX_GREEN = new Clutter.Color();
 | 
			
		||||
MATRIX_GREEN.from_pixel(0x88ff66ff);
 | 
			
		||||
// FIXME pull from GConf
 | 
			
		||||
const MATRIX_FONT = 'Monospace 10';
 | 
			
		||||
 | 
			
		||||
                    /* Imports...feel free to add here as needed */
 | 
			
		||||
/* Imports...feel free to add here as needed */
 | 
			
		||||
var commandHeader = "const Clutter = imports.gi.Clutter; " +
 | 
			
		||||
                    "const GLib = imports.gi.GLib; " +
 | 
			
		||||
                    "const Gtk = imports.gi.Gtk; " +
 | 
			
		||||
@@ -47,7 +37,7 @@ function Notebook() {
 | 
			
		||||
 | 
			
		||||
Notebook.prototype = {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new Big.Box();
 | 
			
		||||
        this.actor = new Nbtk.BoxLayout({ vertical: true });
 | 
			
		||||
 | 
			
		||||
        this.tabControls = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
 | 
			
		||||
                                         spacing: 4, padding: 2 });
 | 
			
		||||
@@ -58,21 +48,24 @@ Notebook.prototype = {
 | 
			
		||||
 | 
			
		||||
    appendPage: function(name, child) {
 | 
			
		||||
        let labelOuterBox = new Big.Box({ padding: 2 });
 | 
			
		||||
        let labelBox = new Big.Box({ padding: 2, border_color: MATRIX_GREEN,
 | 
			
		||||
                                     reactive: true });
 | 
			
		||||
        let labelBox = new Nbtk.BoxLayout({ reactive: true });
 | 
			
		||||
        labelOuterBox.append(labelBox, Big.BoxPackFlags.NONE);
 | 
			
		||||
        let label = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                       font_name: MATRIX_FONT,
 | 
			
		||||
                                       text: name });
 | 
			
		||||
        let label = new Nbtk.Label({ text: name });
 | 
			
		||||
        labelBox.connect('button-press-event', Lang.bind(this, function () {
 | 
			
		||||
            this.selectChild(child);
 | 
			
		||||
            return true;
 | 
			
		||||
        }));
 | 
			
		||||
        labelBox.append(label, Big.BoxPackFlags.EXPAND);
 | 
			
		||||
        this._tabs.push([child, labelBox]);
 | 
			
		||||
        child.hide();
 | 
			
		||||
        this.actor.append(child, Big.BoxPackFlags.EXPAND);
 | 
			
		||||
        labelBox.add(label, { expand: true });
 | 
			
		||||
        this.tabControls.append(labelOuterBox, Big.BoxPackFlags.NONE);
 | 
			
		||||
 | 
			
		||||
        let scrollview = new Nbtk.ScrollView({ x_fill: true, y_fill: true });
 | 
			
		||||
        scrollview.get_hscroll_bar().hide();
 | 
			
		||||
        scrollview.add_actor(child);
 | 
			
		||||
 | 
			
		||||
        this._tabs.push([child, labelBox, scrollview]);
 | 
			
		||||
        scrollview.hide();
 | 
			
		||||
        this.actor.add(scrollview, { expand: true });
 | 
			
		||||
 | 
			
		||||
        if (this._selectedIndex == -1)
 | 
			
		||||
            this.selectIndex(0);
 | 
			
		||||
    },
 | 
			
		||||
@@ -80,10 +73,10 @@ Notebook.prototype = {
 | 
			
		||||
    _unselect: function() {
 | 
			
		||||
        if (this._selectedIndex < 0)
 | 
			
		||||
            return;
 | 
			
		||||
        let [child, labelBox] = this._tabs[this._selectedIndex];
 | 
			
		||||
        let [child, labelBox, scrollview] = this._tabs[this._selectedIndex];
 | 
			
		||||
        labelBox.padding = 2;
 | 
			
		||||
        labelBox.border = 0;
 | 
			
		||||
        child.hide();
 | 
			
		||||
        scrollview.hide();
 | 
			
		||||
        this._selectedIndex = -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -95,10 +88,10 @@ Notebook.prototype = {
 | 
			
		||||
            this.emit('selection', null);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        let [child, labelBox] = this._tabs[index];
 | 
			
		||||
        let [child, labelBox, scrollview] = this._tabs[index];
 | 
			
		||||
        labelBox.padding = 1;
 | 
			
		||||
        labelBox.border = 1;
 | 
			
		||||
        child.show();
 | 
			
		||||
        scrollview.show();
 | 
			
		||||
        this._selectedIndex = index;
 | 
			
		||||
        this.emit('selection', child);
 | 
			
		||||
    },
 | 
			
		||||
@@ -108,7 +101,7 @@ Notebook.prototype = {
 | 
			
		||||
            this.selectIndex(-1);
 | 
			
		||||
        else {
 | 
			
		||||
            for (let i = 0; i < this._tabs.length; i++) {
 | 
			
		||||
                let [tabChild, labelBox] = this._tabs[i];
 | 
			
		||||
                let [tabChild, labelBox, scrollview] = this._tabs[i];
 | 
			
		||||
                if (tabChild == child) {
 | 
			
		||||
                    this.selectIndex(i);
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -130,20 +123,19 @@ Result.prototype = {
 | 
			
		||||
 | 
			
		||||
        this.actor = new Big.Box();
 | 
			
		||||
 | 
			
		||||
        let cmdTxt = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                        font_name: MATRIX_FONT,
 | 
			
		||||
                                        ellipsize: Pango.EllipsizeMode.END,
 | 
			
		||||
                                        text: command });
 | 
			
		||||
        let cmdTxt = new Nbtk.Label({ text: command });
 | 
			
		||||
        cmdTxt.ellipsize = Pango.EllipsizeMode.END;
 | 
			
		||||
 | 
			
		||||
        this.actor.append(cmdTxt, Big.BoxPackFlags.NONE);
 | 
			
		||||
        let resultTxt = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                           font_name: MATRIX_FONT,
 | 
			
		||||
                                           ellipsize: Pango.EllipsizeMode.END,
 | 
			
		||||
                                           text: "r(" + index + ") = " + o });
 | 
			
		||||
        let resultTxt = new Nbtk.Label({ text: "r(" + index + ") = " + o });
 | 
			
		||||
        resultTxt.ellipsize = Pango.EllipsizeMode.END;
 | 
			
		||||
 | 
			
		||||
        this.actor.append(resultTxt, Big.BoxPackFlags.NONE);
 | 
			
		||||
        let line = new Big.Box({ border_color: GREY,
 | 
			
		||||
                                 border_bottom: 1,
 | 
			
		||||
                                 height: 8 });
 | 
			
		||||
        this.actor.append(line, Big.BoxPackFlags.NONE);
 | 
			
		||||
        let line = new Clutter.Rectangle({ name: "Separator",
 | 
			
		||||
                                           height: 1 });
 | 
			
		||||
        let padBin = new Nbtk.Bin({ name: "Separator", x_fill: true, y_fill: true });
 | 
			
		||||
        padBin.add_actor(line);
 | 
			
		||||
        this.actor.append(padBin, Big.BoxPackFlags.NONE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -158,17 +150,14 @@ ActorHierarchy.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._parentList = [];
 | 
			
		||||
 | 
			
		||||
        this.actor = new Big.Box({ spacing: 4,
 | 
			
		||||
                                   border: 1,
 | 
			
		||||
                                   padding: 4,
 | 
			
		||||
                                   border_color: GREY });
 | 
			
		||||
        this.actor = new Nbtk.BoxLayout({ name: "ActorHierarchy", vertical: true });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setTarget: function(actor) {
 | 
			
		||||
        this._previousTarget = this._target;
 | 
			
		||||
        this.target = actor;
 | 
			
		||||
 | 
			
		||||
        this.actor.remove_all();
 | 
			
		||||
        this.actor.get_children().forEach(function (child) { child.destroy(); });
 | 
			
		||||
 | 
			
		||||
        if (!(actor instanceof Clutter.Actor))
 | 
			
		||||
            return;
 | 
			
		||||
@@ -181,11 +170,9 @@ ActorHierarchy.prototype = {
 | 
			
		||||
        while ((parent = parent.get_parent()) != null) {
 | 
			
		||||
            this._parentList.push(parent);
 | 
			
		||||
 | 
			
		||||
            let link = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                          font_name: MATRIX_FONT,
 | 
			
		||||
                                          reactive: true,
 | 
			
		||||
                                          text: "" + parent });
 | 
			
		||||
            this.actor.append(link, Big.BoxPackFlags.IF_FITS);
 | 
			
		||||
            let link = new Nbtk.Label({ reactive: true,
 | 
			
		||||
                                        text: "" + parent });
 | 
			
		||||
            this.actor.add_actor(link);
 | 
			
		||||
            let parentTarget = parent;
 | 
			
		||||
            link.connect('button-press-event', Lang.bind(this, function () {
 | 
			
		||||
                this._selectByActor(parentTarget);
 | 
			
		||||
@@ -214,16 +201,13 @@ PropertyInspector.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._parentList = [];
 | 
			
		||||
 | 
			
		||||
        this.actor = new Big.Box({ spacing: 4,
 | 
			
		||||
                                   border: 1,
 | 
			
		||||
                                   padding: 4,
 | 
			
		||||
                                   border_color: GREY });
 | 
			
		||||
        this.actor = new Nbtk.BoxLayout({ name: "PropertyInspector", vertical: true });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setTarget: function(actor) {
 | 
			
		||||
        this.target = actor;
 | 
			
		||||
 | 
			
		||||
        this.actor.remove_all();
 | 
			
		||||
        this.actor.get_children().forEach(function (child) { child.destroy(); });
 | 
			
		||||
 | 
			
		||||
        for (let propName in actor) {
 | 
			
		||||
            let valueStr;
 | 
			
		||||
@@ -233,11 +217,9 @@ PropertyInspector.prototype = {
 | 
			
		||||
                valueStr = '<error>';
 | 
			
		||||
            }
 | 
			
		||||
            let propText = propName + ": " + valueStr;
 | 
			
		||||
            let propDisplay = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                                 font_name: MATRIX_FONT,
 | 
			
		||||
                                                 reactive: true,
 | 
			
		||||
                                                 text: propText });
 | 
			
		||||
            this.actor.append(propDisplay, Big.BoxPackFlags.IF_FITS);
 | 
			
		||||
            let propDisplay = new Nbtk.Label({ reactive: true,
 | 
			
		||||
                                               text: propText });
 | 
			
		||||
            this.actor.add_actor(propDisplay);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -249,20 +231,16 @@ function Inspector() {
 | 
			
		||||
Inspector.prototype = {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let width = 150;
 | 
			
		||||
        let eventHandler = new Big.Box({ background_color: LG_BACKGROUND_COLOR,
 | 
			
		||||
                                         border: 1,
 | 
			
		||||
                                         border_color: LG_BORDER_COLOR,
 | 
			
		||||
                                         corner_radius: 4,
 | 
			
		||||
                                         y: global.stage.height/2,
 | 
			
		||||
                                         reactive: true
 | 
			
		||||
                                      });
 | 
			
		||||
        let eventHandler = new Nbtk.BoxLayout({ name: "LookingGlassDialog",
 | 
			
		||||
                                                vertical: false,
 | 
			
		||||
                                                y: Math.floor(global.stage.height/2),
 | 
			
		||||
                                                reactive: true });
 | 
			
		||||
        eventHandler.connect('notify::allocation', Lang.bind(this, function () {
 | 
			
		||||
            eventHandler.x = Math.floor((global.stage.width)/2 - (eventHandler.width)/2);
 | 
			
		||||
        }));
 | 
			
		||||
        global.stage.add_actor(eventHandler);
 | 
			
		||||
        let displayText = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                             font_name: MATRIX_FONT, text: '' });
 | 
			
		||||
        eventHandler.append(displayText, Big.BoxPackFlags.EXPAND);
 | 
			
		||||
        let displayText = new Nbtk.Label();
 | 
			
		||||
        eventHandler.add(displayText, { expand: true });
 | 
			
		||||
 | 
			
		||||
        let borderPaintTarget = null;
 | 
			
		||||
        let borderPaintId = null;
 | 
			
		||||
@@ -321,29 +299,26 @@ LookingGlass.prototype = {
 | 
			
		||||
        this._offset = 0;
 | 
			
		||||
        this._results = [];
 | 
			
		||||
 | 
			
		||||
        // TODO replace with scrolling or something better
 | 
			
		||||
        this._maxItems = 10;
 | 
			
		||||
        // Sort of magic, but...eh.
 | 
			
		||||
        this._maxItems = 150;
 | 
			
		||||
 | 
			
		||||
        this.actor = new Nbtk.BoxLayout({ name: "LookingGlassDialog",
 | 
			
		||||
                                          vertical: true,
 | 
			
		||||
                                          visible: false });
 | 
			
		||||
 | 
			
		||||
        let gconf = Shell.GConf.get_default();
 | 
			
		||||
        gconf.watch_directory("/desktop/gnome/interface");
 | 
			
		||||
        gconf.connect("changed::/desktop/gnome/interface/monospace_font_name",
 | 
			
		||||
                      Lang.bind(this, this._updateFont));
 | 
			
		||||
        this._updateFont();
 | 
			
		||||
 | 
			
		||||
        this.actor = new Big.Box({ background_color: LG_BACKGROUND_COLOR,
 | 
			
		||||
                                   border: 1,
 | 
			
		||||
                                   border_color: LG_BORDER_COLOR,
 | 
			
		||||
                                   corner_radius: 4,
 | 
			
		||||
                                   padding_top: 8,
 | 
			
		||||
                                   padding_left: 4,
 | 
			
		||||
                                   padding_right: 4,
 | 
			
		||||
                                   padding_bottom: 4,
 | 
			
		||||
                                   spacing: 4,
 | 
			
		||||
                                   visible: false
 | 
			
		||||
                                });
 | 
			
		||||
        global.stage.add_actor(this.actor);
 | 
			
		||||
 | 
			
		||||
        let toolbar = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
 | 
			
		||||
                                    border: 1, border_color: GREY,
 | 
			
		||||
                                    corner_radius: 4 });
 | 
			
		||||
        this.actor.append(toolbar, Big.BoxPackFlags.NONE);
 | 
			
		||||
        let toolbar = new Nbtk.BoxLayout({ name: "Toolbar" });
 | 
			
		||||
        this.actor.add_actor(toolbar);
 | 
			
		||||
        let inspectIcon = Shell.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }),
 | 
			
		||||
                                                                      24);
 | 
			
		||||
        toolbar.append(inspectIcon, Big.BoxPackFlags.NONE);
 | 
			
		||||
        toolbar.add_actor(inspectIcon);
 | 
			
		||||
        inspectIcon.reactive = true;
 | 
			
		||||
        inspectIcon.connect('button-press-event', Lang.bind(this, function () {
 | 
			
		||||
            let inspector = new Inspector();
 | 
			
		||||
@@ -361,31 +336,26 @@ LookingGlass.prototype = {
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        let notebook = new Notebook();
 | 
			
		||||
        this.actor.append(notebook.actor, Big.BoxPackFlags.EXPAND);
 | 
			
		||||
        toolbar.append(notebook.tabControls, Big.BoxPackFlags.END);
 | 
			
		||||
        this.actor.add(notebook.actor, { expand: true });
 | 
			
		||||
 | 
			
		||||
        this._evalBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
 | 
			
		||||
                                      spacing: 4 });
 | 
			
		||||
        let emptyBox = new Nbtk.Bin();
 | 
			
		||||
        toolbar.add(emptyBox, { expand: true });
 | 
			
		||||
        toolbar.add_actor(notebook.tabControls);
 | 
			
		||||
 | 
			
		||||
        this._evalBox = new Nbtk.BoxLayout({ name: "EvalBox", vertical: true });
 | 
			
		||||
        notebook.appendPage('Evaluator', this._evalBox);
 | 
			
		||||
 | 
			
		||||
        this._resultsArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
 | 
			
		||||
                                          spacing: 4 });
 | 
			
		||||
        this._evalBox.append(this._resultsArea, Big.BoxPackFlags.EXPAND);
 | 
			
		||||
        this._evalBox.add(this._resultsArea, { expand: true });
 | 
			
		||||
 | 
			
		||||
        let entryArea = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
 | 
			
		||||
        this._evalBox.append(entryArea, Big.BoxPackFlags.NONE);
 | 
			
		||||
        this._evalBox.add_actor(entryArea);
 | 
			
		||||
 | 
			
		||||
        let label = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                       font_name: MATRIX_FONT,
 | 
			
		||||
                                       text: 'js>>> ' });
 | 
			
		||||
        let label = new Nbtk.Label({ text: 'js>>> ' });
 | 
			
		||||
        entryArea.append(label, Big.BoxPackFlags.NONE);
 | 
			
		||||
 | 
			
		||||
        this._entry = new Clutter.Text({ color: MATRIX_GREEN,
 | 
			
		||||
                                         font_name: MATRIX_FONT,
 | 
			
		||||
                                         editable: true,
 | 
			
		||||
                                         activatable: true,
 | 
			
		||||
                                         singleLineMode: true,
 | 
			
		||||
                                         text: ''});
 | 
			
		||||
        this._entry = new Nbtk.Entry();
 | 
			
		||||
        /* unmapping the edit box will un-focus it, undo that */
 | 
			
		||||
        notebook.connect('selection', Lang.bind(this, function (nb, child) {
 | 
			
		||||
            if (child == this._evalBox)
 | 
			
		||||
@@ -403,7 +373,7 @@ LookingGlass.prototype = {
 | 
			
		||||
            notebook.selectIndex(0);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._entry.connect('activate', Lang.bind(this, function (o, e) {
 | 
			
		||||
        this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
 | 
			
		||||
            let text = o.get_text();
 | 
			
		||||
            // Ensure we don't get newlines in the command; the history file is
 | 
			
		||||
            // newline-separated.
 | 
			
		||||
@@ -416,7 +386,7 @@ LookingGlass.prototype = {
 | 
			
		||||
            this._historyNavIndex = -1;
 | 
			
		||||
            return true;
 | 
			
		||||
        }));
 | 
			
		||||
        this._entry.connect('key-press-event', Lang.bind(this, function(o, e) {
 | 
			
		||||
        this._entry.clutter_text.connect('key-press-event', Lang.bind(this, function(o, e) {
 | 
			
		||||
            let symbol = e.get_key_symbol();
 | 
			
		||||
            if (symbol == Clutter.Escape) {
 | 
			
		||||
                this.close();
 | 
			
		||||
@@ -446,6 +416,19 @@ LookingGlass.prototype = {
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateFont: function() {
 | 
			
		||||
        let gconf = Shell.GConf.get_default();
 | 
			
		||||
        let fontName = gconf.get_string("/desktop/gnome/interface/monospace_font_name");
 | 
			
		||||
        // This is mishandled by the scanner - should by Pango.FontDescription_from_string(fontName);
 | 
			
		||||
        // https://bugzilla.gnome.org/show_bug.cgi?id=595889
 | 
			
		||||
        let fontDesc = Pango.Font.description_from_string(fontName);
 | 
			
		||||
        // We ignore everything but size and style; you'd be crazy to set your system-wide
 | 
			
		||||
        // monospace font to be bold/oblique/etc. Could easily be added here.
 | 
			
		||||
        this.actor.style =
 | 
			
		||||
            'font-size: ' + fontDesc.get_size() / 1024. + (fontDesc.get_size_is_absolute() ? 'px' : 'pt') + ';'
 | 
			
		||||
            + 'font-family: "' + fontDesc.get_family() + '";';
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _readHistory: function () {
 | 
			
		||||
        if (!this._historyFile.query_exists(null))
 | 
			
		||||
            return;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,16 +7,17 @@ const GLib = imports.gi.GLib;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Meta = imports.gi.Meta;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Chrome = imports.ui.chrome;
 | 
			
		||||
const Environment = imports.ui.environment;
 | 
			
		||||
const Overview = imports.ui.overview;
 | 
			
		||||
const Panel = imports.ui.panel;
 | 
			
		||||
const RunDialog = imports.ui.runDialog;
 | 
			
		||||
const LookingGlass = imports.ui.lookingGlass;
 | 
			
		||||
const Sidebar = imports.ui.sidebar;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
const WindowManager = imports.ui.windowManager;
 | 
			
		||||
 | 
			
		||||
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
 | 
			
		||||
@@ -43,7 +44,7 @@ function start() {
 | 
			
		||||
 | 
			
		||||
    global.grab_dbus_service();
 | 
			
		||||
 | 
			
		||||
    Tweener.init();
 | 
			
		||||
    Environment.init();
 | 
			
		||||
 | 
			
		||||
    // Ensure ShellAppMonitor is initialized; this will
 | 
			
		||||
    // also initialize ShellAppSystem first.  ShellAppSystem
 | 
			
		||||
@@ -66,6 +67,11 @@ function start() {
 | 
			
		||||
    for (let i = 0; i < children.length; i++)
 | 
			
		||||
        children[i].destroy();
 | 
			
		||||
 | 
			
		||||
    let themeContext = Shell.ThemeContext.get_for_stage (global.stage);
 | 
			
		||||
    let stylesheetPath = global.datadir + "/theme/gnome-shell.css";
 | 
			
		||||
    let theme = new Shell.Theme ({ application_stylesheet: stylesheetPath });
 | 
			
		||||
    themeContext.set_theme (theme);
 | 
			
		||||
 | 
			
		||||
    global.connect('panel-run-dialog', function(panel) {
 | 
			
		||||
        // Make sure not more than one run dialog is shown.
 | 
			
		||||
        getRunDialog().open();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										117
									
								
								src/Makefile-nbtk.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/Makefile-nbtk.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
nbtk_cflags =                    \
 | 
			
		||||
    -I$(top_srcdir)/src         \
 | 
			
		||||
    -DPREFIX=\""$(prefix)"\"        \
 | 
			
		||||
    -DLIBDIR=\""$(libdir)"\"        \
 | 
			
		||||
    -DG_DISABLE_DEPRECATED          \
 | 
			
		||||
    -DG_LOG_DOMAIN=\"Nbtk\"          \
 | 
			
		||||
    -DNBTK_COMPILATION  \
 | 
			
		||||
    $(NBTK_CFLAGS)           \
 | 
			
		||||
    $(NULL)
 | 
			
		||||
 | 
			
		||||
nbtk_built_sources = \
 | 
			
		||||
    nbtk-enum-types.h   \
 | 
			
		||||
    nbtk-enum-types.c   \
 | 
			
		||||
    nbtk-marshal.h      \
 | 
			
		||||
    nbtk-marshal.c
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES += $(nbtk_built_sources)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST += \
 | 
			
		||||
	nbtk/nbtk-marshal.list \
 | 
			
		||||
	nbtk/nbtk-enum-types.h.in \
 | 
			
		||||
	nbtk/nbtk-enum-types.c.in
 | 
			
		||||
 | 
			
		||||
CLEANFILES += stamp-nbtk-marshal.h stamp-nbtk-enum-types.h
 | 
			
		||||
 | 
			
		||||
nbtk-marshal.h: stamp-nbtk-marshal.h
 | 
			
		||||
	@true
 | 
			
		||||
stamp-nbtk-marshal.h: Makefile nbtk/nbtk-marshal.list
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_GENMARSHAL) \
 | 
			
		||||
		--prefix=_nbtk_marshal \
 | 
			
		||||
		--header \
 | 
			
		||||
	$(srcdir)/nbtk/nbtk-marshal.list > $@.tmp && \
 | 
			
		||||
	(cmp -s $@.tmp nbtk-marshal.h || cp -f $@.tmp nbtk-marshal.h) && \
 | 
			
		||||
	rm -f $@.tmp && \
 | 
			
		||||
	echo timestamp > $(@F)
 | 
			
		||||
 | 
			
		||||
nbtk-marshal.c: Makefile nbtk/nbtk-marshal.list
 | 
			
		||||
	$(AM_V_GEN) (echo "#include \"nbtk-marshal.h\"" ; \
 | 
			
		||||
	 $(GLIB_GENMARSHAL) \
 | 
			
		||||
		--prefix=_nbtk_marshal \
 | 
			
		||||
		--body \
 | 
			
		||||
	 $(srcdir)/nbtk/nbtk-marshal.list ) > $@.tmp && \
 | 
			
		||||
	cp -f $@.tmp nbtk-marshal.c && \
 | 
			
		||||
	rm -f $@.tmp
 | 
			
		||||
 | 
			
		||||
nbtk-enum-types.h: stamp-nbtk-enum-types.h Makefile
 | 
			
		||||
	@true
 | 
			
		||||
stamp-nbtk-enum-types.h: $(source_h) nbtk/nbtk-enum-types.h.in
 | 
			
		||||
	$(AM_V_GEN) ( cd $(srcdir) && \
 | 
			
		||||
	  $(GLIB_MKENUMS) \
 | 
			
		||||
	    --template nbtk/nbtk-enum-types.h.in \
 | 
			
		||||
	  $(nbtk_source_h) ) >> $@.tmp && \
 | 
			
		||||
	(cmp -s $@.tmp nbtk-enum-types.h || cp $@.tmp nbtk-enum-types.h) && \
 | 
			
		||||
	rm -f $@.tmp && \
 | 
			
		||||
	echo timestamp > $(@F)
 | 
			
		||||
 | 
			
		||||
nbtk-enum-types.c: stamp-nbtk-enum-types.h nbtk/nbtk-enum-types.c.in
 | 
			
		||||
	$(AM_V_GEN) ( cd $(srcdir) && \
 | 
			
		||||
	  $(GLIB_MKENUMS) \
 | 
			
		||||
	    --template nbtk/nbtk-enum-types.c.in \
 | 
			
		||||
	  $(nbtk_source_h) ) >> $@.tmp && \
 | 
			
		||||
	cp $@.tmp $@ && \
 | 
			
		||||
	rm -f $@.tmp
 | 
			
		||||
 | 
			
		||||
# please, keep this sorted alphabetically
 | 
			
		||||
nbtk_source_h =                  \
 | 
			
		||||
    nbtk/nbtk-adjustment.h            \
 | 
			
		||||
    nbtk/nbtk-bin.h                   \
 | 
			
		||||
    nbtk/nbtk-box-layout.h            \
 | 
			
		||||
    nbtk/nbtk-box-layout-child.h      \
 | 
			
		||||
    nbtk/nbtk-button.h                \
 | 
			
		||||
    nbtk/nbtk-clipboard.h             \
 | 
			
		||||
    nbtk/nbtk-entry.h                 \
 | 
			
		||||
    nbtk/nbtk-label.h                 \
 | 
			
		||||
    nbtk/nbtk-private.h               \
 | 
			
		||||
    nbtk/nbtk-scrollable.h            \
 | 
			
		||||
    nbtk/nbtk-scroll-bar.h            \
 | 
			
		||||
    nbtk/nbtk-scroll-view.h           \
 | 
			
		||||
    nbtk/nbtk-subtexture.h            \
 | 
			
		||||
    nbtk/nbtk-texture-cache.h         \
 | 
			
		||||
    nbtk/nbtk-texture-frame.h         \
 | 
			
		||||
    nbtk/nbtk-tooltip.h               \
 | 
			
		||||
    nbtk/nbtk-types.h                 \
 | 
			
		||||
    nbtk/nbtk-widget.h                \
 | 
			
		||||
    $(NULL)
 | 
			
		||||
 | 
			
		||||
# please, keep this sorted alphabetically
 | 
			
		||||
nbtk_source_c =                  \
 | 
			
		||||
    nbtk/nbtk-adjustment.c           \
 | 
			
		||||
    nbtk/nbtk-bin.c                   \
 | 
			
		||||
    nbtk/nbtk-box-layout.c            \
 | 
			
		||||
    nbtk/nbtk-box-layout-child.c      \
 | 
			
		||||
    nbtk/nbtk-button.c                \
 | 
			
		||||
    nbtk/nbtk-clipboard.c             \
 | 
			
		||||
    nbtk/nbtk-entry.c                 \
 | 
			
		||||
    nbtk/nbtk-label.c                 \
 | 
			
		||||
    nbtk/nbtk-private.c               \
 | 
			
		||||
    nbtk/nbtk-scrollable.c            \
 | 
			
		||||
    nbtk/nbtk-scroll-bar.c            \
 | 
			
		||||
    nbtk/nbtk-scroll-view.c           \
 | 
			
		||||
    nbtk/nbtk-subtexture.c            \
 | 
			
		||||
    nbtk/nbtk-texture-cache.c         \
 | 
			
		||||
    nbtk/nbtk-texture-frame.c         \
 | 
			
		||||
    nbtk/nbtk-tooltip.c               \
 | 
			
		||||
    nbtk/nbtk-widget.c                \
 | 
			
		||||
    $(NULL)
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES += libnbtk-1.0.la
 | 
			
		||||
 | 
			
		||||
libnbtk_1_0_la_LIBADD = $(NBTK_LIBS)
 | 
			
		||||
libnbtk_1_0_la_SOURCES = \
 | 
			
		||||
    $(nbtk_source_c) \
 | 
			
		||||
    $(nbtk_source_h) \
 | 
			
		||||
    $(nbtk_built_sources) \
 | 
			
		||||
    $(NULL)
 | 
			
		||||
libnbtk_1_0_la_CPPFLAGS = $(nbtk_cflags)
 | 
			
		||||
libnbtk_1_0_la_LDFLAGS = $(LDADD)
 | 
			
		||||
							
								
								
									
										36
									
								
								src/Makefile-toolkit.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/Makefile-toolkit.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
toolkit_cflags =				\
 | 
			
		||||
    -I$(top_srcdir)/src				\
 | 
			
		||||
    -DPREFIX=\""$(prefix)"\"			\
 | 
			
		||||
    -DLIBDIR=\""$(libdir)"\"			\
 | 
			
		||||
    -DG_DISABLE_DEPRECATED			\
 | 
			
		||||
    -DG_LOG_DOMAIN=\"Shell\"			\
 | 
			
		||||
    $(TOOLKIT_CFLAGS)
 | 
			
		||||
 | 
			
		||||
# please, keep this sorted alphabetically
 | 
			
		||||
toolkit_sources =				\
 | 
			
		||||
	toolkit/shell-border-image.c		\
 | 
			
		||||
	toolkit/shell-border-image.h		\
 | 
			
		||||
	toolkit/shell-theme.c			\
 | 
			
		||||
	toolkit/shell-theme.h			\
 | 
			
		||||
	toolkit/shell-theme-context.c		\
 | 
			
		||||
	toolkit/shell-theme-context.h		\
 | 
			
		||||
	toolkit/shell-theme-node.c		\
 | 
			
		||||
	toolkit/shell-theme-node.h		\
 | 
			
		||||
	toolkit/shell-theme-private.h
 | 
			
		||||
 | 
			
		||||
non_gir_toolkit_sources =			\
 | 
			
		||||
	toolkit/shell-theme-private.h
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES += libshell-toolkit.la
 | 
			
		||||
 | 
			
		||||
libshell_toolkit_la_LIBADD = $(TOOLKIT_LIBS)
 | 
			
		||||
libshell_toolkit_la_SOURCES = $(toolkit_sources) $(toolkit_built_sources)
 | 
			
		||||
libshell_toolkit_la_CPPFLAGS = $(toolkit_cflags)
 | 
			
		||||
libshell_toolkit_la_LDFLAGS = $(LDADD)
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS += test-theme
 | 
			
		||||
 | 
			
		||||
test_theme_CPPFLAGS = $(toolkit_cflags)
 | 
			
		||||
test_theme_LDADD = libshell-toolkit.la
 | 
			
		||||
 | 
			
		||||
test_theme_SOURCES = toolkit/test-theme.c
 | 
			
		||||
@@ -4,6 +4,7 @@ CLEANFILES =
 | 
			
		||||
EXTRA_DIST =
 | 
			
		||||
libexec_PROGRAMS =
 | 
			
		||||
noinst_LTLIBRARIES =
 | 
			
		||||
noinst_PROGRAMS =
 | 
			
		||||
 | 
			
		||||
.AUTOPARALLEL:
 | 
			
		||||
 | 
			
		||||
@@ -24,6 +25,8 @@ EXTRA_DIST += gnome-shell.in
 | 
			
		||||
 | 
			
		||||
include Makefile-big.am
 | 
			
		||||
include Makefile-gdmuser.am
 | 
			
		||||
include Makefile-nbtk.am
 | 
			
		||||
include Makefile-toolkit.am
 | 
			
		||||
include Makefile-tray.am
 | 
			
		||||
 | 
			
		||||
gnome_shell_cflags =				\
 | 
			
		||||
@@ -96,7 +99,7 @@ libgnome_shell_la_SOURCES =			\
 | 
			
		||||
	shell-wm.c				\
 | 
			
		||||
	shell-wm.h
 | 
			
		||||
 | 
			
		||||
non_gir_sources =						\
 | 
			
		||||
non_gir_sources =				\
 | 
			
		||||
	shell-embedded-window-private.h
 | 
			
		||||
 | 
			
		||||
shell_recorder_sources =        \
 | 
			
		||||
@@ -114,7 +117,7 @@ if BUILD_RECORDER
 | 
			
		||||
libgnome_shell_la_SOURCES += $(shell_recorder_sources)
 | 
			
		||||
non_gir_sources += $(shell_recorder_non_gir_sources)
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS = test-recorder
 | 
			
		||||
noinst_PROGRAMS += test-recorder
 | 
			
		||||
 | 
			
		||||
test_recorder_CPPFLAGS = $(TEST_SHELL_RECORDER_CFLAGS)
 | 
			
		||||
test_recorder_LDADD = $(TEST_SHELL_RECORDER_LIBS)
 | 
			
		||||
@@ -125,7 +128,7 @@ test_recorder_SOURCES =     \
 | 
			
		||||
endif BUILD_RECORDER
 | 
			
		||||
 | 
			
		||||
libgnome_shell_la_gir_sources = \
 | 
			
		||||
	$(filter-out $(non_gir_sources), $(libgnome_shell_la_SOURCES))
 | 
			
		||||
	$(filter-out $(non_gir_sources) $(non_gir_toolkit_sources), $(libgnome_shell_la_SOURCES) $(toolkit_sources))
 | 
			
		||||
 | 
			
		||||
shell-marshal.h: stamp-shell-marshal.h
 | 
			
		||||
	@true
 | 
			
		||||
@@ -152,14 +155,16 @@ libgnome_shell_la_LIBADD =	\
 | 
			
		||||
	$(MUTTER_PLUGIN_LIBS)	\
 | 
			
		||||
        $(LIBGNOMEUI_LIBS)      \
 | 
			
		||||
	libbig-1.0.la		\
 | 
			
		||||
	libnbtk-1.0.la       	\
 | 
			
		||||
	libgdmuser-1.0.la	\
 | 
			
		||||
	libshell-toolkit.la	\
 | 
			
		||||
	libtray.la
 | 
			
		||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
 | 
			
		||||
 | 
			
		||||
typelibdir = $(pkglibdir)
 | 
			
		||||
typelib_DATA = Shell-0.1.typelib Big-1.0.typelib
 | 
			
		||||
typelib_DATA = Shell-0.1.typelib Big-1.0.typelib Nbtk-1.0.typelib
 | 
			
		||||
 | 
			
		||||
Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) Big-1.0.gir libgnome-shell.la Makefile
 | 
			
		||||
Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) Big-1.0.gir Nbtk-1.0.gir libgnome-shell.la Makefile
 | 
			
		||||
	$(AM_V_GEN) $(G_IR_SCANNER)			\
 | 
			
		||||
		--namespace=Shell			\
 | 
			
		||||
		--nsversion=0.1				\
 | 
			
		||||
@@ -169,6 +174,7 @@ Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) Big-1.0.gir libgnome-shell.la Makefile
 | 
			
		||||
		--libtool="$(LIBTOOL)"    \
 | 
			
		||||
		--add-include-path=$(builddir)     \
 | 
			
		||||
		--include=Big-1.0     \
 | 
			
		||||
		--include=Nbtk-1.0     \
 | 
			
		||||
		--program=mutter			\
 | 
			
		||||
	        --program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la \
 | 
			
		||||
		$(addprefix $(srcdir)/,$(libgnome_shell_la_gir_sources)) \
 | 
			
		||||
@@ -179,14 +185,14 @@ CLEANFILES += Shell-0.1.gir
 | 
			
		||||
# The dependency on libgnome-shell.la here is because g-ir-compiler opens it
 | 
			
		||||
# (not the fake library, since we've already done the rewriting)
 | 
			
		||||
Shell-0.1.typelib: libgnome-shell.la Shell-0.1.gir Big-1.0.gir
 | 
			
		||||
	$(AM_V_GEN) LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}	\
 | 
			
		||||
	$(AM_V_GEN) \
 | 
			
		||||
		$(G_IR_COMPILER)						\
 | 
			
		||||
			--includedir=.						\
 | 
			
		||||
			--includedir=$(MUTTER_LIB_DIR)/mutter/			\
 | 
			
		||||
		Shell-0.1.gir -o $@
 | 
			
		||||
CLEANFILES += Shell-0.1.typelib
 | 
			
		||||
 | 
			
		||||
Big-1.0.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libbig-1.0.la $(srcdir)/big-enum-types.h Makefile
 | 
			
		||||
Big-1.0.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libbig-1.0.la Makefile
 | 
			
		||||
	$(AM_V_GEN) $(G_IR_SCANNER)			\
 | 
			
		||||
		--namespace=Big				\
 | 
			
		||||
		--nsversion=1.0				\
 | 
			
		||||
@@ -203,6 +209,54 @@ Big-1.0.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libbig-1.0.la $(srcdir)
 | 
			
		||||
CLEANFILES += Big-1.0.gir
 | 
			
		||||
 | 
			
		||||
Big-1.0.typelib: libbig-1.0.la Big-1.0.gir
 | 
			
		||||
	$(AM_V_GEN) LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
 | 
			
		||||
		$(G_IR_COMPILER) Big-1.0.gir -o $@
 | 
			
		||||
	$(AM_V_GEN) $(G_IR_COMPILER) Big-1.0.gir -o $@
 | 
			
		||||
CLEANFILES += Big-1.0.typelib
 | 
			
		||||
 | 
			
		||||
toolkit_gir_sources = \
 | 
			
		||||
	$(filter-out $(non_gir_toolkit_sources), $(toolkit_sources))
 | 
			
		||||
 | 
			
		||||
# Since the Shell namepace includes both the code in toolkit/ that our fork of
 | 
			
		||||
# NBTK depends upon and the code in this directory that depends on NBTK, We have a
 | 
			
		||||
# circular dependency when generating the girs and typelibs. We work around this
 | 
			
		||||
# by generating a Toolkit gir, using it to build the Nbtk gir then sed'ing the
 | 
			
		||||
# reference out of the generated gir.
 | 
			
		||||
Toolkit-0.1.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libshell-toolkit.la Makefile
 | 
			
		||||
	$(AM_V_GEN) $(G_IR_SCANNER)						\
 | 
			
		||||
	        --namespace=Shell						\
 | 
			
		||||
		--nsversion=0.1							\
 | 
			
		||||
	        --include=Clutter-1.0						\
 | 
			
		||||
	        --libtool="$(LIBTOOL)"						\
 | 
			
		||||
	        --program=mutter						\
 | 
			
		||||
		--program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la	\
 | 
			
		||||
	        $(addprefix $(srcdir)/,$(toolkit_gir_sources))			\
 | 
			
		||||
	        $(TOOLKIT_CFLAGS)						\
 | 
			
		||||
	        -o $@
 | 
			
		||||
CLEANFILES += Toolkit-1.0.gir
 | 
			
		||||
 | 
			
		||||
Nbtk-1.0.gir: $(mutter) $(G_IR_SCANNER) Toolkit-0.1.gir libgnome-shell.la libnbtk-1.0.la Makefile
 | 
			
		||||
	$(AM_V_GEN) $(G_IR_SCANNER)						\
 | 
			
		||||
	        --namespace=Nbtk						\
 | 
			
		||||
	        --nsversion=1.0							\
 | 
			
		||||
	        --include=Clutter-1.0						\
 | 
			
		||||
	        --include=Gtk-2.0						\
 | 
			
		||||
		--add-include-path=$(builddir)     				\
 | 
			
		||||
		--include=Toolkit-0.1						\
 | 
			
		||||
	        --libtool="$(LIBTOOL)"						\
 | 
			
		||||
	        --program=mutter						\
 | 
			
		||||
		--program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la	\
 | 
			
		||||
	        -DNBTK_COMPILATION						\
 | 
			
		||||
	        $(addprefix $(srcdir)/,$(nbtk_source_h))			\
 | 
			
		||||
	        $(addprefix $(srcdir)/,$(nbtk_source_c))			\
 | 
			
		||||
	        $(srcdir)/nbtk-enum-types.h					\
 | 
			
		||||
	        $(NBTK_CFLAGS)							\
 | 
			
		||||
	        -o $@.tmp &&							\
 | 
			
		||||
	sed -e '/"Toolkit"/d' < $@.tmp > $@
 | 
			
		||||
CLEANFILES += Nbtk-1.0.gir
 | 
			
		||||
 | 
			
		||||
Nbtk-1.0.typelib: Nbtk-1.0.gir
 | 
			
		||||
	$(AM_V_GEN) $(G_IR_COMPILER)						\
 | 
			
		||||
		--includedir=.							\
 | 
			
		||||
		--includedir=$(MUTTER_LIB_DIR)/mutter/				\
 | 
			
		||||
		$< -o $@
 | 
			
		||||
 | 
			
		||||
CLEANFILES += Nbtk-1.0.typelib
 | 
			
		||||
 
 | 
			
		||||
@@ -268,6 +268,52 @@ corner_get(guint         radius,
 | 
			
		||||
    return corner;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* To match the CSS specification, we want the border to look like it was
 | 
			
		||||
 * drawn over the background. But actually drawing the border over the
 | 
			
		||||
 * background will produce slightly bad antialiasing at the edges, so
 | 
			
		||||
 * compute the effective border color instead.
 | 
			
		||||
 */
 | 
			
		||||
#define NORM(x) (t = (x) + 127, (t + (t >> 8)) >> 8)
 | 
			
		||||
#define MULT(c,a) NORM(c*a)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
premultiply (ClutterColor *color)
 | 
			
		||||
{
 | 
			
		||||
    guint t;
 | 
			
		||||
    color->red = MULT (color->red, color->alpha);
 | 
			
		||||
    color->green = MULT (color->green, color->alpha);
 | 
			
		||||
    color->blue = MULT (color->blue, color->alpha);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unpremultiply (ClutterColor *color)
 | 
			
		||||
{
 | 
			
		||||
    if (color->alpha != 0) {
 | 
			
		||||
        color->red = (color->red * 255 + 127) / color->alpha;
 | 
			
		||||
        color->green = (color->green * 255 + 127) / color->alpha;
 | 
			
		||||
        color->blue = (color->blue * 255 + 127) / color->alpha;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
over (const ClutterColor *source,
 | 
			
		||||
      const ClutterColor *destination,
 | 
			
		||||
      ClutterColor       *result)
 | 
			
		||||
{
 | 
			
		||||
    guint t;
 | 
			
		||||
    ClutterColor src = *source;
 | 
			
		||||
    ClutterColor dst = *destination;
 | 
			
		||||
    premultiply (&src);
 | 
			
		||||
    premultiply (&dst);
 | 
			
		||||
 | 
			
		||||
    result->alpha = src.alpha + NORM ((255 - src.alpha) * dst.alpha);
 | 
			
		||||
    result->red   = src.red +   NORM ((255 - src.alpha) * dst.red);
 | 
			
		||||
    result->green = src.green + NORM ((255 - src.alpha) * dst.green);
 | 
			
		||||
    result->blue  = src.blue +  NORM ((255 - src.alpha) * dst.blue);
 | 
			
		||||
 | 
			
		||||
    unpremultiply (result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
big_rectangle_update_corners(BigRectangle *rectangle)
 | 
			
		||||
{
 | 
			
		||||
@@ -278,6 +324,7 @@ big_rectangle_update_corners(BigRectangle *rectangle)
 | 
			
		||||
    if (rectangle->radius != 0) {
 | 
			
		||||
        ClutterColor *color;
 | 
			
		||||
        ClutterColor *border_color;
 | 
			
		||||
        ClutterColor effective_border;
 | 
			
		||||
        guint border_width;
 | 
			
		||||
 | 
			
		||||
        g_object_get(rectangle,
 | 
			
		||||
@@ -286,10 +333,12 @@ big_rectangle_update_corners(BigRectangle *rectangle)
 | 
			
		||||
                     "color", &color,
 | 
			
		||||
                     NULL);
 | 
			
		||||
 | 
			
		||||
        over (border_color, color, &effective_border);
 | 
			
		||||
 | 
			
		||||
        corner = corner_get(rectangle->radius,
 | 
			
		||||
                            color,
 | 
			
		||||
                            border_width,
 | 
			
		||||
                            border_color);
 | 
			
		||||
                            &effective_border);
 | 
			
		||||
 | 
			
		||||
        clutter_color_free(border_color);
 | 
			
		||||
        clutter_color_free(color);
 | 
			
		||||
@@ -329,12 +378,10 @@ big_rectangle_paint(ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
    rectangle = BIG_RECTANGLE(actor);
 | 
			
		||||
 | 
			
		||||
    if (rectangle->radius == 0) {
 | 
			
		||||
        /* In that case we are no different than our parent class,
 | 
			
		||||
         * so don't bother */
 | 
			
		||||
        CLUTTER_ACTOR_CLASS(big_rectangle_parent_class)->paint(actor);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    /* We can't chain up, even when we the radius is 0, because of the different
 | 
			
		||||
     * interpretation of the border/background relationship here than for
 | 
			
		||||
     * ClutterRectangle.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    if (rectangle->corners_dirty)
 | 
			
		||||
        big_rectangle_update_corners(rectangle);
 | 
			
		||||
@@ -345,6 +392,9 @@ big_rectangle_paint(ClutterActor *actor)
 | 
			
		||||
                 "color", &color,
 | 
			
		||||
                 NULL);
 | 
			
		||||
 | 
			
		||||
    if (border_color->alpha == 0 && color->alpha == 0)
 | 
			
		||||
        goto out;
 | 
			
		||||
 | 
			
		||||
    actor_opacity = clutter_actor_get_paint_opacity (actor);
 | 
			
		||||
 | 
			
		||||
    clutter_actor_get_allocation_box(actor, &box);
 | 
			
		||||
@@ -358,6 +408,11 @@ big_rectangle_paint(ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
    radius = rectangle->radius;
 | 
			
		||||
 | 
			
		||||
    /* Optimization; if the border is transparent, it just looks like part of
 | 
			
		||||
     * the background */
 | 
			
		||||
    if (radius == 0 && border_color->alpha == 0)
 | 
			
		||||
        border_width = 0;
 | 
			
		||||
 | 
			
		||||
    max = MAX(border_width, radius);
 | 
			
		||||
 | 
			
		||||
    if (radius != 0) {
 | 
			
		||||
@@ -393,33 +448,54 @@ big_rectangle_paint(ClutterActor *actor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (border_width != 0) {
 | 
			
		||||
        ClutterColor effective_border;
 | 
			
		||||
        over (border_color, color, &effective_border);
 | 
			
		||||
 | 
			
		||||
        if (!rectangle->border_material)
 | 
			
		||||
            rectangle->border_material = cogl_material_new ();
 | 
			
		||||
 | 
			
		||||
        cogl_color_set_from_4ub(&tmp_color,
 | 
			
		||||
                                border_color->red,
 | 
			
		||||
                                border_color->green,
 | 
			
		||||
                                border_color->blue,
 | 
			
		||||
                                actor_opacity * border_color->alpha / 255);
 | 
			
		||||
                                effective_border.red,
 | 
			
		||||
                                effective_border.green,
 | 
			
		||||
                                effective_border.blue,
 | 
			
		||||
                                actor_opacity * effective_border.alpha / 255);
 | 
			
		||||
        cogl_color_premultiply (&tmp_color);
 | 
			
		||||
        cogl_material_set_color(rectangle->border_material, &tmp_color);
 | 
			
		||||
        cogl_set_source(rectangle->border_material);
 | 
			
		||||
 | 
			
		||||
        /* NORTH */
 | 
			
		||||
        cogl_rectangle(max, 0,
 | 
			
		||||
                       width - max, border_width);
 | 
			
		||||
        if (radius > 0) { /* skip corners */
 | 
			
		||||
            /* NORTH */
 | 
			
		||||
            cogl_rectangle(max, 0,
 | 
			
		||||
                           width - max, border_width);
 | 
			
		||||
 | 
			
		||||
        /* EAST */
 | 
			
		||||
        cogl_rectangle(width - border_width, max,
 | 
			
		||||
                       width, height - max);
 | 
			
		||||
            /* EAST */
 | 
			
		||||
            cogl_rectangle(width - border_width, max,
 | 
			
		||||
                           width, height - max);
 | 
			
		||||
 | 
			
		||||
        /* SOUTH */
 | 
			
		||||
        cogl_rectangle(max, height - border_width,
 | 
			
		||||
                       width - max, height);
 | 
			
		||||
            /* SOUTH */
 | 
			
		||||
            cogl_rectangle(max, height - border_width,
 | 
			
		||||
                           width - max, height);
 | 
			
		||||
 | 
			
		||||
        /* WEST */
 | 
			
		||||
        cogl_rectangle(0, max,
 | 
			
		||||
                       border_width, height - max);
 | 
			
		||||
            /* WEST */
 | 
			
		||||
            cogl_rectangle(0, max,
 | 
			
		||||
                           border_width, height - max);
 | 
			
		||||
        } else { /* include corners */
 | 
			
		||||
            /* NORTH */
 | 
			
		||||
            cogl_rectangle(0, 0,
 | 
			
		||||
                           width, border_width);
 | 
			
		||||
 | 
			
		||||
            /* EAST */
 | 
			
		||||
            cogl_rectangle(width - border_width, border_width,
 | 
			
		||||
                           width, height - border_width);
 | 
			
		||||
 | 
			
		||||
            /* SOUTH */
 | 
			
		||||
            cogl_rectangle(0, height - border_width,
 | 
			
		||||
                           width, height);
 | 
			
		||||
 | 
			
		||||
            /* WEST */
 | 
			
		||||
            cogl_rectangle(0, border_width,
 | 
			
		||||
                           border_width, height - border_width);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!rectangle->background_material)
 | 
			
		||||
@@ -455,6 +531,7 @@ big_rectangle_paint(ClutterActor *actor)
 | 
			
		||||
    cogl_rectangle(border_width, max,
 | 
			
		||||
                   width - border_width, height - max);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    clutter_color_free(border_color);
 | 
			
		||||
    clutter_color_free(color);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,64 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#include <mutter-plugin.h>
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
mutter_plugin_get_stage (MutterPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GList *
 | 
			
		||||
mutter_plugin_get_windows (MutterPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mutter_plugin_query_screen_size (MutterPlugin *plugin,
 | 
			
		||||
                                 int          *width,
 | 
			
		||||
                                 int          *height)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
 | 
			
		||||
                                    gint x, gint y, gint width, gint height)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaScreen *
 | 
			
		||||
mutter_plugin_get_screen (MutterPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
mutter_plugin_get_window_group (MutterPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Display *
 | 
			
		||||
meta_display_get_xdisplay (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaDisplay *
 | 
			
		||||
meta_screen_get_display (MetaScreen *display)
 | 
			
		||||
{
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Window
 | 
			
		||||
meta_screen_get_xroot (MetaScreen *display)
 | 
			
		||||
{
 | 
			
		||||
  return None;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										768
									
								
								src/nbtk/nbtk-adjustment.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										768
									
								
								src/nbtk/nbtk-adjustment.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,768 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-adjustment.c: Adjustment object
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008 OpenedHand
 | 
			
		||||
 * Copyright (c) 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>, inspired by GtkAdjustment
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-adjustment.h"
 | 
			
		||||
#include "nbtk-marshal.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkAdjustment, nbtk_adjustment, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
#define ADJUSTMENT_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_ADJUSTMENT, NbtkAdjustmentPrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkAdjustmentPrivate
 | 
			
		||||
{
 | 
			
		||||
  /* Do not sanity-check values while constructing,
 | 
			
		||||
   * not all properties may be set yet. */
 | 
			
		||||
  gboolean is_constructing : 1;
 | 
			
		||||
 | 
			
		||||
  gdouble lower;
 | 
			
		||||
  gdouble upper;
 | 
			
		||||
  gdouble value;
 | 
			
		||||
  gdouble step_increment;
 | 
			
		||||
  gdouble page_increment;
 | 
			
		||||
  gdouble page_size;
 | 
			
		||||
 | 
			
		||||
  /* For interpolation */
 | 
			
		||||
  ClutterTimeline *interpolation;
 | 
			
		||||
  gdouble old_position;
 | 
			
		||||
  gdouble new_position;
 | 
			
		||||
 | 
			
		||||
  /* For elasticity */
 | 
			
		||||
  gboolean      elastic;
 | 
			
		||||
  guint         bounce_source;
 | 
			
		||||
  ClutterAlpha *bounce_alpha;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_LOWER,
 | 
			
		||||
  PROP_UPPER,
 | 
			
		||||
  PROP_VALUE,
 | 
			
		||||
  PROP_STEP_INC,
 | 
			
		||||
  PROP_PAGE_INC,
 | 
			
		||||
  PROP_PAGE_SIZE,
 | 
			
		||||
 | 
			
		||||
  PROP_ELASTIC,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CHANGED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
static gboolean nbtk_adjustment_set_lower          (NbtkAdjustment *adjustment,
 | 
			
		||||
                                                    gdouble         lower);
 | 
			
		||||
static gboolean nbtk_adjustment_set_upper          (NbtkAdjustment *adjustment,
 | 
			
		||||
                                                    gdouble         upper);
 | 
			
		||||
static gboolean nbtk_adjustment_set_step_increment (NbtkAdjustment *adjustment,
 | 
			
		||||
                                                    gdouble         step);
 | 
			
		||||
static gboolean nbtk_adjustment_set_page_increment (NbtkAdjustment *adjustment,
 | 
			
		||||
                                                    gdouble         page);
 | 
			
		||||
static gboolean nbtk_adjustment_set_page_size      (NbtkAdjustment *adjustment,
 | 
			
		||||
                                                    gdouble         size);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_adjustment_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *g_class;
 | 
			
		||||
  NbtkAdjustment *self = NBTK_ADJUSTMENT (object);
 | 
			
		||||
 | 
			
		||||
  g_class = G_OBJECT_CLASS (nbtk_adjustment_parent_class);
 | 
			
		||||
  /* The docs say we're suppose to chain up, but would crash without
 | 
			
		||||
   * some extra care. */
 | 
			
		||||
  if (g_class && g_class->constructed &&
 | 
			
		||||
      g_class->constructed != nbtk_adjustment_constructed)
 | 
			
		||||
    {
 | 
			
		||||
      g_class->constructed (object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  NBTK_ADJUSTMENT (self)->priv->is_constructing = FALSE;
 | 
			
		||||
  nbtk_adjustment_clamp_page (self, self->priv->lower, self->priv->upper);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_adjustment_get_property (GObject    *gobject,
 | 
			
		||||
                              guint       prop_id,
 | 
			
		||||
                              GValue     *value,
 | 
			
		||||
                              GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = NBTK_ADJUSTMENT (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_LOWER:
 | 
			
		||||
      g_value_set_double (value, priv->lower);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_UPPER:
 | 
			
		||||
      g_value_set_double (value, priv->upper);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_VALUE:
 | 
			
		||||
      g_value_set_double (value, priv->value);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_STEP_INC:
 | 
			
		||||
      g_value_set_double (value, priv->step_increment);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_PAGE_INC:
 | 
			
		||||
      g_value_set_double (value, priv->page_increment);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_PAGE_SIZE:
 | 
			
		||||
      g_value_set_double (value, priv->page_size);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_ELASTIC:
 | 
			
		||||
      g_value_set_boolean (value, priv->elastic);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_adjustment_set_property (GObject      *gobject,
 | 
			
		||||
                              guint         prop_id,
 | 
			
		||||
                              const GValue *value,
 | 
			
		||||
                              GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment *adj = NBTK_ADJUSTMENT (gobject);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_LOWER:
 | 
			
		||||
      nbtk_adjustment_set_lower (adj, g_value_get_double (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_UPPER:
 | 
			
		||||
      nbtk_adjustment_set_upper (adj, g_value_get_double (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_VALUE:
 | 
			
		||||
      nbtk_adjustment_set_value (adj, g_value_get_double (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_STEP_INC:
 | 
			
		||||
      nbtk_adjustment_set_step_increment (adj, g_value_get_double (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_PAGE_INC:
 | 
			
		||||
      nbtk_adjustment_set_page_increment (adj, g_value_get_double (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_PAGE_SIZE:
 | 
			
		||||
      nbtk_adjustment_set_page_size (adj, g_value_get_double (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_ELASTIC:
 | 
			
		||||
      nbtk_adjustment_set_elastic (adj, g_value_get_boolean (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
stop_interpolation (NbtkAdjustment *adjustment)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->interpolation)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_timeline_stop (priv->interpolation);
 | 
			
		||||
      g_object_unref (priv->interpolation);
 | 
			
		||||
      priv->interpolation = NULL;
 | 
			
		||||
 | 
			
		||||
      if (priv->bounce_alpha)
 | 
			
		||||
        {
 | 
			
		||||
          g_object_unref (priv->bounce_alpha);
 | 
			
		||||
          priv->bounce_alpha = NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->bounce_source)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (priv->bounce_source);
 | 
			
		||||
      priv->bounce_source = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_adjustment_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  stop_interpolation (NBTK_ADJUSTMENT (object));
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_adjustment_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_adjustment_class_init (NbtkAdjustmentClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkAdjustmentPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class->constructed = nbtk_adjustment_constructed;
 | 
			
		||||
  object_class->get_property = nbtk_adjustment_get_property;
 | 
			
		||||
  object_class->set_property = nbtk_adjustment_set_property;
 | 
			
		||||
  object_class->dispose = nbtk_adjustment_dispose;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_LOWER,
 | 
			
		||||
                                   g_param_spec_double ("lower",
 | 
			
		||||
                                                        "Lower",
 | 
			
		||||
                                                        "Lower bound",
 | 
			
		||||
                                                        -G_MAXDOUBLE,
 | 
			
		||||
                                                        G_MAXDOUBLE,
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_UPPER,
 | 
			
		||||
                                   g_param_spec_double ("upper",
 | 
			
		||||
                                                        "Upper",
 | 
			
		||||
                                                        "Upper bound",
 | 
			
		||||
                                                        -G_MAXDOUBLE,
 | 
			
		||||
                                                        G_MAXDOUBLE,
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_VALUE,
 | 
			
		||||
                                   g_param_spec_double ("value",
 | 
			
		||||
                                                        "Value",
 | 
			
		||||
                                                        "Current value",
 | 
			
		||||
                                                        -G_MAXDOUBLE,
 | 
			
		||||
                                                        G_MAXDOUBLE,
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_STEP_INC,
 | 
			
		||||
                                   g_param_spec_double ("step-increment",
 | 
			
		||||
                                                        "Step Increment",
 | 
			
		||||
                                                        "Step increment",
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        G_MAXDOUBLE,
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_PAGE_INC,
 | 
			
		||||
                                   g_param_spec_double ("page-increment",
 | 
			
		||||
                                                        "Page Increment",
 | 
			
		||||
                                                        "Page increment",
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        G_MAXDOUBLE,
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_PAGE_SIZE,
 | 
			
		||||
                                   g_param_spec_double ("page-size",
 | 
			
		||||
                                                        "Page Size",
 | 
			
		||||
                                                        "Page size",
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        G_MAXDOUBLE,
 | 
			
		||||
                                                        0.0,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_ELASTIC,
 | 
			
		||||
                                   g_param_spec_boolean ("elastic",
 | 
			
		||||
                                                         "Elastic",
 | 
			
		||||
                                                         "Make interpolation "
 | 
			
		||||
                                                         "behave in an "
 | 
			
		||||
                                                         "'elastic' way and "
 | 
			
		||||
                                                         "stop clamping value.",
 | 
			
		||||
                                                         FALSE,
 | 
			
		||||
                                                        NBTK_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT));
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkAdjustment::changed:
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when any of the adjustment values have changed
 | 
			
		||||
   */
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new ("changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (NbtkAdjustmentClass, changed),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _nbtk_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_adjustment_init (NbtkAdjustment *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = ADJUSTMENT_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  self->priv->is_constructing = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkAdjustment *
 | 
			
		||||
nbtk_adjustment_new (gdouble value,
 | 
			
		||||
                     gdouble lower,
 | 
			
		||||
                     gdouble upper,
 | 
			
		||||
                     gdouble step_increment,
 | 
			
		||||
                     gdouble page_increment,
 | 
			
		||||
                     gdouble page_size)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (NBTK_TYPE_ADJUSTMENT,
 | 
			
		||||
                       "value", value,
 | 
			
		||||
                       "lower", lower,
 | 
			
		||||
                       "upper", upper,
 | 
			
		||||
                       "step-increment", step_increment,
 | 
			
		||||
                       "page-increment", page_increment,
 | 
			
		||||
                       "page-size", page_size,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gdouble
 | 
			
		||||
nbtk_adjustment_get_value (NbtkAdjustment *adjustment)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_ADJUSTMENT (adjustment), 0);
 | 
			
		||||
 | 
			
		||||
  priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->interpolation)
 | 
			
		||||
    {
 | 
			
		||||
      return MAX (priv->lower,
 | 
			
		||||
                  MIN (priv->upper - priv->page_size,
 | 
			
		||||
                       priv->new_position));
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return priv->value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_adjustment_set_value (NbtkAdjustment *adjustment,
 | 
			
		||||
                           gdouble         value)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
 | 
			
		||||
 | 
			
		||||
  priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  stop_interpolation (adjustment);
 | 
			
		||||
 | 
			
		||||
  /* Defer clamp until after construction. */
 | 
			
		||||
  if (!priv->is_constructing)
 | 
			
		||||
    {
 | 
			
		||||
      if (!priv->elastic)
 | 
			
		||||
        value = CLAMP (value,
 | 
			
		||||
                       priv->lower,
 | 
			
		||||
                       MAX (priv->lower, priv->upper - priv->page_size));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->value != value)
 | 
			
		||||
    {
 | 
			
		||||
      priv->value = value;
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (adjustment), "value");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_adjustment_clamp_page (NbtkAdjustment *adjustment,
 | 
			
		||||
                            gdouble         lower,
 | 
			
		||||
                            gdouble         upper)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv;
 | 
			
		||||
  gboolean changed;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
 | 
			
		||||
 | 
			
		||||
  priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  stop_interpolation (adjustment);
 | 
			
		||||
 | 
			
		||||
  lower = CLAMP (lower, priv->lower, priv->upper - priv->page_size);
 | 
			
		||||
  upper = CLAMP (upper, priv->lower + priv->page_size, priv->upper);
 | 
			
		||||
 | 
			
		||||
  changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (priv->value + priv->page_size > upper)
 | 
			
		||||
    {
 | 
			
		||||
      priv->value = upper - priv->page_size;
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->value < lower)
 | 
			
		||||
    {
 | 
			
		||||
      priv->value = lower;
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    g_object_notify (G_OBJECT (adjustment), "value");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_adjustment_set_lower (NbtkAdjustment *adjustment,
 | 
			
		||||
                           gdouble         lower)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->lower != lower)
 | 
			
		||||
    {
 | 
			
		||||
      priv->lower = lower;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (adjustment, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (adjustment), "lower");
 | 
			
		||||
 | 
			
		||||
      /* Defer clamp until after construction. */
 | 
			
		||||
      if (!priv->is_constructing)
 | 
			
		||||
        nbtk_adjustment_clamp_page (adjustment, priv->lower, priv->upper);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_adjustment_set_upper (NbtkAdjustment *adjustment,
 | 
			
		||||
                           gdouble         upper)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->upper != upper)
 | 
			
		||||
    {
 | 
			
		||||
      priv->upper = upper;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (adjustment, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (adjustment), "upper");
 | 
			
		||||
 | 
			
		||||
      /* Defer clamp until after construction. */
 | 
			
		||||
      if (!priv->is_constructing)
 | 
			
		||||
        nbtk_adjustment_clamp_page (adjustment, priv->lower, priv->upper);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_adjustment_set_step_increment (NbtkAdjustment *adjustment,
 | 
			
		||||
                                    gdouble         step)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->step_increment != step)
 | 
			
		||||
    {
 | 
			
		||||
      priv->step_increment = step;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (adjustment, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (adjustment), "step-increment");
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_adjustment_set_page_increment (NbtkAdjustment *adjustment,
 | 
			
		||||
                                    gdouble         page)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->page_increment != page)
 | 
			
		||||
    {
 | 
			
		||||
      priv->page_increment = page;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (adjustment, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (adjustment), "page-increment");
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_adjustment_set_page_size (NbtkAdjustment *adjustment,
 | 
			
		||||
                               gdouble         size)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->page_size != size)
 | 
			
		||||
    {
 | 
			
		||||
      priv->page_size = size;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (adjustment, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (adjustment), "page_size");
 | 
			
		||||
 | 
			
		||||
      /* Well explicitely clamp after construction. */
 | 
			
		||||
      if (!priv->is_constructing)
 | 
			
		||||
        nbtk_adjustment_clamp_page (adjustment, priv->lower, priv->upper);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_adjustment_set_values (NbtkAdjustment *adjustment,
 | 
			
		||||
                            gdouble         value,
 | 
			
		||||
                            gdouble         lower,
 | 
			
		||||
                            gdouble         upper,
 | 
			
		||||
                            gdouble         step_increment,
 | 
			
		||||
                            gdouble         page_increment,
 | 
			
		||||
                            gdouble         page_size)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv;
 | 
			
		||||
  gboolean emit_changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
 | 
			
		||||
  g_return_if_fail (page_size >= 0 && page_size <= G_MAXDOUBLE);
 | 
			
		||||
  g_return_if_fail (step_increment >= 0 && step_increment <= G_MAXDOUBLE);
 | 
			
		||||
  g_return_if_fail (page_increment >= 0 && page_increment <= G_MAXDOUBLE);
 | 
			
		||||
 | 
			
		||||
  priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  stop_interpolation (adjustment);
 | 
			
		||||
 | 
			
		||||
  emit_changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (G_OBJECT (adjustment));
 | 
			
		||||
 | 
			
		||||
  emit_changed |= nbtk_adjustment_set_lower (adjustment, lower);
 | 
			
		||||
  emit_changed |= nbtk_adjustment_set_upper (adjustment, upper);
 | 
			
		||||
  emit_changed |= nbtk_adjustment_set_step_increment (adjustment, step_increment);
 | 
			
		||||
  emit_changed |= nbtk_adjustment_set_page_increment (adjustment, page_increment);
 | 
			
		||||
  emit_changed |= nbtk_adjustment_set_page_size (adjustment, page_size);
 | 
			
		||||
 | 
			
		||||
  if (value != priv->value)
 | 
			
		||||
    {
 | 
			
		||||
      nbtk_adjustment_set_value (adjustment, value);
 | 
			
		||||
      emit_changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (emit_changed)
 | 
			
		||||
    g_signal_emit (G_OBJECT (adjustment), signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (G_OBJECT (adjustment));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_adjustment_get_values (NbtkAdjustment *adjustment,
 | 
			
		||||
                            gdouble        *value,
 | 
			
		||||
                            gdouble        *lower,
 | 
			
		||||
                            gdouble        *upper,
 | 
			
		||||
                            gdouble        *step_increment,
 | 
			
		||||
                            gdouble        *page_increment,
 | 
			
		||||
                            gdouble        *page_size)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ADJUSTMENT (adjustment));
 | 
			
		||||
 | 
			
		||||
  priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  if (lower)
 | 
			
		||||
    *lower = priv->lower;
 | 
			
		||||
 | 
			
		||||
  if (upper)
 | 
			
		||||
    *upper = priv->upper;
 | 
			
		||||
 | 
			
		||||
  if (value)
 | 
			
		||||
    *value = nbtk_adjustment_get_value (adjustment);
 | 
			
		||||
 | 
			
		||||
  if (step_increment)
 | 
			
		||||
    *step_increment = priv->step_increment;
 | 
			
		||||
 | 
			
		||||
  if (page_increment)
 | 
			
		||||
    *page_increment = priv->page_increment;
 | 
			
		||||
 | 
			
		||||
  if (page_size)
 | 
			
		||||
    *page_size = priv->page_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
interpolation_new_frame_cb (ClutterTimeline *timeline,
 | 
			
		||||
                            guint            msecs,
 | 
			
		||||
                            NbtkAdjustment  *adjustment)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  priv->interpolation = NULL;
 | 
			
		||||
 | 
			
		||||
  if (priv->elastic)
 | 
			
		||||
    {
 | 
			
		||||
      gdouble progress = clutter_alpha_get_alpha (priv->bounce_alpha) / 1.0;
 | 
			
		||||
      gdouble dx = priv->old_position
 | 
			
		||||
                 + (priv->new_position - priv->old_position)
 | 
			
		||||
                 * progress;
 | 
			
		||||
 | 
			
		||||
      nbtk_adjustment_set_value (adjustment, dx);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    nbtk_adjustment_set_value (adjustment,
 | 
			
		||||
                               priv->old_position +
 | 
			
		||||
                               (priv->new_position - priv->old_position) *
 | 
			
		||||
                               clutter_timeline_get_progress (timeline));
 | 
			
		||||
 | 
			
		||||
  priv->interpolation = timeline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
interpolation_completed_cb (ClutterTimeline *timeline,
 | 
			
		||||
                            NbtkAdjustment  *adjustment)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  stop_interpolation (adjustment);
 | 
			
		||||
  nbtk_adjustment_set_value (adjustment, priv->new_position);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Note, there's super-optimal code that does a similar thing in
 | 
			
		||||
 * clutter-alpha.c
 | 
			
		||||
 *
 | 
			
		||||
 * Tried this instead of CLUTTER_ALPHA_SINE_INC, but I think SINE_INC looks
 | 
			
		||||
 * better. Leaving code here in case this is revisited.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
static guint32
 | 
			
		||||
bounce_alpha_func (ClutterAlpha *alpha,
 | 
			
		||||
                   gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterFixed progress, angle;
 | 
			
		||||
  ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha);
 | 
			
		||||
 | 
			
		||||
  progress = clutter_timeline_get_progressx (timeline);
 | 
			
		||||
  angle = clutter_qmulx (CFX_PI_2 + CFX_PI_4/2, progress);
 | 
			
		||||
 | 
			
		||||
  return clutter_sinx (angle) +
 | 
			
		||||
    (CFX_ONE - clutter_sinx (CFX_PI_2 + CFX_PI_4/2));
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_adjustment_interpolate (NbtkAdjustment *adjustment,
 | 
			
		||||
                             gdouble         value,
 | 
			
		||||
                             guint           duration)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
 | 
			
		||||
  stop_interpolation (adjustment);
 | 
			
		||||
 | 
			
		||||
  if (duration <= 1)
 | 
			
		||||
    {
 | 
			
		||||
      nbtk_adjustment_set_value (adjustment, value);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->old_position = priv->value;
 | 
			
		||||
  priv->new_position = value;
 | 
			
		||||
 | 
			
		||||
  priv->interpolation = clutter_timeline_new (duration);
 | 
			
		||||
 | 
			
		||||
  if (priv->elastic)
 | 
			
		||||
    priv->bounce_alpha = clutter_alpha_new_full (priv->interpolation,
 | 
			
		||||
                                                 CLUTTER_LINEAR);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (priv->interpolation,
 | 
			
		||||
                    "new-frame",
 | 
			
		||||
                    G_CALLBACK (interpolation_new_frame_cb),
 | 
			
		||||
                    adjustment);
 | 
			
		||||
  g_signal_connect (priv->interpolation,
 | 
			
		||||
                    "completed",
 | 
			
		||||
                    G_CALLBACK (interpolation_completed_cb),
 | 
			
		||||
                    adjustment);
 | 
			
		||||
 | 
			
		||||
  clutter_timeline_start (priv->interpolation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
nbtk_adjustment_get_elastic (NbtkAdjustment *adjustment)
 | 
			
		||||
{
 | 
			
		||||
  return adjustment->priv->elastic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_adjustment_set_elastic (NbtkAdjustment *adjustment,
 | 
			
		||||
                             gboolean        elastic)
 | 
			
		||||
{
 | 
			
		||||
  adjustment->priv->elastic = elastic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
nbtk_adjustment_clamp (NbtkAdjustment *adjustment,
 | 
			
		||||
                       gboolean        interpolate,
 | 
			
		||||
                       guint           duration)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustmentPrivate *priv = adjustment->priv;
 | 
			
		||||
  gdouble dest = priv->value;
 | 
			
		||||
 | 
			
		||||
  if (priv->value < priv->lower)
 | 
			
		||||
    dest = priv->lower;
 | 
			
		||||
 | 
			
		||||
  if (priv->value > priv->upper - priv->page_size)
 | 
			
		||||
    dest = priv->upper - priv->page_size;
 | 
			
		||||
 | 
			
		||||
  if (dest != priv->value)
 | 
			
		||||
    {
 | 
			
		||||
      if (interpolate)
 | 
			
		||||
        nbtk_adjustment_interpolate (adjustment, dest, duration);
 | 
			
		||||
      else
 | 
			
		||||
        nbtk_adjustment_set_value (adjustment, dest);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										121
									
								
								src/nbtk/nbtk-adjustment.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								src/nbtk/nbtk-adjustment.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-adjustment.h: Adjustment object
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>, inspired by GtkAdjustment
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_ADJUSTMENT_H__
 | 
			
		||||
#define __NBTK_ADJUSTMENT_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_ADJUSTMENT            (nbtk_adjustment_get_type())
 | 
			
		||||
#define NBTK_ADJUSTMENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_ADJUSTMENT, NbtkAdjustment))
 | 
			
		||||
#define NBTK_IS_ADJUSTMENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_ADJUSTMENT))
 | 
			
		||||
#define NBTK_ADJUSTMENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_ADJUSTMENT, NbtkAdjustmentClass))
 | 
			
		||||
#define NBTK_IS_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_ADJUSTMENT))
 | 
			
		||||
#define NBTK_ADJUSTMENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_ADJUSTMENT, NbtkAdjustmentClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkAdjustment          NbtkAdjustment;
 | 
			
		||||
typedef struct _NbtkAdjustmentPrivate   NbtkAdjustmentPrivate;
 | 
			
		||||
typedef struct _NbtkAdjustmentClass     NbtkAdjustmentClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkAdjustment:
 | 
			
		||||
 *
 | 
			
		||||
 * Class for handling an interval between to values. The contents of
 | 
			
		||||
 * the #NbtkAdjustment are private and should be accessed using the
 | 
			
		||||
 * public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkAdjustment
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkAdjustmentPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkAdjustmentClass
 | 
			
		||||
 * @changed: Class handler for the ::changed signal.
 | 
			
		||||
 *
 | 
			
		||||
 * Base class for #NbtkAdjustment.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkAdjustmentClass
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /*< public >*/
 | 
			
		||||
  void (* changed) (NbtkAdjustment *adjustment);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_adjustment_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkAdjustment *nbtk_adjustment_new          (gdouble         value,
 | 
			
		||||
                                              gdouble         lower,
 | 
			
		||||
                                              gdouble         upper,
 | 
			
		||||
                                              gdouble         step_increment,
 | 
			
		||||
                                              gdouble         page_increment,
 | 
			
		||||
                                              gdouble         page_size);
 | 
			
		||||
gdouble         nbtk_adjustment_get_value    (NbtkAdjustment *adjustment);
 | 
			
		||||
void            nbtk_adjustment_set_value    (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gdouble         value);
 | 
			
		||||
void            nbtk_adjustment_clamp_page   (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gdouble         lower,
 | 
			
		||||
                                              gdouble         upper);
 | 
			
		||||
void            nbtk_adjustment_set_values   (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gdouble         value,
 | 
			
		||||
                                              gdouble         lower,
 | 
			
		||||
                                              gdouble         upper,
 | 
			
		||||
                                              gdouble         step_increment,
 | 
			
		||||
                                              gdouble         page_increment,
 | 
			
		||||
                                              gdouble         page_size);
 | 
			
		||||
void            nbtk_adjustment_get_values   (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gdouble        *value,
 | 
			
		||||
                                              gdouble        *lower,
 | 
			
		||||
                                              gdouble        *upper,
 | 
			
		||||
                                              gdouble        *step_increment,
 | 
			
		||||
                                              gdouble        *page_increment,
 | 
			
		||||
                                              gdouble        *page_size);
 | 
			
		||||
 | 
			
		||||
void            nbtk_adjustment_interpolate  (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gdouble         value,
 | 
			
		||||
                                              guint           duration);
 | 
			
		||||
 | 
			
		||||
gboolean        nbtk_adjustment_get_elastic  (NbtkAdjustment *adjustment);
 | 
			
		||||
void            nbtk_adjustment_set_elastic  (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gboolean        elastic);
 | 
			
		||||
 | 
			
		||||
gboolean        nbtk_adjustment_clamp        (NbtkAdjustment *adjustment,
 | 
			
		||||
                                              gboolean        interpolate,
 | 
			
		||||
                                              guint           duration);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_ADJUSTMENT_H__ */
 | 
			
		||||
							
								
								
									
										739
									
								
								src/nbtk/nbtk-bin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										739
									
								
								src/nbtk/nbtk-bin.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,739 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-bin.c: Basic container actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Emmanuele Bassi <ebassi@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-bin
 | 
			
		||||
 * @short_description: a simple container with one actor
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkBin is a simple container capable of having only one
 | 
			
		||||
 * #ClutterActor as a child.
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkBin inherits from #NbtkWidget, so it is fully themable.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-bin.h"
 | 
			
		||||
#include "nbtk-enum-types.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
#define NBTK_BIN_GET_PRIVATE(obj)       (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_BIN, NbtkBinPrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkBinPrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *child;
 | 
			
		||||
 | 
			
		||||
  NbtkAlignment x_align;
 | 
			
		||||
  NbtkAlignment y_align;
 | 
			
		||||
 | 
			
		||||
  guint x_fill : 1;
 | 
			
		||||
  guint y_fill : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_CHILD,
 | 
			
		||||
  PROP_X_ALIGN,
 | 
			
		||||
  PROP_Y_ALIGN,
 | 
			
		||||
  PROP_X_FILL,
 | 
			
		||||
  PROP_Y_FILL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (NbtkBin, nbtk_bin, NBTK_TYPE_WIDGET,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
 | 
			
		||||
                                                clutter_container_iface_init));
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_nbtk_bin_get_align_factors (NbtkBin *bin,
 | 
			
		||||
                             gdouble *x_align,
 | 
			
		||||
                             gdouble *y_align)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = bin->priv;
 | 
			
		||||
  gdouble factor;
 | 
			
		||||
 | 
			
		||||
  switch (priv->x_align)
 | 
			
		||||
    {
 | 
			
		||||
    case NBTK_ALIGN_LEFT:
 | 
			
		||||
      factor = 0.0;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case NBTK_ALIGN_CENTER:
 | 
			
		||||
      factor = 0.5;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case NBTK_ALIGN_RIGHT:
 | 
			
		||||
      factor = 1.0;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      factor = 0.0;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (x_align)
 | 
			
		||||
    *x_align = factor;
 | 
			
		||||
 | 
			
		||||
  switch (priv->y_align)
 | 
			
		||||
    {
 | 
			
		||||
    case NBTK_ALIGN_TOP:
 | 
			
		||||
      factor = 0.0;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case NBTK_ALIGN_CENTER:
 | 
			
		||||
      factor = 0.5;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case NBTK_ALIGN_BOTTOM:
 | 
			
		||||
      factor = 1.0;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      factor = 0.0;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (y_align)
 | 
			
		||||
    *y_align = factor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_add (ClutterContainer *container,
 | 
			
		||||
              ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  nbtk_bin_set_child (NBTK_BIN (container), actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_remove (ClutterContainer *container,
 | 
			
		||||
                 ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (container)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->child == actor)
 | 
			
		||||
    nbtk_bin_set_child (NBTK_BIN (container), NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_foreach (ClutterContainer *container,
 | 
			
		||||
                  ClutterCallback   callback,
 | 
			
		||||
                  gpointer          user_data)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (container)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
    callback (priv->child, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_container_iface_init (ClutterContainerIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->add = nbtk_bin_add;
 | 
			
		||||
  iface->remove = nbtk_bin_remove;
 | 
			
		||||
  iface->foreach = nbtk_bin_foreach;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_paint (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (self)->priv;
 | 
			
		||||
 | 
			
		||||
  /* allow NbtkWidget to paint the background */
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_bin_parent_class)->paint (self);
 | 
			
		||||
 | 
			
		||||
  /* the pain our child */
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
    clutter_actor_paint (priv->child);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_pick (ClutterActor       *self,
 | 
			
		||||
               const ClutterColor *pick_color)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (self)->priv;
 | 
			
		||||
 | 
			
		||||
  /* get the default pick implementation */
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_bin_parent_class)->pick (self, pick_color);
 | 
			
		||||
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
    clutter_actor_paint (priv->child);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_allocate (ClutterActor          *self,
 | 
			
		||||
                   const ClutterActorBox *box,
 | 
			
		||||
                   ClutterAllocationFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (self)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_bin_parent_class)->allocate (self, box,
 | 
			
		||||
                                                         flags);
 | 
			
		||||
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
    {
 | 
			
		||||
      ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (self));
 | 
			
		||||
      gfloat natural_width, natural_height;
 | 
			
		||||
      gfloat min_width, min_height;
 | 
			
		||||
      gfloat child_width, child_height;
 | 
			
		||||
      gfloat available_width, available_height;
 | 
			
		||||
      ClutterRequestMode request;
 | 
			
		||||
      ClutterActorBox content_box;
 | 
			
		||||
      ClutterActorBox allocation = { 0, };
 | 
			
		||||
      gdouble x_align, y_align;
 | 
			
		||||
 | 
			
		||||
      shell_theme_node_get_content_box (theme_node, box, &content_box);
 | 
			
		||||
 | 
			
		||||
      _nbtk_bin_get_align_factors (NBTK_BIN (self), &x_align, &y_align);
 | 
			
		||||
 | 
			
		||||
      available_width  = content_box.x2 - content_box.x1;
 | 
			
		||||
      available_height = content_box.y2 - content_box.y1;
 | 
			
		||||
 | 
			
		||||
      if (available_width < 0)
 | 
			
		||||
        available_width = 0;
 | 
			
		||||
 | 
			
		||||
      if (available_height < 0)
 | 
			
		||||
        available_height = 0;
 | 
			
		||||
 | 
			
		||||
      if (priv->x_fill)
 | 
			
		||||
        {
 | 
			
		||||
          allocation.x1 = (int) content_box.x1;
 | 
			
		||||
          allocation.x2 = (int) content_box.x2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (priv->y_fill)
 | 
			
		||||
        {
 | 
			
		||||
          allocation.y1 = (int) content_box.y1;
 | 
			
		||||
          allocation.y2 = (int) content_box.y2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* if we are filling horizontally and vertically then we're done */
 | 
			
		||||
      if (priv->x_fill && priv->y_fill)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_actor_allocate (priv->child, &allocation, flags);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
 | 
			
		||||
      g_object_get (G_OBJECT (priv->child), "request-mode", &request, NULL);
 | 
			
		||||
 | 
			
		||||
      if (request == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_actor_get_preferred_width (priv->child, available_height,
 | 
			
		||||
                                             &min_width,
 | 
			
		||||
                                             &natural_width);
 | 
			
		||||
 | 
			
		||||
          child_width = CLAMP (natural_width, min_width, available_width);
 | 
			
		||||
 | 
			
		||||
          clutter_actor_get_preferred_height (priv->child, child_width,
 | 
			
		||||
                                              &min_height,
 | 
			
		||||
                                              &natural_height);
 | 
			
		||||
 | 
			
		||||
          child_height = CLAMP (natural_height, min_height, available_height);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          clutter_actor_get_preferred_height (priv->child, available_width,
 | 
			
		||||
                                              &min_height,
 | 
			
		||||
                                              &natural_height);
 | 
			
		||||
 | 
			
		||||
          child_height = CLAMP (natural_height, min_height, available_height);
 | 
			
		||||
 | 
			
		||||
          clutter_actor_get_preferred_width (priv->child, child_height,
 | 
			
		||||
                                             &min_width,
 | 
			
		||||
                                             &natural_width);
 | 
			
		||||
 | 
			
		||||
          child_width = CLAMP (natural_width, min_width, available_width);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (!priv->x_fill)
 | 
			
		||||
        {
 | 
			
		||||
          allocation.x1 = content_box.x1 + (int) ((available_width - child_width) * x_align);
 | 
			
		||||
          allocation.x2 = allocation.x1 + child_width;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (!priv->y_fill)
 | 
			
		||||
        {
 | 
			
		||||
          allocation.y1 = content_box.y1 + (int) ((available_height - child_height) * y_align);
 | 
			
		||||
          allocation.y2 = allocation.y1 + child_height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (priv->child, &allocation, flags);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                              gfloat   for_height,
 | 
			
		||||
                              gfloat  *min_width_p,
 | 
			
		||||
                              gfloat  *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (self)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_height (theme_node, &for_height);
 | 
			
		||||
 | 
			
		||||
  if (priv->child == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (min_width_p)
 | 
			
		||||
	*min_width_p = 0;
 | 
			
		||||
 | 
			
		||||
      if (natural_width_p)
 | 
			
		||||
        *natural_width_p = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->child, for_height,
 | 
			
		||||
                                         min_width_p,
 | 
			
		||||
                                         natural_width_p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                               gfloat   for_width,
 | 
			
		||||
                               gfloat  *min_height_p,
 | 
			
		||||
                               gfloat  *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (self)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_width (theme_node, &for_width);
 | 
			
		||||
 | 
			
		||||
  if (priv->child == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (min_height_p)
 | 
			
		||||
        *min_height_p = 0;
 | 
			
		||||
 | 
			
		||||
      if (natural_height_p)
 | 
			
		||||
        *natural_height_p = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->child, for_width,
 | 
			
		||||
                                          min_height_p,
 | 
			
		||||
                                          natural_height_p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_dispose (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_unparent (priv->child);
 | 
			
		||||
      priv->child = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_bin_parent_class)->dispose (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_set_property (GObject      *gobject,
 | 
			
		||||
                       guint         prop_id,
 | 
			
		||||
                       const GValue *value,
 | 
			
		||||
                       GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBin *bin = NBTK_BIN (gobject);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_CHILD:
 | 
			
		||||
      nbtk_bin_set_child (bin, g_value_get_object (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_X_ALIGN:
 | 
			
		||||
      nbtk_bin_set_alignment (bin,
 | 
			
		||||
                              g_value_get_enum (value),
 | 
			
		||||
                              bin->priv->y_align);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_Y_ALIGN:
 | 
			
		||||
      nbtk_bin_set_alignment (bin,
 | 
			
		||||
                              bin->priv->x_align,
 | 
			
		||||
                              g_value_get_enum (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_X_FILL:
 | 
			
		||||
      nbtk_bin_set_fill (bin,
 | 
			
		||||
                         g_value_get_boolean (value),
 | 
			
		||||
                         bin->priv->y_fill);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_Y_FILL:
 | 
			
		||||
      nbtk_bin_set_fill (bin,
 | 
			
		||||
                         bin->priv->y_fill,
 | 
			
		||||
                         g_value_get_boolean (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_get_property (GObject    *gobject,
 | 
			
		||||
                       guint       prop_id,
 | 
			
		||||
                       GValue     *value,
 | 
			
		||||
                       GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv = NBTK_BIN (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_CHILD:
 | 
			
		||||
      g_value_set_object (value, priv->child);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_X_FILL:
 | 
			
		||||
      g_value_set_boolean (value, priv->x_fill);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_Y_FILL:
 | 
			
		||||
      g_value_set_boolean (value, priv->y_fill);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_class_init (NbtkBinClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkBinPrivate));
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_bin_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_bin_get_property;
 | 
			
		||||
  gobject_class->dispose = nbtk_bin_dispose;
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width = nbtk_bin_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = nbtk_bin_get_preferred_height;
 | 
			
		||||
  actor_class->allocate = nbtk_bin_allocate;
 | 
			
		||||
  actor_class->paint = nbtk_bin_paint;
 | 
			
		||||
  actor_class->pick = nbtk_bin_pick;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkBin:child:
 | 
			
		||||
   *
 | 
			
		||||
   * The child #ClutterActor of the #NbtkBin container.
 | 
			
		||||
   */
 | 
			
		||||
  pspec = g_param_spec_object ("child",
 | 
			
		||||
                               "Child",
 | 
			
		||||
                               "The child of the Bin",
 | 
			
		||||
                               CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                               NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_CHILD, pspec);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkBin:x-align:
 | 
			
		||||
   *
 | 
			
		||||
   * The horizontal alignment of the #NbtkBin child.
 | 
			
		||||
   */
 | 
			
		||||
  pspec = g_param_spec_enum ("x-align",
 | 
			
		||||
                             "X Align",
 | 
			
		||||
                             "The horizontal alignment",
 | 
			
		||||
                             NBTK_TYPE_ALIGNMENT,
 | 
			
		||||
                             NBTK_ALIGN_CENTER,
 | 
			
		||||
                             NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_X_ALIGN, pspec);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkBin:y-align:
 | 
			
		||||
   *
 | 
			
		||||
   * The vertical alignment of the #NbtkBin child.
 | 
			
		||||
   */
 | 
			
		||||
  pspec = g_param_spec_enum ("y-align",
 | 
			
		||||
                             "Y Align",
 | 
			
		||||
                             "The vertical alignment",
 | 
			
		||||
                             NBTK_TYPE_ALIGNMENT,
 | 
			
		||||
                             NBTK_ALIGN_CENTER,
 | 
			
		||||
                             NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_Y_ALIGN, pspec);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkBin:x-fill:
 | 
			
		||||
   *
 | 
			
		||||
   * Whether the child should fill the horizontal allocation
 | 
			
		||||
   */
 | 
			
		||||
  pspec = g_param_spec_boolean ("x-fill",
 | 
			
		||||
                                "X Fill",
 | 
			
		||||
                                "Whether the child should fill the "
 | 
			
		||||
                                "horizontal allocation",
 | 
			
		||||
                                FALSE,
 | 
			
		||||
                                NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_X_FILL, pspec);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkBin:y-fill:
 | 
			
		||||
   *
 | 
			
		||||
   * Whether the child should fill the vertical allocation
 | 
			
		||||
   */
 | 
			
		||||
  pspec = g_param_spec_boolean ("y-fill",
 | 
			
		||||
                                "Y Fill",
 | 
			
		||||
                                "Whether the child should fill the "
 | 
			
		||||
                                "vertical allocation",
 | 
			
		||||
                                FALSE,
 | 
			
		||||
                                NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_Y_FILL, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_bin_init (NbtkBin *bin)
 | 
			
		||||
{
 | 
			
		||||
  bin->priv = NBTK_BIN_GET_PRIVATE (bin);
 | 
			
		||||
 | 
			
		||||
  bin->priv->x_align = NBTK_ALIGN_CENTER;
 | 
			
		||||
  bin->priv->y_align = NBTK_ALIGN_CENTER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new #NbtkBin, a simple container for one child.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly created #NbtkBin actor
 | 
			
		||||
 */
 | 
			
		||||
NbtkWidget *
 | 
			
		||||
nbtk_bin_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (NBTK_TYPE_BIN, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_set_child:
 | 
			
		||||
 * @bin: a #NbtkBin
 | 
			
		||||
 * @child: a #ClutterActor, or %NULL
 | 
			
		||||
 *
 | 
			
		||||
 * Sets @child as the child of @bin.
 | 
			
		||||
 *
 | 
			
		||||
 * If @bin already has a child, the previous child is removed.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_bin_set_child (NbtkBin *bin,
 | 
			
		||||
                    ClutterActor *child)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BIN (bin));
 | 
			
		||||
  g_return_if_fail (child == NULL || CLUTTER_IS_ACTOR (child));
 | 
			
		||||
 | 
			
		||||
  priv = bin->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->child == child)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActor *old_child = priv->child;
 | 
			
		||||
 | 
			
		||||
      g_object_ref (old_child);
 | 
			
		||||
 | 
			
		||||
      priv->child = NULL;
 | 
			
		||||
      clutter_actor_unparent (old_child);
 | 
			
		||||
 | 
			
		||||
      g_signal_emit_by_name (bin, "actor-removed", old_child);
 | 
			
		||||
 | 
			
		||||
      g_object_unref (old_child);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (child)
 | 
			
		||||
    {
 | 
			
		||||
      priv->child = child;
 | 
			
		||||
      clutter_actor_set_parent (child, CLUTTER_ACTOR (bin));
 | 
			
		||||
 | 
			
		||||
      g_signal_emit_by_name (bin, "actor-added", priv->child);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_relayout (CLUTTER_ACTOR (bin));
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (bin), "child");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_get_child:
 | 
			
		||||
 * @bin: a #NbtkBin
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves a pointer to the child of @bin.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): a #ClutterActor, or %NULL
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor *
 | 
			
		||||
nbtk_bin_get_child (NbtkBin *bin)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_BIN (bin), NULL);
 | 
			
		||||
 | 
			
		||||
  return bin->priv->child;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_set_alignment:
 | 
			
		||||
 * @bin: a #NbtkBin
 | 
			
		||||
 * @x_align: horizontal alignment
 | 
			
		||||
 * @y_align: vertical alignment
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the horizontal and vertical alignment of the child
 | 
			
		||||
 * inside a #NbtkBin.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_bin_set_alignment (NbtkBin       *bin,
 | 
			
		||||
                        NbtkAlignment  x_align,
 | 
			
		||||
                        NbtkAlignment  y_align)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv;
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BIN (bin));
 | 
			
		||||
 | 
			
		||||
  priv = bin->priv;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (G_OBJECT (bin));
 | 
			
		||||
 | 
			
		||||
  if (priv->x_align != x_align)
 | 
			
		||||
    {
 | 
			
		||||
      priv->x_align = x_align;
 | 
			
		||||
      g_object_notify (G_OBJECT (bin), "x-align");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->y_align != y_align)
 | 
			
		||||
    {
 | 
			
		||||
      priv->y_align = y_align;
 | 
			
		||||
      g_object_notify (G_OBJECT (bin), "y-align");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    clutter_actor_queue_relayout (CLUTTER_ACTOR (bin));
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (G_OBJECT (bin));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_get_alignment:
 | 
			
		||||
 * @bin: a #NbtkBin
 | 
			
		||||
 * @x_align: return location for the horizontal alignment, or %NULL
 | 
			
		||||
 * @y_align: return location for the vertical alignment, or %NULL
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the horizontal and vertical alignment of the child
 | 
			
		||||
 * inside a #NbtkBin, as set by nbtk_bin_set_alignment().
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_bin_get_alignment (NbtkBin       *bin,
 | 
			
		||||
                        NbtkAlignment *x_align,
 | 
			
		||||
                        NbtkAlignment *y_align)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BIN (bin));
 | 
			
		||||
 | 
			
		||||
  priv = bin->priv;
 | 
			
		||||
 | 
			
		||||
  if (x_align)
 | 
			
		||||
    *x_align = priv->x_align;
 | 
			
		||||
 | 
			
		||||
  if (y_align)
 | 
			
		||||
    *y_align = priv->y_align;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_set_fill:
 | 
			
		||||
 * @bin: a #NbtkBin
 | 
			
		||||
 * @x_fill: %TRUE if the child should fill horizontally the @bin
 | 
			
		||||
 * @y_fill: %TRUE if the child should fill vertically the @bin
 | 
			
		||||
 *
 | 
			
		||||
 * Sets whether the child of @bin should fill out the horizontal
 | 
			
		||||
 * and/or vertical allocation of the parent
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_bin_set_fill (NbtkBin  *bin,
 | 
			
		||||
                   gboolean  x_fill,
 | 
			
		||||
                   gboolean  y_fill)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinPrivate *priv;
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BIN (bin));
 | 
			
		||||
 | 
			
		||||
  priv = bin->priv;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (G_OBJECT (bin));
 | 
			
		||||
 | 
			
		||||
  if (priv->x_fill != x_fill)
 | 
			
		||||
    {
 | 
			
		||||
      priv->x_fill = x_fill;
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (bin), "x-fill");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->y_fill != y_fill)
 | 
			
		||||
    {
 | 
			
		||||
      priv->y_fill = y_fill;
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
 | 
			
		||||
      g_object_notify (G_OBJECT (bin), "y-fill");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    clutter_actor_queue_relayout (CLUTTER_ACTOR (bin));
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (G_OBJECT (bin));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_bin_get_fill:
 | 
			
		||||
 * @bin: a #NbtkBin
 | 
			
		||||
 * @x_fill: (out): return location for the horizontal fill, or %NULL
 | 
			
		||||
 * @y_fill: (out): return location for the vertical fill, or %NULL
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves the horizontal and vertical fill settings
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_bin_get_fill (NbtkBin  *bin,
 | 
			
		||||
                   gboolean *x_fill,
 | 
			
		||||
                   gboolean *y_fill)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BIN (bin));
 | 
			
		||||
 | 
			
		||||
  if (x_fill)
 | 
			
		||||
    *x_fill = bin->priv->x_fill;
 | 
			
		||||
 | 
			
		||||
  if (y_fill)
 | 
			
		||||
    *y_fill = bin->priv->y_fill;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								src/nbtk/nbtk-bin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/nbtk/nbtk-bin.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-bin.h: Basic container actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2008 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Emmanuele Bassi <ebassi@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_BIN_H__
 | 
			
		||||
#define __NBTK_BIN_H__
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-types.h>
 | 
			
		||||
#include <nbtk/nbtk-widget.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_BIN                   (nbtk_bin_get_type ())
 | 
			
		||||
#define NBTK_BIN(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_BIN, NbtkBin))
 | 
			
		||||
#define NBTK_IS_BIN(obj)                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_BIN))
 | 
			
		||||
#define NBTK_BIN_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_BIN, NbtkBinClass))
 | 
			
		||||
#define NBTK_IS_BIN_CLASS(klass)        (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_BIN))
 | 
			
		||||
#define NBTK_BIN_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_BIN, NbtkBinClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkBin                 NbtkBin;
 | 
			
		||||
typedef struct _NbtkBinPrivate          NbtkBinPrivate;
 | 
			
		||||
typedef struct _NbtkBinClass            NbtkBinClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkBin:
 | 
			
		||||
 *
 | 
			
		||||
 * The #NbtkBin struct contains only private data
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkBin
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkWidget parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkBinPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkBinClass:
 | 
			
		||||
 *
 | 
			
		||||
 * The #NbtkBinClass struct contains only private data
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkBinClass
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkWidgetClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_bin_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkWidget   *nbtk_bin_new           (void);
 | 
			
		||||
void          nbtk_bin_set_child     (NbtkBin           *bin,
 | 
			
		||||
                                      ClutterActor      *child);
 | 
			
		||||
ClutterActor *nbtk_bin_get_child     (NbtkBin           *bin);
 | 
			
		||||
void          nbtk_bin_set_alignment (NbtkBin           *bin,
 | 
			
		||||
                                      NbtkAlignment      x_align,
 | 
			
		||||
                                      NbtkAlignment      y_align);
 | 
			
		||||
void          nbtk_bin_get_alignment (NbtkBin           *bin,
 | 
			
		||||
                                      NbtkAlignment     *x_align,
 | 
			
		||||
                                      NbtkAlignment     *y_align);
 | 
			
		||||
void          nbtk_bin_set_fill      (NbtkBin           *bin,
 | 
			
		||||
                                      gboolean           x_fill,
 | 
			
		||||
                                      gboolean           y_fill);
 | 
			
		||||
void          nbtk_bin_get_fill      (NbtkBin           *bin,
 | 
			
		||||
                                      gboolean          *x_fill,
 | 
			
		||||
                                      gboolean          *y_fill);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_BIN_H__ */
 | 
			
		||||
							
								
								
									
										176
									
								
								src/nbtk/nbtk-box-layout-child.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								src/nbtk/nbtk-box-layout-child.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-box-layout-child.c: box layout child actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas.wood@intel.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "nbtk-box-layout-child.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkBoxLayoutChild, nbtk_box_layout_child, CLUTTER_TYPE_CHILD_META)
 | 
			
		||||
 | 
			
		||||
#define BOX_LAYOUT_CHILD_PRIVATE(o) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_BOX_LAYOUT_CHILD, NbtkBoxLayoutChildPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_EXPAND,
 | 
			
		||||
  PROP_X_FILL,
 | 
			
		||||
  PROP_Y_FILL,
 | 
			
		||||
  PROP_X_ALIGN,
 | 
			
		||||
  PROP_Y_ALIGN
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_box_layout_child_get_property (GObject *object, guint property_id,
 | 
			
		||||
                                    GValue *value, GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBoxLayoutChild *child = NBTK_BOX_LAYOUT_CHILD (object);
 | 
			
		||||
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_EXPAND:
 | 
			
		||||
      g_value_set_boolean (value, child->expand);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_X_FILL:
 | 
			
		||||
      g_value_set_boolean (value, child->x_fill);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_Y_FILL:
 | 
			
		||||
      g_value_set_boolean (value, child->y_fill);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_X_ALIGN:
 | 
			
		||||
      g_value_set_enum (value, child->x_align);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_Y_ALIGN:
 | 
			
		||||
      g_value_set_enum (value, child->y_align);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_box_layout_child_set_property (GObject *object, guint property_id,
 | 
			
		||||
                                    const GValue *value, GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkBoxLayoutChild *child = NBTK_BOX_LAYOUT_CHILD (object);
 | 
			
		||||
  NbtkBoxLayout *box = NBTK_BOX_LAYOUT (CLUTTER_CHILD_META (object)->container);
 | 
			
		||||
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_EXPAND:
 | 
			
		||||
      child->expand = g_value_get_boolean (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_X_FILL:
 | 
			
		||||
      child->x_fill = g_value_get_boolean (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_Y_FILL:
 | 
			
		||||
      child->y_fill = g_value_get_boolean (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_X_ALIGN:
 | 
			
		||||
      child->x_align = g_value_get_enum (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_Y_ALIGN:
 | 
			
		||||
      child->y_align = g_value_get_enum (value);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_relayout ((ClutterActor*) box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_box_layout_child_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_box_layout_child_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_box_layout_child_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_box_layout_child_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_box_layout_child_class_init (NbtkBoxLayoutChildClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = nbtk_box_layout_child_get_property;
 | 
			
		||||
  object_class->set_property = nbtk_box_layout_child_set_property;
 | 
			
		||||
  object_class->dispose = nbtk_box_layout_child_dispose;
 | 
			
		||||
  object_class->finalize = nbtk_box_layout_child_finalize;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("expand", "Expand",
 | 
			
		||||
                                "Allocate the child extra space",
 | 
			
		||||
                                FALSE,
 | 
			
		||||
                                NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (object_class, PROP_EXPAND, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("x-fill", "x-fill",
 | 
			
		||||
                                "Whether the child should receive priority "
 | 
			
		||||
                                "when the container is allocating spare space "
 | 
			
		||||
                                "on the horizontal axis",
 | 
			
		||||
                                TRUE,
 | 
			
		||||
                                NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (object_class, PROP_X_FILL, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("y-fill", "y-fill",
 | 
			
		||||
                                "Whether the child should receive priority "
 | 
			
		||||
                                "when the container is allocating spare space "
 | 
			
		||||
                                "on the vertical axis",
 | 
			
		||||
                                TRUE,
 | 
			
		||||
                                NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (object_class, PROP_Y_FILL, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_enum ("x-align",
 | 
			
		||||
                             "X Alignment",
 | 
			
		||||
                             "X alignment of the widget within the cell",
 | 
			
		||||
                             NBTK_TYPE_ALIGN,
 | 
			
		||||
                             NBTK_ALIGN_MIDDLE,
 | 
			
		||||
                             NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (object_class, PROP_X_ALIGN, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_enum ("y-align",
 | 
			
		||||
                             "Y Alignment",
 | 
			
		||||
                             "Y alignment of the widget within the cell",
 | 
			
		||||
                             NBTK_TYPE_ALIGN,
 | 
			
		||||
                             NBTK_ALIGN_MIDDLE,
 | 
			
		||||
                             NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (object_class, PROP_Y_ALIGN, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_box_layout_child_init (NbtkBoxLayoutChild *self)
 | 
			
		||||
{
 | 
			
		||||
  self->expand = FALSE;
 | 
			
		||||
 | 
			
		||||
  self->x_fill = TRUE;
 | 
			
		||||
  self->y_fill = TRUE;
 | 
			
		||||
 | 
			
		||||
  self->x_align = NBTK_ALIGN_CENTER;
 | 
			
		||||
  self->y_align = NBTK_ALIGN_CENTER;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								src/nbtk/nbtk-box-layout-child.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/nbtk/nbtk-box-layout-child.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-box-layout-child.h: box layout child actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas.wood@intel.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _NBTK_BOX_LAYOUT_CHILD_H
 | 
			
		||||
#define _NBTK_BOX_LAYOUT_CHILD_H
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include "nbtk-enum-types.h"
 | 
			
		||||
#include "nbtk-box-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_BOX_LAYOUT_CHILD nbtk_box_layout_child_get_type()
 | 
			
		||||
 | 
			
		||||
#define NBTK_BOX_LAYOUT_CHILD(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT_CHILD, NbtkBoxLayoutChild))
 | 
			
		||||
 | 
			
		||||
#define NBTK_BOX_LAYOUT_CHILD_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_CAST ((klass), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT_CHILD, NbtkBoxLayoutChildClass))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_BOX_LAYOUT_CHILD(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT_CHILD))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_BOX_LAYOUT_CHILD_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT_CHILD))
 | 
			
		||||
 | 
			
		||||
#define NBTK_BOX_LAYOUT_CHILD_GET_CLASS(obj) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT_CHILD, NbtkBoxLayoutChildClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkBoxLayoutChild NbtkBoxLayoutChild;
 | 
			
		||||
typedef struct _NbtkBoxLayoutChildClass NbtkBoxLayoutChildClass;
 | 
			
		||||
typedef struct _NbtkBoxLayoutChildPrivate NbtkBoxLayoutChildPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkBoxLayoutChild:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkBoxLayoutChild
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterChildMeta parent;
 | 
			
		||||
 | 
			
		||||
  gboolean expand;
 | 
			
		||||
  gboolean x_fill : 1;
 | 
			
		||||
  gboolean y_fill : 1;
 | 
			
		||||
  NbtkAlign x_align;
 | 
			
		||||
  NbtkAlign y_align;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkBoxLayoutChildClass
 | 
			
		||||
{
 | 
			
		||||
  ClutterChildMetaClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_box_layout_child_get_type (void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* _NBTK_BOX_LAYOUT_CHILD_H */
 | 
			
		||||
							
								
								
									
										1252
									
								
								src/nbtk/nbtk-box-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1252
									
								
								src/nbtk/nbtk-box-layout.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										91
									
								
								src/nbtk/nbtk-box-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/nbtk/nbtk-box-layout.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-box-layout.h: box layout actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas.wood@intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef _NBTK_BOX_LAYOUT_H
 | 
			
		||||
#define _NBTK_BOX_LAYOUT_H
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-widget.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_BOX_LAYOUT nbtk_box_layout_get_type()
 | 
			
		||||
 | 
			
		||||
#define NBTK_BOX_LAYOUT(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT, NbtkBoxLayout))
 | 
			
		||||
 | 
			
		||||
#define NBTK_BOX_LAYOUT_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_CAST ((klass), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT, NbtkBoxLayoutClass))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_BOX_LAYOUT(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_BOX_LAYOUT_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT))
 | 
			
		||||
 | 
			
		||||
#define NBTK_BOX_LAYOUT_GET_CLASS(obj) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
 | 
			
		||||
  NBTK_TYPE_BOX_LAYOUT, NbtkBoxLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkBoxLayout NbtkBoxLayout;
 | 
			
		||||
typedef struct _NbtkBoxLayoutClass NbtkBoxLayoutClass;
 | 
			
		||||
typedef struct _NbtkBoxLayoutPrivate NbtkBoxLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkBoxLayout:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkBoxLayout
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkWidget parent;
 | 
			
		||||
 | 
			
		||||
  NbtkBoxLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkBoxLayoutClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkWidgetClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_box_layout_get_type (void);
 | 
			
		||||
 | 
			
		||||
NbtkWidget *nbtk_box_layout_new (void);
 | 
			
		||||
 | 
			
		||||
void nbtk_box_layout_set_vertical (NbtkBoxLayout *box, gboolean vertical);
 | 
			
		||||
gboolean nbtk_box_layout_get_vertical (NbtkBoxLayout *box);
 | 
			
		||||
 | 
			
		||||
void nbtk_box_layout_set_pack_start (NbtkBoxLayout *box, gboolean pack_start);
 | 
			
		||||
gboolean nbtk_box_layout_get_pack_start (NbtkBoxLayout *box);
 | 
			
		||||
 | 
			
		||||
void nbtk_box_layout_set_spacing (NbtkBoxLayout *box, guint spacing);
 | 
			
		||||
guint nbtk_box_layout_get_spacing (NbtkBoxLayout *box);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* _NBTK_BOX_LAYOUT_H */
 | 
			
		||||
							
								
								
									
										690
									
								
								src/nbtk/nbtk-button.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										690
									
								
								src/nbtk/nbtk-button.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,690 @@
 | 
			
		||||
/*-button.c: Plain button actor
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright , 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Emmanuele Bassi <ebassi@openedhand.com>
 | 
			
		||||
 *             Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-button
 | 
			
		||||
 * @short_description: Button widget
 | 
			
		||||
 *
 | 
			
		||||
 * A button widget with support for either a text label or icon, toggle mode
 | 
			
		||||
 * and transitions effects between states.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-button.h"
 | 
			
		||||
 | 
			
		||||
#include "nbtk-marshal.h"
 | 
			
		||||
#include "nbtk-texture-frame.h"
 | 
			
		||||
#include "nbtk-texture-cache.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_LABEL,
 | 
			
		||||
  PROP_TOGGLE,
 | 
			
		||||
  PROP_ACTIVE,
 | 
			
		||||
  PROP_TRANSITION
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CLICKED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define NBTK_BUTTON_GET_PRIVATE(obj)    \
 | 
			
		||||
        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_BUTTON, NbtkButtonPrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkButtonPrivate
 | 
			
		||||
{
 | 
			
		||||
  gchar *text;
 | 
			
		||||
 | 
			
		||||
  ClutterActor *old_bg;
 | 
			
		||||
  gboolean old_bg_parented; /* TRUE if we have adopted old_bg */
 | 
			
		||||
 | 
			
		||||
  guint8 old_opacity;
 | 
			
		||||
 | 
			
		||||
  guint is_pressed : 1;
 | 
			
		||||
  guint is_hover : 1;
 | 
			
		||||
  guint is_checked : 1;
 | 
			
		||||
  guint is_toggle : 1;
 | 
			
		||||
 | 
			
		||||
  gint transition_duration;
 | 
			
		||||
 | 
			
		||||
  ClutterAnimation *animation;
 | 
			
		||||
 | 
			
		||||
  gint spacing;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint button_signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkButton, nbtk_button, NBTK_TYPE_BIN);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_update_label_style (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *label;
 | 
			
		||||
  ShellThemeNode *theme_node;
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  const PangoFontDescription *font;
 | 
			
		||||
  gchar *font_string = NULL;
 | 
			
		||||
 | 
			
		||||
  label = nbtk_bin_get_child ((NbtkBin*) button);
 | 
			
		||||
 | 
			
		||||
  /* check the child is really a label */
 | 
			
		||||
  if (!CLUTTER_IS_TEXT (label))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (button));
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_foreground_color (theme_node, &color);
 | 
			
		||||
  clutter_text_set_color (CLUTTER_TEXT (label), &color);
 | 
			
		||||
 | 
			
		||||
  font = shell_theme_node_get_font (theme_node);
 | 
			
		||||
  font_string = pango_font_description_to_string (font);
 | 
			
		||||
  clutter_text_set_font_name (CLUTTER_TEXT (label), font_string);
 | 
			
		||||
  g_free (font_string);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_dispose_old_bg (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv = button->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->old_bg)
 | 
			
		||||
    {
 | 
			
		||||
      if (priv->old_bg_parented)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_actor_unparent (priv->old_bg);
 | 
			
		||||
          priv->old_bg_parented = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      g_object_unref (priv->old_bg);
 | 
			
		||||
      priv->old_bg = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_animation_completed (ClutterAnimation  *animation,
 | 
			
		||||
                          NbtkButton        *button)
 | 
			
		||||
{
 | 
			
		||||
  nbtk_button_dispose_old_bg (button);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_style_changed (NbtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButton *button = NBTK_BUTTON (widget);
 | 
			
		||||
  NbtkButtonPrivate *priv = button->priv;
 | 
			
		||||
  NbtkButtonClass *button_class = NBTK_BUTTON_GET_CLASS (button);
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (button));
 | 
			
		||||
  ClutterActor *bg_image;
 | 
			
		||||
  double spacing;
 | 
			
		||||
 | 
			
		||||
  nbtk_button_dispose_old_bg (button);
 | 
			
		||||
 | 
			
		||||
  bg_image = nbtk_widget_get_border_image ((NbtkWidget*) button);
 | 
			
		||||
  if (bg_image)
 | 
			
		||||
    button->priv->old_bg = g_object_ref (bg_image);
 | 
			
		||||
 | 
			
		||||
  NBTK_WIDGET_CLASS (nbtk_button_parent_class)->style_changed (widget);
 | 
			
		||||
 | 
			
		||||
  spacing = 6;
 | 
			
		||||
  shell_theme_node_get_length (theme_node, "border-spacing", FALSE, &spacing);
 | 
			
		||||
  priv->spacing = round (spacing);
 | 
			
		||||
 | 
			
		||||
  /* update the label styling */
 | 
			
		||||
  nbtk_button_update_label_style (button);
 | 
			
		||||
 | 
			
		||||
  /* run a transition if applicable */
 | 
			
		||||
  if (button_class->transition)
 | 
			
		||||
    {
 | 
			
		||||
      button_class->transition (button, priv->old_bg);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (priv->old_bg &&
 | 
			
		||||
          (!nbtk_widget_get_style_pseudo_class (widget)))
 | 
			
		||||
        {
 | 
			
		||||
          ClutterAnimation *animation;
 | 
			
		||||
          if (!clutter_actor_get_parent (priv->old_bg))
 | 
			
		||||
            {
 | 
			
		||||
              clutter_actor_set_parent (priv->old_bg, (ClutterActor*) widget);
 | 
			
		||||
              priv->old_bg_parented = TRUE;
 | 
			
		||||
            }
 | 
			
		||||
          if (priv->transition_duration > 0)
 | 
			
		||||
            {
 | 
			
		||||
              animation = clutter_actor_animate (priv->old_bg,
 | 
			
		||||
                                                 CLUTTER_LINEAR,
 | 
			
		||||
                                                 priv->transition_duration,
 | 
			
		||||
                                                 "opacity", 0,
 | 
			
		||||
                                                 NULL);
 | 
			
		||||
              g_signal_connect (animation, "completed",
 | 
			
		||||
                                G_CALLBACK (nbtk_animation_completed), button);
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              nbtk_button_dispose_old_bg (button);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_real_pressed (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "active");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_real_released (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv = button->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->is_checked)
 | 
			
		||||
    nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "checked");
 | 
			
		||||
  else if (!priv->is_hover)
 | 
			
		||||
    nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, NULL);
 | 
			
		||||
  else
 | 
			
		||||
    nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "hover");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_button_button_press (ClutterActor       *actor,
 | 
			
		||||
                          ClutterButtonEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  nbtk_widget_hide_tooltip (NBTK_WIDGET (actor));
 | 
			
		||||
 | 
			
		||||
  if (event->button == 1)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkButton *button = NBTK_BUTTON (actor);
 | 
			
		||||
      NbtkButtonClass *klass = NBTK_BUTTON_GET_CLASS (button);
 | 
			
		||||
 | 
			
		||||
      button->priv->is_pressed = TRUE;
 | 
			
		||||
 | 
			
		||||
      clutter_grab_pointer (actor);
 | 
			
		||||
 | 
			
		||||
      if (klass->pressed)
 | 
			
		||||
        klass->pressed (button);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_button_button_release (ClutterActor       *actor,
 | 
			
		||||
                            ClutterButtonEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  if (event->button == 1)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkButton *button = NBTK_BUTTON (actor);
 | 
			
		||||
      NbtkButtonClass *klass = NBTK_BUTTON_GET_CLASS (button);
 | 
			
		||||
 | 
			
		||||
      if (!button->priv->is_pressed)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      clutter_ungrab_pointer ();
 | 
			
		||||
 | 
			
		||||
      if (button->priv->is_toggle)
 | 
			
		||||
        {
 | 
			
		||||
          nbtk_button_set_checked (button, !button->priv->is_checked);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      button->priv->is_pressed = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (klass->released)
 | 
			
		||||
        klass->released (button);
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (button, button_signals[CLICKED], 0);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_button_enter (ClutterActor         *actor,
 | 
			
		||||
                   ClutterCrossingEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButton *button = NBTK_BUTTON (actor);
 | 
			
		||||
 | 
			
		||||
  if (!button->priv->is_checked)
 | 
			
		||||
    nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "hover");
 | 
			
		||||
 | 
			
		||||
  button->priv->is_hover = 1;
 | 
			
		||||
 | 
			
		||||
  return CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->enter_event (actor, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_button_leave (ClutterActor         *actor,
 | 
			
		||||
                   ClutterCrossingEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButton *button = NBTK_BUTTON (actor);
 | 
			
		||||
 | 
			
		||||
  button->priv->is_hover = 0;
 | 
			
		||||
 | 
			
		||||
  if (button->priv->is_pressed)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkButtonClass *klass = NBTK_BUTTON_GET_CLASS (button);
 | 
			
		||||
 | 
			
		||||
      clutter_ungrab_pointer ();
 | 
			
		||||
 | 
			
		||||
      button->priv->is_pressed = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (klass->released)
 | 
			
		||||
        klass->released (button);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (button->priv->is_checked)
 | 
			
		||||
    nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "checked");
 | 
			
		||||
  else
 | 
			
		||||
    nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, NULL);
 | 
			
		||||
 | 
			
		||||
  return CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->leave_event (actor, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_set_property (GObject      *gobject,
 | 
			
		||||
                          guint         prop_id,
 | 
			
		||||
                          const GValue *value,
 | 
			
		||||
                          GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButton *button = NBTK_BUTTON (gobject);
 | 
			
		||||
  NbtkButtonPrivate *priv = NBTK_BUTTON (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
      nbtk_button_set_label (button, g_value_get_string (value));
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_TOGGLE:
 | 
			
		||||
      nbtk_button_set_toggle_mode (button, g_value_get_boolean (value));
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_ACTIVE:
 | 
			
		||||
      nbtk_button_set_checked (button, g_value_get_boolean (value));
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_TRANSITION:
 | 
			
		||||
      priv->transition_duration = g_value_get_int (value);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_get_property (GObject    *gobject,
 | 
			
		||||
                          guint       prop_id,
 | 
			
		||||
                          GValue     *value,
 | 
			
		||||
                          GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv = NBTK_BUTTON (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
      g_value_set_string (value, priv->text);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_TOGGLE:
 | 
			
		||||
      g_value_set_boolean (value, priv->is_toggle);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_ACTIVE:
 | 
			
		||||
      g_value_set_boolean (value, priv->is_checked);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_TRANSITION:
 | 
			
		||||
      g_value_set_int (value, priv->transition_duration);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_finalize (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv = NBTK_BUTTON (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->text);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_button_parent_class)->finalize (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_dispose (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  nbtk_button_dispose_old_bg (NBTK_BUTTON (gobject));
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_button_parent_class)->dispose (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_map (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv = NBTK_BUTTON (self)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->map (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->old_bg && priv->old_bg_parented)
 | 
			
		||||
    clutter_actor_map (priv->old_bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_unmap (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv = NBTK_BUTTON (self)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_button_parent_class)->unmap (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->old_bg && priv->old_bg_parented)
 | 
			
		||||
    clutter_actor_unmap (priv->old_bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_draw_background (NbtkWidget         *widget)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  NBTK_WIDGET_CLASS (nbtk_button_parent_class)->draw_background (widget);
 | 
			
		||||
 | 
			
		||||
  priv = NBTK_BUTTON (widget)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->old_bg && priv->old_bg_parented)
 | 
			
		||||
      clutter_actor_paint (priv->old_bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_class_init (NbtkButtonClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkButtonPrivate));
 | 
			
		||||
 | 
			
		||||
  klass->pressed = nbtk_button_real_pressed;
 | 
			
		||||
  klass->released = nbtk_button_real_released;
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_button_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_button_get_property;
 | 
			
		||||
  gobject_class->dispose = nbtk_button_dispose;
 | 
			
		||||
  gobject_class->finalize = nbtk_button_finalize;
 | 
			
		||||
 | 
			
		||||
  actor_class->button_press_event = nbtk_button_button_press;
 | 
			
		||||
  actor_class->button_release_event = nbtk_button_button_release;
 | 
			
		||||
  actor_class->enter_event = nbtk_button_enter;
 | 
			
		||||
  actor_class->leave_event = nbtk_button_leave;
 | 
			
		||||
 | 
			
		||||
  actor_class->map = nbtk_button_map;
 | 
			
		||||
  actor_class->unmap = nbtk_button_unmap;
 | 
			
		||||
 | 
			
		||||
  widget_class->draw_background = nbtk_button_draw_background;
 | 
			
		||||
  widget_class->style_changed = nbtk_button_style_changed;
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_string ("label",
 | 
			
		||||
                               "Label",
 | 
			
		||||
                               "Label of the button",
 | 
			
		||||
                               NULL, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("toggle-mode",
 | 
			
		||||
                                "Toggle Mode",
 | 
			
		||||
                                "Enable or disable toggling",
 | 
			
		||||
                                FALSE, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TOGGLE, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("checked",
 | 
			
		||||
                                "Checked",
 | 
			
		||||
                                "Indicates if a toggle button is \"on\""
 | 
			
		||||
                                " or \"off\"",
 | 
			
		||||
                                FALSE, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_ACTIVE, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_int ("transition-duration",
 | 
			
		||||
                            "Transition Duration",
 | 
			
		||||
                            "Duration of the state transition effect",
 | 
			
		||||
                            0, G_MAXINT, 120, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TRANSITION, pspec);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkButton::clicked:
 | 
			
		||||
   * @button: the object that received the signal
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the user activates the button, either with a mouse press and
 | 
			
		||||
   * release or with the keyboard.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  button_signals[CLICKED] =
 | 
			
		||||
    g_signal_new ("clicked",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (NbtkButtonClass, clicked),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _nbtk_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_button_init (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  button->priv = NBTK_BUTTON_GET_PRIVATE (button);
 | 
			
		||||
  button->priv->transition_duration = 120;
 | 
			
		||||
  button->priv->spacing = 6;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_reactive ((ClutterActor *) button, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new button
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new #NbtkButton
 | 
			
		||||
 */
 | 
			
		||||
NbtkWidget *
 | 
			
		||||
nbtk_button_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (NBTK_TYPE_BUTTON, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_new_with_label:
 | 
			
		||||
 * @text: text to set the label to
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #NbtkButton with the specified label
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new #NbtkButton
 | 
			
		||||
 */
 | 
			
		||||
NbtkWidget *
 | 
			
		||||
nbtk_button_new_with_label (const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (NBTK_TYPE_BUTTON, "label", text, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_get_label:
 | 
			
		||||
 * @button: a #NbtkButton
 | 
			
		||||
 *
 | 
			
		||||
 * Get the text displayed on the button
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the text for the button. This must not be freed by the application
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
nbtk_button_get_label (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_BUTTON (button), NULL);
 | 
			
		||||
 | 
			
		||||
  return button->priv->text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_set_label:
 | 
			
		||||
 * @button: a #Nbtkbutton
 | 
			
		||||
 * @text: text to set the label to
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the text displayed on the button
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_button_set_label (NbtkButton  *button,
 | 
			
		||||
                       const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkButtonPrivate *priv;
 | 
			
		||||
  ClutterActor *label;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BUTTON (button));
 | 
			
		||||
 | 
			
		||||
  priv = button->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->text);
 | 
			
		||||
 | 
			
		||||
  if (text)
 | 
			
		||||
    priv->text = g_strdup (text);
 | 
			
		||||
  else
 | 
			
		||||
    priv->text = g_strdup ("");
 | 
			
		||||
 | 
			
		||||
  label = nbtk_bin_get_child ((NbtkBin*) button);
 | 
			
		||||
 | 
			
		||||
  if (label && CLUTTER_IS_TEXT (label))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_text_set_text (CLUTTER_TEXT (label), priv->text);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      label = g_object_new (CLUTTER_TYPE_TEXT,
 | 
			
		||||
                            "text", priv->text,
 | 
			
		||||
                            "line-alignment", PANGO_ALIGN_CENTER,
 | 
			
		||||
                            "ellipsize", PANGO_ELLIPSIZE_END,
 | 
			
		||||
                            "use-markup", TRUE,
 | 
			
		||||
                            NULL);
 | 
			
		||||
      nbtk_bin_set_child ((NbtkBin*) button, label);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Fake a style change so that we reset the style properties on the label */
 | 
			
		||||
  nbtk_widget_style_changed (NBTK_WIDGET (button));
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (button), "label");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_get_toggle_mode:
 | 
			
		||||
 * @button: a #NbtkButton
 | 
			
		||||
 *
 | 
			
		||||
 * Get the toggle mode status of the button.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: #TRUE if toggle mode is set, otherwise #FALSE
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
nbtk_button_get_toggle_mode (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_BUTTON (button), FALSE);
 | 
			
		||||
 | 
			
		||||
  return button->priv->is_toggle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_set_toggle_mode:
 | 
			
		||||
 * @button: a #Nbtkbutton
 | 
			
		||||
 * @toggle: #TRUE or #FALSE
 | 
			
		||||
 *
 | 
			
		||||
 * Enables or disables toggle mode for the button. In toggle mode, the active
 | 
			
		||||
 * state will be "toggled" when the user clicks the button.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_button_set_toggle_mode (NbtkButton  *button,
 | 
			
		||||
                             gboolean     toggle)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BUTTON (button));
 | 
			
		||||
 | 
			
		||||
  button->priv->is_toggle = toggle;
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (button), "toggle-mode");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_get_checked:
 | 
			
		||||
 * @button: a #NbtkButton
 | 
			
		||||
 *
 | 
			
		||||
 * Get the state of the button that is in toggle mode.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: #TRUE if the button is checked, or #FALSE if not
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
nbtk_button_get_checked (NbtkButton *button)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_BUTTON (button), FALSE);
 | 
			
		||||
 | 
			
		||||
  return button->priv->is_checked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_button_set_checked:
 | 
			
		||||
 * @button: a #Nbtkbutton
 | 
			
		||||
 * @checked: #TRUE or #FALSE
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the pressed state of the button. This is only really useful if the
 | 
			
		||||
 * button has #toggle-mode mode set to #TRUE.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_button_set_checked (NbtkButton  *button,
 | 
			
		||||
                         gboolean     checked)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (NBTK_IS_BUTTON (button));
 | 
			
		||||
 | 
			
		||||
  if (button->priv->is_checked != checked)
 | 
			
		||||
    {
 | 
			
		||||
      button->priv->is_checked = checked;
 | 
			
		||||
 | 
			
		||||
      if (checked)
 | 
			
		||||
        nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "checked");
 | 
			
		||||
      else
 | 
			
		||||
        if (button->priv->is_hover)
 | 
			
		||||
          nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, "hover");
 | 
			
		||||
        else
 | 
			
		||||
          nbtk_widget_set_style_pseudo_class ((NbtkWidget*) button, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (button), "checked");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								src/nbtk/nbtk-button.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/nbtk/nbtk-button.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-button.h: Plain button actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Emmanuele Bassi <ebassi@openedhand.com>
 | 
			
		||||
 *             Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_BUTTON_H__
 | 
			
		||||
#define __NBTK_BUTTON_H__
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-bin.h>
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_BUTTON                (nbtk_button_get_type ())
 | 
			
		||||
#define NBTK_BUTTON(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_BUTTON, NbtkButton))
 | 
			
		||||
#define NBTK_IS_BUTTON(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_BUTTON))
 | 
			
		||||
#define NBTK_BUTTON_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_BUTTON, NbtkButtonClass))
 | 
			
		||||
#define NBTK_IS_BUTTON_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_BUTTON))
 | 
			
		||||
#define NBTK_BUTTON_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_BUTTON, NbtkButtonClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkButton              NbtkButton;
 | 
			
		||||
typedef struct _NbtkButtonPrivate       NbtkButtonPrivate;
 | 
			
		||||
typedef struct _NbtkButtonClass         NbtkButtonClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkButton:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure is private and should only be accessed using
 | 
			
		||||
 * the provided API.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct _NbtkButton
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkBin parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkButtonPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkButtonClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* vfuncs, not signals */
 | 
			
		||||
  void (* pressed)  (NbtkButton *button);
 | 
			
		||||
  void (* released) (NbtkButton *button);
 | 
			
		||||
  void (* transition) (NbtkButton *button, ClutterActor *old_bg);
 | 
			
		||||
 | 
			
		||||
  /* signals */
 | 
			
		||||
  void (* clicked) (NbtkButton *button);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_button_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkWidget *          nbtk_button_new            (void);
 | 
			
		||||
NbtkWidget *          nbtk_button_new_with_label (const gchar  *text);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_button_get_label      (NbtkButton   *button);
 | 
			
		||||
void                  nbtk_button_set_label      (NbtkButton   *button,
 | 
			
		||||
                                                  const gchar  *text);
 | 
			
		||||
void                  nbtk_button_set_toggle_mode    (NbtkButton *button, gboolean toggle);
 | 
			
		||||
gboolean              nbtk_button_get_toggle_mode    (NbtkButton *button);
 | 
			
		||||
void                  nbtk_button_set_checked        (NbtkButton *button, gboolean checked);
 | 
			
		||||
gboolean              nbtk_button_get_checked        (NbtkButton *button);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_BUTTON_H__ */
 | 
			
		||||
							
								
								
									
										367
									
								
								src/nbtk/nbtk-clipboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/nbtk/nbtk-clipboard.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,367 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-clipboard.c: clipboard object
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas.wood@intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "nbtk-clipboard.h"
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <clutter/x11/clutter-x11.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkClipboard, nbtk_clipboard, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
#define CLIPBOARD_PRIVATE(o) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_CLIPBOARD, NbtkClipboardPrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkClipboardPrivate
 | 
			
		||||
{
 | 
			
		||||
  Window clipboard_window;
 | 
			
		||||
  gchar *clipboard_text;
 | 
			
		||||
 | 
			
		||||
  Atom *supported_targets;
 | 
			
		||||
  gint n_targets;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EventFilterData EventFilterData;
 | 
			
		||||
struct _EventFilterData
 | 
			
		||||
{
 | 
			
		||||
  NbtkClipboard *clipboard;
 | 
			
		||||
  NbtkClipboardCallbackFunc callback;
 | 
			
		||||
  gpointer user_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static Atom __atom_clip = None;
 | 
			
		||||
static Atom __utf8_string = None;
 | 
			
		||||
static Atom __atom_targets = None;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_clipboard_get_property (GObject *object, guint property_id,
 | 
			
		||||
                              GValue *value, GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
    {
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_clipboard_set_property (GObject *object, guint property_id,
 | 
			
		||||
                              const GValue *value, GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
    {
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_clipboard_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_clipboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_clipboard_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  NbtkClipboardPrivate *priv = ((NbtkClipboard *) object)->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->clipboard_text);
 | 
			
		||||
  priv->clipboard_text = NULL;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->supported_targets);
 | 
			
		||||
  priv->supported_targets = NULL;
 | 
			
		||||
  priv->n_targets = 0;
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_clipboard_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterX11FilterReturn
 | 
			
		||||
nbtk_clipboard_provider (XEvent        *xev,
 | 
			
		||||
                         ClutterEvent  *cev,
 | 
			
		||||
                         NbtkClipboard *clipboard)
 | 
			
		||||
{
 | 
			
		||||
  XSelectionEvent notify_event;
 | 
			
		||||
  XSelectionRequestEvent *req_event;
 | 
			
		||||
 | 
			
		||||
  if (xev->type != SelectionRequest)
 | 
			
		||||
    return CLUTTER_X11_FILTER_CONTINUE;
 | 
			
		||||
 | 
			
		||||
  req_event = &xev->xselectionrequest;
 | 
			
		||||
 | 
			
		||||
  clutter_x11_trap_x_errors ();
 | 
			
		||||
 | 
			
		||||
  if (req_event->target == __atom_targets)
 | 
			
		||||
    {
 | 
			
		||||
      XChangeProperty (req_event->display,
 | 
			
		||||
                       req_event->requestor,
 | 
			
		||||
                       req_event->property,
 | 
			
		||||
                       XA_ATOM,
 | 
			
		||||
                       32,
 | 
			
		||||
                       PropModeReplace,
 | 
			
		||||
                       (guchar*) clipboard->priv->supported_targets,
 | 
			
		||||
                       clipboard->priv->n_targets);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      XChangeProperty (req_event->display,
 | 
			
		||||
                       req_event->requestor,
 | 
			
		||||
                       req_event->property,
 | 
			
		||||
                       req_event->target,
 | 
			
		||||
                       8,
 | 
			
		||||
                       PropModeReplace,
 | 
			
		||||
                       (guchar*) clipboard->priv->clipboard_text,
 | 
			
		||||
                       strlen (clipboard->priv->clipboard_text));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  notify_event.type = SelectionNotify;
 | 
			
		||||
  notify_event.display = req_event->display;
 | 
			
		||||
  notify_event.requestor = req_event->requestor;
 | 
			
		||||
  notify_event.selection = req_event->selection;
 | 
			
		||||
  notify_event.target = req_event->target;
 | 
			
		||||
  notify_event.time = req_event->time;
 | 
			
		||||
 | 
			
		||||
  if (req_event->property == None)
 | 
			
		||||
    notify_event.property = req_event->target;
 | 
			
		||||
  else
 | 
			
		||||
    notify_event.property = req_event->property;
 | 
			
		||||
 | 
			
		||||
  /* notify the requestor that they have a copy of the selection */
 | 
			
		||||
  XSendEvent (req_event->display, req_event->requestor, False, 0,
 | 
			
		||||
              (XEvent *) ¬ify_event);
 | 
			
		||||
  /* Make it happen non async */
 | 
			
		||||
  XSync (clutter_x11_get_default_display(), FALSE);
 | 
			
		||||
 | 
			
		||||
  clutter_x11_untrap_x_errors (); /* FIXME: Warn here on fail ? */
 | 
			
		||||
 | 
			
		||||
  return CLUTTER_X11_FILTER_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_clipboard_class_init (NbtkClipboardClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkClipboardPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = nbtk_clipboard_get_property;
 | 
			
		||||
  object_class->set_property = nbtk_clipboard_set_property;
 | 
			
		||||
  object_class->dispose = nbtk_clipboard_dispose;
 | 
			
		||||
  object_class->finalize = nbtk_clipboard_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_clipboard_init (NbtkClipboard *self)
 | 
			
		||||
{
 | 
			
		||||
  Display *dpy;
 | 
			
		||||
  NbtkClipboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = self->priv = CLIPBOARD_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  priv->clipboard_window =
 | 
			
		||||
    XCreateSimpleWindow (clutter_x11_get_default_display (),
 | 
			
		||||
                         clutter_x11_get_root_window (),
 | 
			
		||||
                         -1, -1, 1, 1, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
  dpy = clutter_x11_get_default_display ();
 | 
			
		||||
 | 
			
		||||
  /* Only create once */
 | 
			
		||||
  if (__atom_clip == None)
 | 
			
		||||
    __atom_clip = XInternAtom (dpy, "CLIPBOARD", 0);
 | 
			
		||||
 | 
			
		||||
  if (__utf8_string == None)
 | 
			
		||||
    __utf8_string = XInternAtom (dpy, "UTF8_STRING", 0);
 | 
			
		||||
 | 
			
		||||
  if (__atom_targets == None)
 | 
			
		||||
    __atom_targets = XInternAtom (dpy, "TARGETS", 0);
 | 
			
		||||
 | 
			
		||||
  priv->n_targets = 2;
 | 
			
		||||
  priv->supported_targets = g_new (Atom, priv->n_targets);
 | 
			
		||||
 | 
			
		||||
  priv->supported_targets[0] = __utf8_string;
 | 
			
		||||
  priv->supported_targets[1] = __atom_targets;
 | 
			
		||||
 | 
			
		||||
  clutter_x11_add_filter ((ClutterX11FilterFunc) nbtk_clipboard_provider,
 | 
			
		||||
                          self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterX11FilterReturn
 | 
			
		||||
nbtk_clipboard_x11_event_filter (XEvent          *xev,
 | 
			
		||||
                                 ClutterEvent    *cev,
 | 
			
		||||
                                 EventFilterData *filter_data)
 | 
			
		||||
{
 | 
			
		||||
  Atom actual_type;
 | 
			
		||||
  int actual_format, result;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  unsigned char *data = NULL;
 | 
			
		||||
 | 
			
		||||
  if(xev->type != SelectionNotify)
 | 
			
		||||
    return CLUTTER_X11_FILTER_CONTINUE;
 | 
			
		||||
 | 
			
		||||
  if (xev->xselection.property == None)
 | 
			
		||||
    {
 | 
			
		||||
      /* clipboard empty */
 | 
			
		||||
      filter_data->callback (filter_data->clipboard,
 | 
			
		||||
                             NULL,
 | 
			
		||||
                             filter_data->user_data);
 | 
			
		||||
 | 
			
		||||
      clutter_x11_remove_filter ((ClutterX11FilterFunc) nbtk_clipboard_x11_event_filter,
 | 
			
		||||
                                 filter_data);
 | 
			
		||||
      g_free (filter_data);
 | 
			
		||||
      return CLUTTER_X11_FILTER_REMOVE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_x11_trap_x_errors ();
 | 
			
		||||
 | 
			
		||||
  result = XGetWindowProperty (xev->xselection.display,
 | 
			
		||||
                               xev->xselection.requestor,
 | 
			
		||||
                               xev->xselection.property,
 | 
			
		||||
                               0L, G_MAXINT,
 | 
			
		||||
                               True,
 | 
			
		||||
                               AnyPropertyType,
 | 
			
		||||
                               &actual_type,
 | 
			
		||||
                               &actual_format,
 | 
			
		||||
                               &nitems,
 | 
			
		||||
                               &bytes_after,
 | 
			
		||||
                               &data);
 | 
			
		||||
 | 
			
		||||
  if (clutter_x11_untrap_x_errors () || result != Success)
 | 
			
		||||
    {
 | 
			
		||||
      /* FIXME: handle failure better */
 | 
			
		||||
      g_warning ("Clipboard: prop retrival failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  filter_data->callback (filter_data->clipboard, (char*) data,
 | 
			
		||||
                         filter_data->user_data);
 | 
			
		||||
 | 
			
		||||
  clutter_x11_remove_filter
 | 
			
		||||
                    ((ClutterX11FilterFunc) nbtk_clipboard_x11_event_filter,
 | 
			
		||||
                     filter_data);
 | 
			
		||||
 | 
			
		||||
  g_free (filter_data);
 | 
			
		||||
 | 
			
		||||
  if (data)
 | 
			
		||||
    XFree (data);
 | 
			
		||||
 | 
			
		||||
  return CLUTTER_X11_FILTER_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_clipboard_get_default:
 | 
			
		||||
 *
 | 
			
		||||
 * Get the global #NbtkClipboard object that represents the clipboard.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): a #NbtkClipboard owned by Nbtk and must not be
 | 
			
		||||
 * unrefferenced or freed.
 | 
			
		||||
 */
 | 
			
		||||
NbtkClipboard*
 | 
			
		||||
nbtk_clipboard_get_default (void)
 | 
			
		||||
{
 | 
			
		||||
  static NbtkClipboard *default_clipboard = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!default_clipboard)
 | 
			
		||||
    {
 | 
			
		||||
      default_clipboard = g_object_new (NBTK_TYPE_CLIPBOARD, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return default_clipboard;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_clipboard_get_text:
 | 
			
		||||
 * @clipboard: A #NbtkCliboard
 | 
			
		||||
 * @callback: function to be called when the text is retreived
 | 
			
		||||
 * @user_data: data to be passed to the callback
 | 
			
		||||
 *
 | 
			
		||||
 * Request the data from the clipboard in text form. @callback is executed
 | 
			
		||||
 * when the data is retreived.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_clipboard_get_text (NbtkClipboard             *clipboard,
 | 
			
		||||
                         NbtkClipboardCallbackFunc  callback,
 | 
			
		||||
                         gpointer                   user_data)
 | 
			
		||||
{
 | 
			
		||||
  EventFilterData *data;
 | 
			
		||||
 | 
			
		||||
  Display *dpy;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_CLIPBOARD (clipboard));
 | 
			
		||||
  g_return_if_fail (callback != NULL);
 | 
			
		||||
 | 
			
		||||
  data = g_new0 (EventFilterData, 1);
 | 
			
		||||
  data->clipboard = clipboard;
 | 
			
		||||
  data->callback = callback;
 | 
			
		||||
  data->user_data = user_data;
 | 
			
		||||
 | 
			
		||||
  clutter_x11_add_filter ((ClutterX11FilterFunc)nbtk_clipboard_x11_event_filter,
 | 
			
		||||
                          data);
 | 
			
		||||
 | 
			
		||||
  dpy = clutter_x11_get_default_display ();
 | 
			
		||||
 | 
			
		||||
  clutter_x11_trap_x_errors (); /* safety on */
 | 
			
		||||
 | 
			
		||||
  XConvertSelection (dpy,
 | 
			
		||||
                     __atom_clip,
 | 
			
		||||
                     __utf8_string, __utf8_string,
 | 
			
		||||
                     clipboard->priv->clipboard_window,
 | 
			
		||||
                     CurrentTime);
 | 
			
		||||
 | 
			
		||||
  clutter_x11_untrap_x_errors ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_clipboard_set_text:
 | 
			
		||||
 * @clipboard: A #NbtkClipboard
 | 
			
		||||
 * @text: text to copy to the clipboard
 | 
			
		||||
 *
 | 
			
		||||
 * Sets text as the current contents of the clipboard.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_clipboard_set_text (NbtkClipboard *clipboard,
 | 
			
		||||
                         const gchar   *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkClipboardPrivate *priv;
 | 
			
		||||
  Display *dpy;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_CLIPBOARD (clipboard));
 | 
			
		||||
  g_return_if_fail (text != NULL);
 | 
			
		||||
 | 
			
		||||
  priv = clipboard->priv;
 | 
			
		||||
 | 
			
		||||
  /* make a copy of the text */
 | 
			
		||||
  g_free (priv->clipboard_text);
 | 
			
		||||
  priv->clipboard_text = g_strdup (text);
 | 
			
		||||
 | 
			
		||||
  /* tell X we own the clipboard selection */
 | 
			
		||||
  dpy = clutter_x11_get_default_display ();
 | 
			
		||||
 | 
			
		||||
  clutter_x11_trap_x_errors ();
 | 
			
		||||
 | 
			
		||||
  XSetSelectionOwner (dpy, __atom_clip, priv->clipboard_window, CurrentTime);
 | 
			
		||||
  XSync (dpy, FALSE);
 | 
			
		||||
 | 
			
		||||
  clutter_x11_untrap_x_errors ();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								src/nbtk/nbtk-clipboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/nbtk/nbtk-clipboard.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-clipboard.h: clipboard object
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas.wood@intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _NBTK_CLIPBOARD_H
 | 
			
		||||
#define _NBTK_CLIPBOARD_H
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_CLIPBOARD nbtk_clipboard_get_type()
 | 
			
		||||
 | 
			
		||||
#define NBTK_CLIPBOARD(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
 | 
			
		||||
  NBTK_TYPE_CLIPBOARD, NbtkClipboard))
 | 
			
		||||
 | 
			
		||||
#define NBTK_CLIPBOARD_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_CAST ((klass), \
 | 
			
		||||
  NBTK_TYPE_CLIPBOARD, NbtkClipboardClass))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_CLIPBOARD(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
 | 
			
		||||
  NBTK_TYPE_CLIPBOARD))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_CLIPBOARD_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
 | 
			
		||||
  NBTK_TYPE_CLIPBOARD))
 | 
			
		||||
 | 
			
		||||
#define NBTK_CLIPBOARD_GET_CLASS(obj) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
 | 
			
		||||
  NBTK_TYPE_CLIPBOARD, NbtkClipboardClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkClipboard NbtkClipboard;
 | 
			
		||||
typedef struct _NbtkClipboardClass NbtkClipboardClass;
 | 
			
		||||
typedef struct _NbtkClipboardPrivate NbtkClipboardPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkClipboard:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure is private and should only be accessed using
 | 
			
		||||
 * the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkClipboard
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GObject parent;
 | 
			
		||||
  NbtkClipboardPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkClipboardClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkClipboardCallbackFunc:
 | 
			
		||||
 * @clipboard: A #NbtkClipboard
 | 
			
		||||
 * @text: text from the clipboard
 | 
			
		||||
 * @user_data: user data
 | 
			
		||||
 *
 | 
			
		||||
 * Callback function called when text is retrieved from the clipboard.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*NbtkClipboardCallbackFunc) (NbtkClipboard *clipboard,
 | 
			
		||||
                                           const gchar   *text,
 | 
			
		||||
                                           gpointer       user_data);
 | 
			
		||||
 | 
			
		||||
GType nbtk_clipboard_get_type (void);
 | 
			
		||||
 | 
			
		||||
NbtkClipboard* nbtk_clipboard_get_default (void);
 | 
			
		||||
void nbtk_clipboard_get_text (NbtkClipboard *clipboard, NbtkClipboardCallbackFunc callback, gpointer user_data);
 | 
			
		||||
void nbtk_clipboard_set_text (NbtkClipboard *clipboard, const gchar *text);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* _NBTK_CLIPBOARD_H */
 | 
			
		||||
							
								
								
									
										897
									
								
								src/nbtk/nbtk-entry.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										897
									
								
								src/nbtk/nbtk-entry.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,897 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-entry.c: Plain entry actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas.wood@intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-entry
 | 
			
		||||
 * @short_description: Widget for displaying text
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkEntry is a simple widget for displaying text. It derives from
 | 
			
		||||
 * #NbtkWidget to add extra style and placement functionality over
 | 
			
		||||
 * #ClutterText. The internal #ClutterText is publicly accessibly to allow
 | 
			
		||||
 * applications to set further properties.
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkEntry supports the following pseudo style states:
 | 
			
		||||
 * <itemizedlist>
 | 
			
		||||
 *  <listitem>
 | 
			
		||||
 *   <para>focus: the widget has focus</para>
 | 
			
		||||
 *  </listitem>
 | 
			
		||||
 *  <listitem>
 | 
			
		||||
 *   <para>indeterminate: the widget is showing the hint text</para>
 | 
			
		||||
 *  </listitem>
 | 
			
		||||
 * </itemizedlist>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <clutter-imcontext/clutter-imtext.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-entry.h"
 | 
			
		||||
 | 
			
		||||
#include "nbtk-widget.h"
 | 
			
		||||
#include "nbtk-texture-cache.h"
 | 
			
		||||
#include "nbtk-marshal.h"
 | 
			
		||||
#include "nbtk-clipboard.h"
 | 
			
		||||
 | 
			
		||||
#define HAS_FOCUS(actor) (clutter_actor_get_stage (actor) && clutter_stage_get_key_focus ((ClutterStage *) clutter_actor_get_stage (actor)) == actor)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* properties */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_CLUTTER_TEXT,
 | 
			
		||||
  PROP_HINT_TEXT,
 | 
			
		||||
  PROP_TEXT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* signals */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PRIMARY_ICON_CLICKED,
 | 
			
		||||
  SECONDARY_ICON_CLICKED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define NBTK_ENTRY_GET_PRIVATE(obj)     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_ENTRY, NbtkEntryPrivate))
 | 
			
		||||
#define NBTK_ENTRY_PRIV(x) ((NbtkEntry *) x)->priv
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _NbtkEntryPrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *entry;
 | 
			
		||||
  gchar        *hint;
 | 
			
		||||
 | 
			
		||||
  ClutterActor *primary_icon;
 | 
			
		||||
  ClutterActor *secondary_icon;
 | 
			
		||||
 | 
			
		||||
  gfloat   spacing;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint entry_signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkEntry, nbtk_entry, NBTK_TYPE_WIDGET);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_set_property (GObject      *gobject,
 | 
			
		||||
                         guint         prop_id,
 | 
			
		||||
                         const GValue *value,
 | 
			
		||||
                         GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntry *entry = NBTK_ENTRY (gobject);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_HINT_TEXT:
 | 
			
		||||
      nbtk_entry_set_hint_text (entry, g_value_get_string (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
      nbtk_entry_set_text (entry, g_value_get_string (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_get_property (GObject    *gobject,
 | 
			
		||||
                         guint       prop_id,
 | 
			
		||||
                         GValue     *value,
 | 
			
		||||
                         GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (gobject);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_CLUTTER_TEXT:
 | 
			
		||||
      g_value_set_object (value, priv->entry);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_HINT_TEXT:
 | 
			
		||||
      g_value_set_string (value, priv->hint);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
      g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->entry)));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (object);
 | 
			
		||||
 | 
			
		||||
  if (priv->entry)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_unparent (priv->entry);
 | 
			
		||||
      priv->entry = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (object);
 | 
			
		||||
 | 
			
		||||
  g_free (priv->hint);
 | 
			
		||||
  priv->hint = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_style_changed (NbtkWidget *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (self);
 | 
			
		||||
  ShellThemeNode *theme_node;
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  const PangoFontDescription *font;
 | 
			
		||||
  gchar *font_string;
 | 
			
		||||
 | 
			
		||||
  theme_node = nbtk_widget_get_theme_node (self);
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_foreground_color (theme_node, &color);
 | 
			
		||||
  clutter_text_set_color (CLUTTER_TEXT (priv->entry), &color);
 | 
			
		||||
 | 
			
		||||
  if (shell_theme_node_get_color (theme_node, "caret-color", FALSE, &color))
 | 
			
		||||
      clutter_text_set_cursor_color (CLUTTER_TEXT (priv->entry), &color);
 | 
			
		||||
 | 
			
		||||
  if (shell_theme_node_get_color (theme_node, "selection-background-color", FALSE, &color))
 | 
			
		||||
    clutter_text_set_selection_color (CLUTTER_TEXT (priv->entry), &color);
 | 
			
		||||
 | 
			
		||||
  font = shell_theme_node_get_font (theme_node);
 | 
			
		||||
  font_string = pango_font_description_to_string (font);
 | 
			
		||||
  clutter_text_set_font_name (CLUTTER_TEXT (priv->entry), font_string);
 | 
			
		||||
  g_free (font_string);
 | 
			
		||||
 | 
			
		||||
  NBTK_WIDGET_CLASS (nbtk_entry_parent_class)->style_changed (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_get_preferred_width (ClutterActor *actor,
 | 
			
		||||
                                gfloat   for_height,
 | 
			
		||||
                                gfloat  *min_width_p,
 | 
			
		||||
                                gfloat  *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
  gfloat icon_w;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_height (theme_node, &for_height);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_preferred_width (priv->entry, for_height,
 | 
			
		||||
                                     min_width_p,
 | 
			
		||||
                                     natural_width_p);
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->primary_icon, -1, NULL, &icon_w);
 | 
			
		||||
 | 
			
		||||
      if (min_width_p)
 | 
			
		||||
        *min_width_p += icon_w + priv->spacing;
 | 
			
		||||
 | 
			
		||||
      if (natural_width_p)
 | 
			
		||||
        *natural_width_p += icon_w + priv->spacing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->secondary_icon,
 | 
			
		||||
                                         -1, NULL, &icon_w);
 | 
			
		||||
 | 
			
		||||
      if (min_width_p)
 | 
			
		||||
        *min_width_p += icon_w + priv->spacing;
 | 
			
		||||
 | 
			
		||||
      if (natural_width_p)
 | 
			
		||||
        *natural_width_p += icon_w + priv->spacing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_get_preferred_height (ClutterActor *actor,
 | 
			
		||||
                                 gfloat   for_width,
 | 
			
		||||
                                 gfloat  *min_height_p,
 | 
			
		||||
                                 gfloat  *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
  gfloat icon_h;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_width (theme_node, &for_width);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_preferred_height (priv->entry, for_width,
 | 
			
		||||
                                      min_height_p,
 | 
			
		||||
                                      natural_height_p);
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->primary_icon,
 | 
			
		||||
                                          -1, NULL, &icon_h);
 | 
			
		||||
 | 
			
		||||
      if (min_height_p && icon_h > *min_height_p)
 | 
			
		||||
        *min_height_p = icon_h;
 | 
			
		||||
 | 
			
		||||
      if (natural_height_p && icon_h > *natural_height_p)
 | 
			
		||||
        *natural_height_p = icon_h;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->secondary_icon,
 | 
			
		||||
                                          -1, NULL, &icon_h);
 | 
			
		||||
 | 
			
		||||
      if (min_height_p && icon_h > *min_height_p)
 | 
			
		||||
        *min_height_p = icon_h;
 | 
			
		||||
 | 
			
		||||
      if (natural_height_p && icon_h > *natural_height_p)
 | 
			
		||||
        *natural_height_p = icon_h;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_allocate (ClutterActor          *actor,
 | 
			
		||||
                     const ClutterActorBox *box,
 | 
			
		||||
                     ClutterAllocationFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
  ClutterActorClass *parent_class;
 | 
			
		||||
  ClutterActorBox content_box, child_box, icon_box;
 | 
			
		||||
  gfloat icon_w, icon_h;
 | 
			
		||||
  gfloat entry_h, min_h, pref_h, avail_h;
 | 
			
		||||
 | 
			
		||||
  parent_class = CLUTTER_ACTOR_CLASS (nbtk_entry_parent_class);
 | 
			
		||||
  parent_class->allocate (actor, box, flags);
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_content_box (theme_node, box, &content_box);
 | 
			
		||||
 | 
			
		||||
  avail_h = content_box.y2 - content_box.y1;
 | 
			
		||||
 | 
			
		||||
  child_box.x1 = content_box.x1;
 | 
			
		||||
  child_box.x2 = content_box.x2;
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->primary_icon,
 | 
			
		||||
                                         -1, NULL, &icon_w);
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->primary_icon,
 | 
			
		||||
                                          -1, NULL, &icon_h);
 | 
			
		||||
 | 
			
		||||
      icon_box.x1 = content_box.x1;
 | 
			
		||||
      icon_box.x2 = icon_box.x1 + icon_w;
 | 
			
		||||
 | 
			
		||||
      icon_box.y1 = (int) (content_box.y1 + avail_h / 2 - icon_h / 2);
 | 
			
		||||
      icon_box.y2 = icon_box.y1 + icon_h;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (priv->primary_icon,
 | 
			
		||||
                              &icon_box,
 | 
			
		||||
                              flags);
 | 
			
		||||
 | 
			
		||||
      /* reduce the size for the entry */
 | 
			
		||||
      child_box.x1 += icon_w + priv->spacing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->secondary_icon,
 | 
			
		||||
                                         -1, NULL, &icon_w);
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->secondary_icon,
 | 
			
		||||
                                          -1, NULL, &icon_h);
 | 
			
		||||
 | 
			
		||||
      icon_box.x2 = content_box.x2;
 | 
			
		||||
      icon_box.x1 = icon_box.x2 - icon_w;
 | 
			
		||||
 | 
			
		||||
      icon_box.y1 = (int) (content_box.y1 + avail_h / 2 - icon_h / 2);
 | 
			
		||||
      icon_box.y2 = icon_box.y1 + icon_h;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (priv->secondary_icon,
 | 
			
		||||
                              &icon_box,
 | 
			
		||||
                              flags);
 | 
			
		||||
 | 
			
		||||
      /* reduce the size for the entry */
 | 
			
		||||
      child_box.x2 -= icon_w - priv->spacing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_preferred_height (priv->entry, child_box.x2 - child_box.x1,
 | 
			
		||||
                                      &min_h, &pref_h);
 | 
			
		||||
 | 
			
		||||
  entry_h = CLAMP (pref_h, min_h, avail_h);
 | 
			
		||||
 | 
			
		||||
  child_box.y1 = (int) (content_box.y1 + avail_h / 2 - entry_h / 2);
 | 
			
		||||
  child_box.y2 = child_box.y1 + entry_h;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_allocate (priv->entry, &child_box, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_text_focus_in_cb (ClutterText *text,
 | 
			
		||||
                          ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
 | 
			
		||||
  /* remove the hint if visible */
 | 
			
		||||
  if (priv->hint
 | 
			
		||||
      && !strcmp (clutter_text_get_text (text), priv->hint))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_text_set_text (text, "");
 | 
			
		||||
    }
 | 
			
		||||
  nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (actor), "focus");
 | 
			
		||||
  clutter_text_set_cursor_visible (text, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_text_focus_out_cb (ClutterText  *text,
 | 
			
		||||
                           ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
 | 
			
		||||
  /* add a hint if the entry is empty */
 | 
			
		||||
  if (priv->hint && !strcmp (clutter_text_get_text (text), ""))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_text_set_text (text, priv->hint);
 | 
			
		||||
      nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (actor), "indeterminate");
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (actor), NULL);
 | 
			
		||||
    }
 | 
			
		||||
  clutter_text_set_cursor_visible (text, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
  ClutterActorClass *parent_class;
 | 
			
		||||
 | 
			
		||||
  parent_class = CLUTTER_ACTOR_CLASS (nbtk_entry_parent_class);
 | 
			
		||||
  parent_class->paint (actor);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_paint (priv->entry);
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    clutter_actor_paint (priv->primary_icon);
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    clutter_actor_paint (priv->secondary_icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_pick (ClutterActor *actor,
 | 
			
		||||
                 const ClutterColor *c)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_entry_parent_class)->pick (actor, c);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_paint (priv->entry);
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    clutter_actor_paint (priv->primary_icon);
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    clutter_actor_paint (priv->secondary_icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_map (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY (actor)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_entry_parent_class)->map (actor);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_map (priv->entry);
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    clutter_actor_map (priv->primary_icon);
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    clutter_actor_map (priv->secondary_icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_unmap (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY (actor)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_entry_parent_class)->unmap (actor);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_unmap (priv->entry);
 | 
			
		||||
 | 
			
		||||
  if (priv->primary_icon)
 | 
			
		||||
    clutter_actor_unmap (priv->primary_icon);
 | 
			
		||||
 | 
			
		||||
  if (priv->secondary_icon)
 | 
			
		||||
    clutter_actor_unmap (priv->secondary_icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_clipboard_callback (NbtkClipboard *clipboard,
 | 
			
		||||
                               const gchar   *text,
 | 
			
		||||
                               gpointer       data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterText *ctext = (ClutterText*) ((NbtkEntry *) data)->priv->entry;
 | 
			
		||||
  gint cursor_pos;
 | 
			
		||||
 | 
			
		||||
  if (!text)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* delete the current selection before pasting */
 | 
			
		||||
  clutter_text_delete_selection (ctext);
 | 
			
		||||
 | 
			
		||||
  /* "paste" the clipboard text into the entry */
 | 
			
		||||
  cursor_pos = clutter_text_get_cursor_position (ctext);
 | 
			
		||||
  clutter_text_insert_text (ctext, text, cursor_pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_entry_key_press_event (ClutterActor    *actor,
 | 
			
		||||
                            ClutterKeyEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
 | 
			
		||||
  /* This is expected to handle events that were emitted for the inner
 | 
			
		||||
     ClutterText. They only reach this function if the ClutterText
 | 
			
		||||
     didn't handle them */
 | 
			
		||||
 | 
			
		||||
  /* paste */
 | 
			
		||||
  if ((event->modifier_state & CLUTTER_CONTROL_MASK)
 | 
			
		||||
      && event->keyval == CLUTTER_v)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkClipboard *clipboard;
 | 
			
		||||
 | 
			
		||||
      clipboard = nbtk_clipboard_get_default ();
 | 
			
		||||
 | 
			
		||||
      nbtk_clipboard_get_text (clipboard, nbtk_entry_clipboard_callback, actor);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* copy */
 | 
			
		||||
  if ((event->modifier_state & CLUTTER_CONTROL_MASK)
 | 
			
		||||
      && event->keyval == CLUTTER_c)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkClipboard *clipboard;
 | 
			
		||||
      gchar *text;
 | 
			
		||||
 | 
			
		||||
      clipboard = nbtk_clipboard_get_default ();
 | 
			
		||||
 | 
			
		||||
      text = clutter_text_get_selection ((ClutterText*) priv->entry);
 | 
			
		||||
 | 
			
		||||
      if (text && strlen (text))
 | 
			
		||||
        nbtk_clipboard_set_text (clipboard, text);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* cut */
 | 
			
		||||
  if ((event->modifier_state & CLUTTER_CONTROL_MASK)
 | 
			
		||||
      && event->keyval == CLUTTER_x)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkClipboard *clipboard;
 | 
			
		||||
      gchar *text;
 | 
			
		||||
 | 
			
		||||
      clipboard = nbtk_clipboard_get_default ();
 | 
			
		||||
 | 
			
		||||
      text = clutter_text_get_selection ((ClutterText*) priv->entry);
 | 
			
		||||
 | 
			
		||||
      if (text && strlen (text))
 | 
			
		||||
        {
 | 
			
		||||
          nbtk_clipboard_set_text (clipboard, text);
 | 
			
		||||
 | 
			
		||||
          /* now delete the text */
 | 
			
		||||
          clutter_text_delete_selection ((ClutterText *) priv->entry);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_key_focus_in (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = NBTK_ENTRY_PRIV (actor);
 | 
			
		||||
 | 
			
		||||
  /* We never want key focus. The ClutterText should be given first
 | 
			
		||||
     pass for all key events */
 | 
			
		||||
  clutter_actor_grab_key_focus (priv->entry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_class_init (NbtkEntryClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkEntryPrivate));
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_entry_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_entry_get_property;
 | 
			
		||||
  gobject_class->finalize = nbtk_entry_finalize;
 | 
			
		||||
  gobject_class->dispose = nbtk_entry_dispose;
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width = nbtk_entry_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = nbtk_entry_get_preferred_height;
 | 
			
		||||
  actor_class->allocate = nbtk_entry_allocate;
 | 
			
		||||
  actor_class->paint = nbtk_entry_paint;
 | 
			
		||||
  actor_class->pick = nbtk_entry_pick;
 | 
			
		||||
  actor_class->map = nbtk_entry_map;
 | 
			
		||||
  actor_class->unmap = nbtk_entry_unmap;
 | 
			
		||||
 | 
			
		||||
  actor_class->key_press_event = nbtk_entry_key_press_event;
 | 
			
		||||
  actor_class->key_focus_in = nbtk_entry_key_focus_in;
 | 
			
		||||
 | 
			
		||||
  widget_class->style_changed = nbtk_entry_style_changed;
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_object ("clutter-text",
 | 
			
		||||
			       "Clutter Text",
 | 
			
		||||
			       "Internal ClutterText actor",
 | 
			
		||||
			       CLUTTER_TYPE_TEXT,
 | 
			
		||||
			       G_PARAM_READABLE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_CLUTTER_TEXT, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_string ("hint-text",
 | 
			
		||||
                               "Hint Text",
 | 
			
		||||
                               "Text to display when the entry is not focused "
 | 
			
		||||
                               "and the text property is empty",
 | 
			
		||||
                               NULL, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_HINT_TEXT, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_string ("text",
 | 
			
		||||
                               "Text",
 | 
			
		||||
                               "Text of the entry",
 | 
			
		||||
                               NULL, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
 | 
			
		||||
 | 
			
		||||
  /* signals */
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkEntry::primary-icon-clicked:
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the primary icon is clicked
 | 
			
		||||
   */
 | 
			
		||||
  entry_signals[PRIMARY_ICON_CLICKED] =
 | 
			
		||||
    g_signal_new ("primary-icon-clicked",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (NbtkEntryClass, primary_icon_clicked),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _nbtk_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
  /**
 | 
			
		||||
   * NbtkEntry::secondary-icon-clicked:
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when the secondary icon is clicked
 | 
			
		||||
   */
 | 
			
		||||
  entry_signals[SECONDARY_ICON_CLICKED] =
 | 
			
		||||
    g_signal_new ("secondary-icon-clicked",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (NbtkEntryClass, secondary_icon_clicked),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _nbtk_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_entry_init (NbtkEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = entry->priv = NBTK_ENTRY_GET_PRIVATE (entry);
 | 
			
		||||
 | 
			
		||||
  priv->entry = g_object_new (CLUTTER_TYPE_IMTEXT,
 | 
			
		||||
                              "line-alignment", PANGO_ALIGN_LEFT,
 | 
			
		||||
                              "editable", TRUE,
 | 
			
		||||
                              "reactive", TRUE,
 | 
			
		||||
                              "single-line-mode", TRUE,
 | 
			
		||||
                              NULL);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (priv->entry, "key-focus-in",
 | 
			
		||||
                    G_CALLBACK (clutter_text_focus_in_cb), entry);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (priv->entry, "key-focus-out",
 | 
			
		||||
                    G_CALLBACK (clutter_text_focus_out_cb), entry);
 | 
			
		||||
 | 
			
		||||
  priv->spacing = 6.0f;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_parent (priv->entry, CLUTTER_ACTOR (entry));
 | 
			
		||||
  clutter_actor_set_reactive ((ClutterActor *) entry, TRUE);
 | 
			
		||||
 | 
			
		||||
  /* set cursor hidden until we receive focus */
 | 
			
		||||
  clutter_text_set_cursor_visible ((ClutterText *) priv->entry, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_new:
 | 
			
		||||
 * @text: text to set the entry to
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #NbtkEntry with the specified entry
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new #NbtkEntry
 | 
			
		||||
 */
 | 
			
		||||
NbtkWidget *
 | 
			
		||||
nbtk_entry_new (const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkWidget *entry;
 | 
			
		||||
 | 
			
		||||
  /* add the entry to the stage, but don't allow it to be visible */
 | 
			
		||||
  entry = g_object_new (NBTK_TYPE_ENTRY,
 | 
			
		||||
                        "text", text,
 | 
			
		||||
                        NULL);
 | 
			
		||||
 | 
			
		||||
  return entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_get_text:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 *
 | 
			
		||||
 * Get the text displayed on the entry
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the text for the entry. This must not be freed by the application
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
nbtk_entry_get_text (NbtkEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_ENTRY (entry), NULL);
 | 
			
		||||
 | 
			
		||||
  return clutter_text_get_text (CLUTTER_TEXT (entry->priv->entry));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_set_text:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 * @text: text to set the entry to
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the text displayed on the entry
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_entry_set_text (NbtkEntry *entry,
 | 
			
		||||
                     const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
  priv = entry->priv;
 | 
			
		||||
 | 
			
		||||
  /* set a hint if we are blanking the entry */
 | 
			
		||||
  if (priv->hint
 | 
			
		||||
      && text && !strcmp ("", text)
 | 
			
		||||
      && !HAS_FOCUS (priv->entry))
 | 
			
		||||
    {
 | 
			
		||||
      text = priv->hint;
 | 
			
		||||
      nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (entry), "indeterminate");
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (HAS_FOCUS (priv->entry))
 | 
			
		||||
        nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (entry), "focus");
 | 
			
		||||
      else
 | 
			
		||||
        nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (entry), NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_text_set_text (CLUTTER_TEXT (priv->entry), text);
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (entry), "text");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_get_clutter_text:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve the internal #ClutterText so that extra parameters can be set
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): the #ClutterText used by #NbtkEntry. The entry is
 | 
			
		||||
 * owned by the #NbtkEntry and should not be unref'ed by the application.
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor*
 | 
			
		||||
nbtk_entry_get_clutter_text (NbtkEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_ENTRY (entry), NULL);
 | 
			
		||||
 | 
			
		||||
  return entry->priv->entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_set_hint_text:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 * @text: text to set as the entry hint
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the text to display when the entry is empty and unfocused. When the
 | 
			
		||||
 * entry is displaying the hint, it has a pseudo class of "indeterminate".
 | 
			
		||||
 * A value of NULL unsets the hint.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_entry_set_hint_text (NbtkEntry *entry,
 | 
			
		||||
                          const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
  priv = entry->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->hint);
 | 
			
		||||
 | 
			
		||||
  priv->hint = g_strdup (text);
 | 
			
		||||
 | 
			
		||||
  if (!strcmp (clutter_text_get_text (CLUTTER_TEXT (priv->entry)), ""))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_text_set_text (CLUTTER_TEXT (priv->entry), priv->hint);
 | 
			
		||||
      nbtk_widget_set_style_pseudo_class (NBTK_WIDGET (entry), "indeterminate");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_get_hint_text:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the text that is displayed when the entry is empty and unfocused
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the current value of the hint property. This string is owned by the
 | 
			
		||||
 * #NbtkEntry and should not be freed or modified.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN
 | 
			
		||||
gchar *
 | 
			
		||||
nbtk_entry_get_hint_text (NbtkEntry *entry)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_ENTRY (entry), NULL);
 | 
			
		||||
 | 
			
		||||
  return entry->priv->hint;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
_nbtk_entry_icon_press_cb (ClutterActor       *actor,
 | 
			
		||||
                           ClutterButtonEvent *event,
 | 
			
		||||
                           NbtkEntry          *entry)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv = entry->priv;
 | 
			
		||||
 | 
			
		||||
  if (actor == priv->primary_icon)
 | 
			
		||||
    g_signal_emit (entry, entry_signals[PRIMARY_ICON_CLICKED], 0);
 | 
			
		||||
  else
 | 
			
		||||
    g_signal_emit (entry, entry_signals[SECONDARY_ICON_CLICKED], 0);
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_nbtk_entry_set_icon_from_file (NbtkEntry     *entry,
 | 
			
		||||
                                ClutterActor **icon,
 | 
			
		||||
                                const gchar   *filename)
 | 
			
		||||
{
 | 
			
		||||
  if (*icon)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_handlers_disconnect_by_func (*icon,
 | 
			
		||||
                                            _nbtk_entry_icon_press_cb,
 | 
			
		||||
                                            entry);
 | 
			
		||||
      clutter_actor_unparent (*icon);
 | 
			
		||||
      *icon = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (filename)
 | 
			
		||||
    {
 | 
			
		||||
      NbtkTextureCache *cache;
 | 
			
		||||
 | 
			
		||||
      cache = nbtk_texture_cache_get_default ();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      *icon = (ClutterActor*) nbtk_texture_cache_get_texture (cache, filename, FALSE);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_set_reactive (*icon, TRUE);
 | 
			
		||||
      clutter_actor_set_parent (*icon, CLUTTER_ACTOR (entry));
 | 
			
		||||
      g_signal_connect (*icon, "button-release-event",
 | 
			
		||||
                        G_CALLBACK (_nbtk_entry_icon_press_cb), entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_relayout (CLUTTER_ACTOR (entry));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_set_primary_icon_from_file:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 * @filename: filename of an icon
 | 
			
		||||
 *
 | 
			
		||||
 * Set the primary icon of the entry to the given filename
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_entry_set_primary_icon_from_file (NbtkEntry   *entry,
 | 
			
		||||
                                       const gchar *filename)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
  priv = entry->priv;
 | 
			
		||||
 | 
			
		||||
  _nbtk_entry_set_icon_from_file (entry, &priv->primary_icon, filename);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_entry_set_secondary_icon_from_file:
 | 
			
		||||
 * @entry: a #NbtkEntry
 | 
			
		||||
 * @filename: filename of an icon
 | 
			
		||||
 *
 | 
			
		||||
 * Set the primary icon of the entry to the given filename
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_entry_set_secondary_icon_from_file (NbtkEntry   *entry,
 | 
			
		||||
                                         const gchar *filename)
 | 
			
		||||
{
 | 
			
		||||
  NbtkEntryPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_ENTRY (entry));
 | 
			
		||||
 | 
			
		||||
  priv = entry->priv;
 | 
			
		||||
 | 
			
		||||
  _nbtk_entry_set_icon_from_file (entry, &priv->secondary_icon, filename);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								src/nbtk/nbtk-entry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/nbtk/nbtk-entry.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-entry.h: Plain entry actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_ENTRY_H__
 | 
			
		||||
#define __NBTK_ENTRY_H__
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-widget.h>
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_ENTRY                (nbtk_entry_get_type ())
 | 
			
		||||
#define NBTK_ENTRY(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_ENTRY, NbtkEntry))
 | 
			
		||||
#define NBTK_IS_ENTRY(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_ENTRY))
 | 
			
		||||
#define NBTK_ENTRY_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_ENTRY, NbtkEntryClass))
 | 
			
		||||
#define NBTK_IS_ENTRY_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_ENTRY))
 | 
			
		||||
#define NBTK_ENTRY_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_ENTRY, NbtkEntryClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkEntry              NbtkEntry;
 | 
			
		||||
typedef struct _NbtkEntryPrivate       NbtkEntryPrivate;
 | 
			
		||||
typedef struct _NbtkEntryClass         NbtkEntryClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkEntry:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure is private and should only be accessed using
 | 
			
		||||
 * the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkEntry
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkWidget parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkEntryPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkEntryClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkWidgetClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* signals */
 | 
			
		||||
  void (*primary_icon_clicked) (NbtkEntry *entry);
 | 
			
		||||
  void (*secondary_icon_clicked) (NbtkEntry *entry);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_entry_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkWidget *          nbtk_entry_new              (const gchar *text);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_entry_get_text         (NbtkEntry   *entry);
 | 
			
		||||
void                  nbtk_entry_set_text         (NbtkEntry   *entry,
 | 
			
		||||
                                                   const gchar *text);
 | 
			
		||||
ClutterActor*         nbtk_entry_get_clutter_text (NbtkEntry   *entry);
 | 
			
		||||
 | 
			
		||||
void                  nbtk_entry_set_hint_text (NbtkEntry *entry,
 | 
			
		||||
                                                const gchar *text);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_entry_get_hint_text (NbtkEntry *entry);
 | 
			
		||||
 | 
			
		||||
void nbtk_entry_set_primary_icon_from_file (NbtkEntry   *entry,
 | 
			
		||||
                                            const gchar *filename);
 | 
			
		||||
void nbtk_entry_set_secondary_icon_from_file (NbtkEntry   *entry,
 | 
			
		||||
                                              const gchar *filename);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_ENTRY_H__ */
 | 
			
		||||
							
								
								
									
										30
									
								
								src/nbtk/nbtk-enum-types.c.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/nbtk/nbtk-enum-types.c.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#include "nbtk-enum-types.h"
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
/* enumerations from "@filename@" */
 | 
			
		||||
#include "@filename@"
 | 
			
		||||
/*** END file-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-header ***/
 | 
			
		||||
GType
 | 
			
		||||
@enum_name@_get_type(void) {
 | 
			
		||||
  static GType enum_type_id = 0;
 | 
			
		||||
  if (G_UNLIKELY (!enum_type_id))
 | 
			
		||||
    {
 | 
			
		||||
      static const G@Type@Value values[] = {
 | 
			
		||||
/*** END value-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-production ***/
 | 
			
		||||
        { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
 | 
			
		||||
/*** END value-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-tail ***/
 | 
			
		||||
        { 0, NULL, NULL }
 | 
			
		||||
      };
 | 
			
		||||
      enum_type_id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
 | 
			
		||||
    }
 | 
			
		||||
  return enum_type_id;
 | 
			
		||||
}
 | 
			
		||||
/*** END value-tail ***/
 | 
			
		||||
							
								
								
									
										29
									
								
								src/nbtk/nbtk-enum-types.h.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/nbtk/nbtk-enum-types.h.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_ENUM_TYPES_H__
 | 
			
		||||
#define __NBTK_ENUM_TYPES_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
/* enumerations from "@filename@" */
 | 
			
		||||
/*** END file-production ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-tail ***/
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* !__NBTK_ENUM_TYPES_H__ */
 | 
			
		||||
/*** END file-tail ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN value-header ***/
 | 
			
		||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
 | 
			
		||||
#define NBTK_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
 | 
			
		||||
 | 
			
		||||
/*** END value-header ***/
 | 
			
		||||
							
								
								
									
										341
									
								
								src/nbtk/nbtk-label.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/nbtk/nbtk-label.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-label.c: Plain label actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008,2009 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-label
 | 
			
		||||
 * @short_description: Widget for displaying text
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkLabel is a simple widget for displaying text. It derives from
 | 
			
		||||
 * #NbtkWidget to add extra style and placement functionality over
 | 
			
		||||
 * #ClutterText. The internal #ClutterText is publicly accessibly to allow
 | 
			
		||||
 * applications to set further properties.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-label.h"
 | 
			
		||||
 | 
			
		||||
#include "nbtk-widget.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_CLUTTER_TEXT,
 | 
			
		||||
  PROP_TEXT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define NBTK_LABEL_GET_PRIVATE(obj)     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_LABEL, NbtkLabelPrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkLabelPrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *label;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkLabel, nbtk_label, NBTK_TYPE_WIDGET);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_set_property (GObject      *gobject,
 | 
			
		||||
                           guint         prop_id,
 | 
			
		||||
                           const GValue *value,
 | 
			
		||||
                           GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabel *label = NBTK_LABEL (gobject);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
      nbtk_label_set_text (label, g_value_get_string (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_get_property (GObject    *gobject,
 | 
			
		||||
                           guint       prop_id,
 | 
			
		||||
                           GValue     *value,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_CLUTTER_TEXT:
 | 
			
		||||
      g_value_set_object (value, priv->label);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
      g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->label)));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_style_changed (NbtkWidget *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv;
 | 
			
		||||
  ShellThemeNode *theme_node;
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  const PangoFontDescription *font;
 | 
			
		||||
  gchar *font_string;
 | 
			
		||||
 | 
			
		||||
  priv = NBTK_LABEL (self)->priv;
 | 
			
		||||
  theme_node = nbtk_widget_get_theme_node (self);
 | 
			
		||||
  shell_theme_node_get_foreground_color (theme_node, &color);
 | 
			
		||||
  clutter_text_set_color (CLUTTER_TEXT (priv->label), &color);
 | 
			
		||||
 | 
			
		||||
  font = shell_theme_node_get_font (theme_node);
 | 
			
		||||
  font_string = pango_font_description_to_string (font);
 | 
			
		||||
  clutter_text_set_font_name (CLUTTER_TEXT (priv->label), font_string);
 | 
			
		||||
  g_free (font_string);
 | 
			
		||||
 | 
			
		||||
  NBTK_WIDGET_CLASS (nbtk_label_parent_class)->style_changed (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_get_preferred_width (ClutterActor *actor,
 | 
			
		||||
                                gfloat        for_height,
 | 
			
		||||
                                gfloat       *min_width_p,
 | 
			
		||||
                                gfloat       *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (actor)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_height (theme_node, &for_height);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_preferred_width (priv->label, for_height,
 | 
			
		||||
                                     min_width_p,
 | 
			
		||||
                                     natural_width_p);
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_get_preferred_height (ClutterActor *actor,
 | 
			
		||||
                                 gfloat        for_width,
 | 
			
		||||
                                 gfloat       *min_height_p,
 | 
			
		||||
                                 gfloat       *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (actor)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_width (theme_node, &for_width);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_preferred_height (priv->label, for_width,
 | 
			
		||||
                                      min_height_p,
 | 
			
		||||
                                      natural_height_p);
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_allocate (ClutterActor          *actor,
 | 
			
		||||
                     const ClutterActorBox *box,
 | 
			
		||||
                     ClutterAllocationFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (actor)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
  ClutterActorClass *parent_class;
 | 
			
		||||
  ClutterActorBox content_box;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_content_box (theme_node, box, &content_box);
 | 
			
		||||
 | 
			
		||||
  parent_class = CLUTTER_ACTOR_CLASS (nbtk_label_parent_class);
 | 
			
		||||
  parent_class->allocate (actor, box, flags);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_allocate (priv->label, &content_box, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (actor)->priv;
 | 
			
		||||
  ClutterActorClass *parent_class;
 | 
			
		||||
 | 
			
		||||
  parent_class = CLUTTER_ACTOR_CLASS (nbtk_label_parent_class);
 | 
			
		||||
  parent_class->paint (actor);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_paint (priv->label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_map (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (actor)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_label_parent_class)->map (actor);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_map (priv->label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_unmap (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv = NBTK_LABEL (actor)->priv;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_label_parent_class)->unmap (actor);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_unmap (priv->label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_class_init (NbtkLabelClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkLabelPrivate));
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_label_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_label_get_property;
 | 
			
		||||
 | 
			
		||||
  actor_class->paint = nbtk_label_paint;
 | 
			
		||||
  actor_class->allocate = nbtk_label_allocate;
 | 
			
		||||
  actor_class->get_preferred_width = nbtk_label_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = nbtk_label_get_preferred_height;
 | 
			
		||||
  actor_class->map = nbtk_label_map;
 | 
			
		||||
  actor_class->unmap = nbtk_label_unmap;
 | 
			
		||||
 | 
			
		||||
  widget_class->style_changed = nbtk_label_style_changed;
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_object ("clutter-text",
 | 
			
		||||
			       "Clutter Text",
 | 
			
		||||
			       "Internal ClutterText actor",
 | 
			
		||||
			       CLUTTER_TYPE_TEXT,
 | 
			
		||||
			       G_PARAM_READABLE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_CLUTTER_TEXT, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_string ("text",
 | 
			
		||||
                               "Text",
 | 
			
		||||
                               "Text of the label",
 | 
			
		||||
                               NULL, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_label_init (NbtkLabel *label)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  label->priv = priv = NBTK_LABEL_GET_PRIVATE (label);
 | 
			
		||||
 | 
			
		||||
  label->priv->label = g_object_new (CLUTTER_TYPE_TEXT,
 | 
			
		||||
                                     "ellipsize", PANGO_ELLIPSIZE_END,
 | 
			
		||||
                                     NULL);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_parent (priv->label, CLUTTER_ACTOR (label));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_label_new:
 | 
			
		||||
 * @text: text to set the label to
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #NbtkLabel with the specified label
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new #NbtkLabel
 | 
			
		||||
 */
 | 
			
		||||
NbtkWidget *
 | 
			
		||||
nbtk_label_new (const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  if (text == NULL || *text == '\0')
 | 
			
		||||
    return g_object_new (NBTK_TYPE_LABEL, NULL);
 | 
			
		||||
  else
 | 
			
		||||
    return g_object_new (NBTK_TYPE_LABEL,
 | 
			
		||||
                         "text", text,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_label_get_text:
 | 
			
		||||
 * @label: a #NbtkLabel
 | 
			
		||||
 *
 | 
			
		||||
 * Get the text displayed on the label
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the text for the label. This must not be freed by the application
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
nbtk_label_get_text (NbtkLabel *label)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_LABEL (label), NULL);
 | 
			
		||||
 | 
			
		||||
  return clutter_text_get_text (CLUTTER_TEXT (label->priv->label));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_label_set_text:
 | 
			
		||||
 * @label: a #NbtkLabel
 | 
			
		||||
 * @text: text to set the label to
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the text displayed on the label
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_label_set_text (NbtkLabel *label,
 | 
			
		||||
                     const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkLabelPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_LABEL (label));
 | 
			
		||||
  g_return_if_fail (text != NULL);
 | 
			
		||||
 | 
			
		||||
  priv = label->priv;
 | 
			
		||||
 | 
			
		||||
  clutter_text_set_text (CLUTTER_TEXT (priv->label), text);
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (label), "text");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_label_get_clutter_text:
 | 
			
		||||
 * @label: a #NbtkLabel
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve the internal #ClutterText so that extra parameters can be set
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): ethe #ClutterText used by #NbtkLabel. The label
 | 
			
		||||
 * is owned by the #NbtkLabel and should not be unref'ed by the application.
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor*
 | 
			
		||||
nbtk_label_get_clutter_text (NbtkLabel *label)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_LABEL (label), NULL);
 | 
			
		||||
 | 
			
		||||
  return label->priv->label;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								src/nbtk/nbtk-label.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/nbtk/nbtk-label.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-label.h: Plain label actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_LABEL_H__
 | 
			
		||||
#define __NBTK_LABEL_H__
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-widget.h>
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_LABEL                (nbtk_label_get_type ())
 | 
			
		||||
#define NBTK_LABEL(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_LABEL, NbtkLabel))
 | 
			
		||||
#define NBTK_IS_LABEL(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_LABEL))
 | 
			
		||||
#define NBTK_LABEL_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_LABEL, NbtkLabelClass))
 | 
			
		||||
#define NBTK_IS_LABEL_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_LABEL))
 | 
			
		||||
#define NBTK_LABEL_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_LABEL, NbtkLabelClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkLabel              NbtkLabel;
 | 
			
		||||
typedef struct _NbtkLabelPrivate       NbtkLabelPrivate;
 | 
			
		||||
typedef struct _NbtkLabelClass         NbtkLabelClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkLabel:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure is private and should only be accessed using
 | 
			
		||||
 * the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkLabel
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkWidget parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkLabelPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkLabelClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkWidgetClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_label_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkWidget *          nbtk_label_new              (const gchar *text);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_label_get_text         (NbtkLabel   *label);
 | 
			
		||||
void                  nbtk_label_set_text         (NbtkLabel   *label,
 | 
			
		||||
                                                   const gchar *text);
 | 
			
		||||
ClutterActor *        nbtk_label_get_clutter_text (NbtkLabel   *label);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_LABEL_H__ */
 | 
			
		||||
							
								
								
									
										12
									
								
								src/nbtk/nbtk-marshal.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/nbtk/nbtk-marshal.list
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
VOID:OBJECT
 | 
			
		||||
VOID:VOID
 | 
			
		||||
VOID:PARAM
 | 
			
		||||
VOID:POINTER
 | 
			
		||||
VOID:UINT
 | 
			
		||||
VOID:UINT,UINT
 | 
			
		||||
VOID:OBJECT,OBJECT
 | 
			
		||||
VOID:STRING,OBJECT
 | 
			
		||||
VOID:OBJECT,OBJECT,INT,INT
 | 
			
		||||
VOID:OBJECT,FLOAT,FLOAT,INT,ENUM
 | 
			
		||||
VOID:FLOAT,FLOAT,INT,ENUM
 | 
			
		||||
VOID:FLOAT,FLOAT
 | 
			
		||||
							
								
								
									
										111
									
								
								src/nbtk/nbtk-private.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/nbtk/nbtk-private.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
/* Utility function to modify a child allocation box with respect to the
 | 
			
		||||
 * x/y-fill child properties. Expects childbox to contain the available
 | 
			
		||||
 * allocation space.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
_nbtk_allocate_fill (ClutterActor *child,
 | 
			
		||||
                     ClutterActorBox *childbox,
 | 
			
		||||
                     NbtkAlign x_alignment,
 | 
			
		||||
                     NbtkAlign y_alignment,
 | 
			
		||||
                     gboolean x_fill,
 | 
			
		||||
                     gboolean y_fill)
 | 
			
		||||
{
 | 
			
		||||
  gfloat natural_width, natural_height;
 | 
			
		||||
  gfloat min_width, min_height;
 | 
			
		||||
  gfloat child_width, child_height;
 | 
			
		||||
  gfloat available_width, available_height;
 | 
			
		||||
  ClutterRequestMode request;
 | 
			
		||||
  ClutterActorBox allocation = { 0, };
 | 
			
		||||
  gdouble x_align, y_align;
 | 
			
		||||
 | 
			
		||||
  if (x_alignment == NBTK_ALIGN_START)
 | 
			
		||||
    x_align = 0.0;
 | 
			
		||||
  else if (x_alignment == NBTK_ALIGN_MIDDLE)
 | 
			
		||||
    x_align = 0.5;
 | 
			
		||||
  else
 | 
			
		||||
    x_align = 1.0;
 | 
			
		||||
 | 
			
		||||
  if (y_alignment == NBTK_ALIGN_START)
 | 
			
		||||
    y_align = 0.0;
 | 
			
		||||
  else if (y_alignment == NBTK_ALIGN_MIDDLE)
 | 
			
		||||
    y_align = 0.5;
 | 
			
		||||
  else
 | 
			
		||||
    y_align = 1.0;
 | 
			
		||||
 | 
			
		||||
  available_width  = childbox->x2 - childbox->x1;
 | 
			
		||||
  available_height = childbox->y2 - childbox->y1;
 | 
			
		||||
 | 
			
		||||
  if (available_width < 0)
 | 
			
		||||
    available_width = 0;
 | 
			
		||||
 | 
			
		||||
  if (available_height < 0)
 | 
			
		||||
    available_height = 0;
 | 
			
		||||
 | 
			
		||||
  if (x_fill)
 | 
			
		||||
    {
 | 
			
		||||
      allocation.x1 = childbox->x1;
 | 
			
		||||
      allocation.x2 = (int) (allocation.x1 + available_width);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (y_fill)
 | 
			
		||||
    {
 | 
			
		||||
      allocation.y1 = childbox->y1;
 | 
			
		||||
      allocation.y2 = (int) (allocation.y1 + available_height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* if we are filling horizontally and vertically then we're done */
 | 
			
		||||
  if (x_fill && y_fill)
 | 
			
		||||
    {
 | 
			
		||||
      *childbox = allocation;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
 | 
			
		||||
  g_object_get (G_OBJECT (child), "request-mode", &request, NULL);
 | 
			
		||||
 | 
			
		||||
  if (request == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (child, available_height,
 | 
			
		||||
                                         &min_width,
 | 
			
		||||
                                         &natural_width);
 | 
			
		||||
 | 
			
		||||
      child_width = CLAMP (natural_width, min_width, available_width);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_get_preferred_height (child, child_width,
 | 
			
		||||
                                          &min_height,
 | 
			
		||||
                                          &natural_height);
 | 
			
		||||
 | 
			
		||||
      child_height = CLAMP (natural_height, min_height, available_height);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (child, available_width,
 | 
			
		||||
                                          &min_height,
 | 
			
		||||
                                          &natural_height);
 | 
			
		||||
 | 
			
		||||
      child_height = CLAMP (natural_height, min_height, available_height);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_get_preferred_width (child, child_height,
 | 
			
		||||
                                         &min_width,
 | 
			
		||||
                                         &natural_width);
 | 
			
		||||
 | 
			
		||||
      child_width = CLAMP (natural_width, min_width, available_width);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!x_fill)
 | 
			
		||||
    {
 | 
			
		||||
      allocation.x1 = childbox->x1 + (int) ((available_width - child_width) * x_align);
 | 
			
		||||
      allocation.x2 = allocation.x1 + (int) child_width;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!y_fill)
 | 
			
		||||
    {
 | 
			
		||||
      allocation.y1 = childbox->y1 + (int) ((available_height - child_height) * y_align);
 | 
			
		||||
      allocation.y2 = allocation.y1 + (int) child_height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *childbox = allocation;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/nbtk/nbtk-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/nbtk/nbtk-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-private.h: Private declarations
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_PRIVATE_H__
 | 
			
		||||
#define __NBTK_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include "nbtk-widget.h"
 | 
			
		||||
#include "nbtk-bin.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define I_(str)         (g_intern_static_string ((str)))
 | 
			
		||||
 | 
			
		||||
#define NBTK_PARAM_READABLE     \
 | 
			
		||||
        (G_PARAM_READABLE |     \
 | 
			
		||||
         G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
 | 
			
		||||
 | 
			
		||||
#define NBTK_PARAM_READWRITE    \
 | 
			
		||||
        (G_PARAM_READABLE | G_PARAM_WRITABLE | \
 | 
			
		||||
         G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
ClutterActor *_nbtk_widget_get_dnd_clone (NbtkWidget *widget);
 | 
			
		||||
void _nbtk_bin_get_align_factors (NbtkBin *bin, gdouble *x_align, gdouble *y_align);
 | 
			
		||||
 | 
			
		||||
void _nbtk_allocate_fill (ClutterActor *child, ClutterActorBox *childbox, NbtkAlign x_align, NbtkAlign y_align, gboolean x_fill, gboolean y_fill);
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										1065
									
								
								src/nbtk/nbtk-scroll-bar.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1065
									
								
								src/nbtk/nbtk-scroll-bar.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										81
									
								
								src/nbtk/nbtk-scroll-bar.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/nbtk/nbtk-scroll-bar.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-scroll-bar.h: Scroll bar actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_SCROLL_BAR_H__
 | 
			
		||||
#define __NBTK_SCROLL_BAR_H__
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-adjustment.h>
 | 
			
		||||
#include <nbtk/nbtk-bin.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_SCROLL_BAR            (nbtk_scroll_bar_get_type())
 | 
			
		||||
#define NBTK_SCROLL_BAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SCROLL_BAR, NbtkScrollBar))
 | 
			
		||||
#define NBTK_IS_SCROLL_BAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SCROLL_BAR))
 | 
			
		||||
#define NBTK_SCROLL_BAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_SCROLL_BAR, NbtkScrollBarClass))
 | 
			
		||||
#define NBTK_IS_SCROLL_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_SCROLL_BAR))
 | 
			
		||||
#define NBTK_SCROLL_BAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_SCROLL_BAR, NbtkScrollBarClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkScrollBar          NbtkScrollBar;
 | 
			
		||||
typedef struct _NbtkScrollBarPrivate   NbtkScrollBarPrivate;
 | 
			
		||||
typedef struct _NbtkScrollBarClass     NbtkScrollBarClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkScrollBar:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkScrollBar
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkBin parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkScrollBarPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkScrollBarClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* signals */
 | 
			
		||||
  void (*scroll_start) (NbtkScrollBar *bar);
 | 
			
		||||
  void (*scroll_stop)  (NbtkScrollBar *bar);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_scroll_bar_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkWidget *    nbtk_scroll_bar_new            (NbtkAdjustment *adjustment);
 | 
			
		||||
void            nbtk_scroll_bar_set_adjustment (NbtkScrollBar  *bar,
 | 
			
		||||
                                                NbtkAdjustment *adjustment);
 | 
			
		||||
NbtkAdjustment *nbtk_scroll_bar_get_adjustment (NbtkScrollBar  *bar);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_SCROLL_BAR_H__ */
 | 
			
		||||
							
								
								
									
										829
									
								
								src/nbtk/nbtk-scroll-view.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										829
									
								
								src/nbtk/nbtk-scroll-view.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,829 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-scroll-view.h: Container with scroll-bars
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "nbtk-scroll-view.h"
 | 
			
		||||
#include "nbtk-marshal.h"
 | 
			
		||||
#include "nbtk-scroll-bar.h"
 | 
			
		||||
#include "nbtk-scrollable.h"
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
 | 
			
		||||
 | 
			
		||||
static ClutterContainerIface *nbtk_scroll_view_parent_iface = NULL;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (NbtkScrollView, nbtk_scroll_view, NBTK_TYPE_BIN,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
 | 
			
		||||
                                                clutter_container_iface_init))
 | 
			
		||||
 | 
			
		||||
#define SCROLL_VIEW_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
 | 
			
		||||
                                NBTK_TYPE_SCROLL_VIEW, \
 | 
			
		||||
                                NbtkScrollViewPrivate))
 | 
			
		||||
 | 
			
		||||
/* Default width (or height - the narrow dimension) for the scrollbars*/
 | 
			
		||||
#define DEFAULT_SCROLLBAR_WIDTH 24
 | 
			
		||||
 | 
			
		||||
struct _NbtkScrollViewPrivate
 | 
			
		||||
{
 | 
			
		||||
  /* a pointer to the child; this is actually stored
 | 
			
		||||
   * inside NbtkBin:child, but we keep it to avoid
 | 
			
		||||
   * calling nbtk_bin_get_child() every time we need it
 | 
			
		||||
   */
 | 
			
		||||
  ClutterActor   *child;
 | 
			
		||||
 | 
			
		||||
  ClutterActor   *hscroll;
 | 
			
		||||
  ClutterActor   *vscroll;
 | 
			
		||||
 | 
			
		||||
  gfloat          row_size;
 | 
			
		||||
  gfloat          column_size;
 | 
			
		||||
 | 
			
		||||
  gboolean        row_size_set : 1;
 | 
			
		||||
  gboolean        column_size_set : 1;
 | 
			
		||||
  guint           mouse_scroll : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_HSCROLL,
 | 
			
		||||
  PROP_VSCROLL,
 | 
			
		||||
  PROP_MOUSE_SCROLL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_get_property (GObject *object, guint property_id,
 | 
			
		||||
                                 GValue *value, GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = ((NbtkScrollView *)object)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_HSCROLL :
 | 
			
		||||
      g_value_set_object (value, priv->hscroll);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_VSCROLL :
 | 
			
		||||
      g_value_set_object (value, priv->vscroll);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_MOUSE_SCROLL:
 | 
			
		||||
      g_value_set_boolean (value, priv->mouse_scroll);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_set_property (GObject *object, guint property_id,
 | 
			
		||||
                                 const GValue *value, GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_MOUSE_SCROLL:
 | 
			
		||||
      nbtk_scroll_view_set_mouse_scrolling ((NbtkScrollView *) object,
 | 
			
		||||
                                         g_value_get_boolean (value));
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (object)->priv;
 | 
			
		||||
 | 
			
		||||
  priv->child = NULL;
 | 
			
		||||
 | 
			
		||||
  if (priv->vscroll)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_unparent (priv->vscroll);
 | 
			
		||||
      priv->vscroll = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->hscroll)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_unparent (priv->hscroll);
 | 
			
		||||
      priv->hscroll = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_scroll_view_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_scroll_view_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
 | 
			
		||||
 | 
			
		||||
  /* NbtkBin will paint the child */
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_scroll_view_parent_class)->paint (actor);
 | 
			
		||||
 | 
			
		||||
  /* paint our custom children */
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
 | 
			
		||||
    clutter_actor_paint (priv->hscroll);
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
 | 
			
		||||
    clutter_actor_paint (priv->vscroll);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_pick (ClutterActor *actor, const ClutterColor *color)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
 | 
			
		||||
 | 
			
		||||
  /* Chain up so we get a bounding box pained (if we are reactive) */
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_scroll_view_parent_class)->pick (actor, color);
 | 
			
		||||
 | 
			
		||||
  /* paint our custom children */
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
 | 
			
		||||
    clutter_actor_paint (priv->hscroll);
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
 | 
			
		||||
    clutter_actor_paint (priv->vscroll);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static double
 | 
			
		||||
get_scrollbar_width (NbtkScrollView *scroll_view)
 | 
			
		||||
{
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (scroll_view));
 | 
			
		||||
  double result = DEFAULT_SCROLLBAR_WIDTH;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_length (theme_node, "scrollbar-width", FALSE, &result);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static double
 | 
			
		||||
get_scrollbar_height (NbtkScrollView *scroll_view)
 | 
			
		||||
{
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (scroll_view));
 | 
			
		||||
  double result = DEFAULT_SCROLLBAR_WIDTH;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_length (theme_node, "scrollbar-height", FALSE, &result);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_get_preferred_width (ClutterActor *actor,
 | 
			
		||||
                                      gfloat        for_height,
 | 
			
		||||
                                      gfloat       *min_width_p,
 | 
			
		||||
                                      gfloat       *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
 | 
			
		||||
  if (!priv->child)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_height (theme_node, &for_height);
 | 
			
		||||
 | 
			
		||||
  /* Our natural width is the natural width of the child */
 | 
			
		||||
  clutter_actor_get_preferred_width (priv->child,
 | 
			
		||||
                                     for_height,
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     natural_width_p);
 | 
			
		||||
 | 
			
		||||
  /* Add space for the scroll-bar if we can determine it will be necessary */
 | 
			
		||||
  if ((for_height >= 0) && natural_width_p)
 | 
			
		||||
    {
 | 
			
		||||
      gfloat natural_height;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->child, -1.0,
 | 
			
		||||
                                          NULL,
 | 
			
		||||
                                          &natural_height);
 | 
			
		||||
      if (for_height < natural_height)
 | 
			
		||||
        *natural_width_p += get_scrollbar_width (NBTK_SCROLL_VIEW (actor));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (min_width_p)
 | 
			
		||||
    *min_width_p = 0;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_get_preferred_height (ClutterActor *actor,
 | 
			
		||||
                                       gfloat        for_width,
 | 
			
		||||
                                       gfloat       *min_height_p,
 | 
			
		||||
                                       gfloat       *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
 | 
			
		||||
  if (!priv->child)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_width (theme_node, &for_width);
 | 
			
		||||
 | 
			
		||||
  /* Our natural height is the natural height of the child */
 | 
			
		||||
  clutter_actor_get_preferred_height (priv->child,
 | 
			
		||||
                                      for_width,
 | 
			
		||||
                                      NULL,
 | 
			
		||||
                                      natural_height_p);
 | 
			
		||||
 | 
			
		||||
  /* Add space for the scroll-bar if we can determine it will be necessary */
 | 
			
		||||
  if ((for_width >= 0) && natural_height_p)
 | 
			
		||||
    {
 | 
			
		||||
      gfloat natural_width;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->child, -1.0,
 | 
			
		||||
                                         NULL,
 | 
			
		||||
                                         &natural_width);
 | 
			
		||||
      if (for_width < natural_width)
 | 
			
		||||
        *natural_height_p += get_scrollbar_height (NBTK_SCROLL_VIEW (actor));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (min_height_p)
 | 
			
		||||
    *min_height_p = 0;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_allocate (ClutterActor          *actor,
 | 
			
		||||
                           const ClutterActorBox *box,
 | 
			
		||||
                           ClutterAllocationFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorBox content_box, child_box;
 | 
			
		||||
  ClutterActorClass *parent_parent_class;
 | 
			
		||||
  gfloat avail_width, avail_height, sb_width, sb_height;
 | 
			
		||||
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (actor)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (actor));
 | 
			
		||||
 | 
			
		||||
  /* Chain up to the parent's parent class
 | 
			
		||||
   *
 | 
			
		||||
   * We do this because we do not want NbtkBin to allocate the child, as we
 | 
			
		||||
   * give it a different allocation later, depending on whether the scrollbars
 | 
			
		||||
   * are visible
 | 
			
		||||
   */
 | 
			
		||||
  parent_parent_class
 | 
			
		||||
    = g_type_class_peek_parent (nbtk_scroll_view_parent_class);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (parent_parent_class)->
 | 
			
		||||
    allocate (actor, box, flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_content_box (theme_node, box, &content_box);
 | 
			
		||||
 | 
			
		||||
  avail_width = content_box.x2 - content_box.x1;
 | 
			
		||||
  avail_height = content_box.y2 - content_box.y1;
 | 
			
		||||
 | 
			
		||||
  sb_width = get_scrollbar_width (NBTK_SCROLL_VIEW (actor));
 | 
			
		||||
  sb_height = get_scrollbar_width (NBTK_SCROLL_VIEW (actor));
 | 
			
		||||
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
 | 
			
		||||
    sb_width = 0;
 | 
			
		||||
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
 | 
			
		||||
    sb_height = 0;
 | 
			
		||||
 | 
			
		||||
  /* Vertical scrollbar */
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
 | 
			
		||||
    {
 | 
			
		||||
      child_box.x1 = content_box.x2 - sb_width;
 | 
			
		||||
      child_box.y1 = content_box.y1;
 | 
			
		||||
      child_box.x2 = content_box.x2;
 | 
			
		||||
      child_box.y2 = content_box.y2 - sb_height;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (priv->vscroll, &child_box, flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Horizontal scrollbar */
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
 | 
			
		||||
    {
 | 
			
		||||
      child_box.x1 = content_box.x1;
 | 
			
		||||
      child_box.y1 = content_box.y2 - sb_height;
 | 
			
		||||
      child_box.x2 = content_box.x2 - sb_width;
 | 
			
		||||
      child_box.y2 = content_box.y2;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (priv->hscroll, &child_box, flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* Child */
 | 
			
		||||
  child_box.x1 = content_box.x1;
 | 
			
		||||
  child_box.y1 = content_box.y1;
 | 
			
		||||
  child_box.x2 = content_box.x2 - sb_width;
 | 
			
		||||
  child_box.y2 = content_box.y2 - sb_height;
 | 
			
		||||
 | 
			
		||||
  if (priv->child)
 | 
			
		||||
      clutter_actor_allocate (priv->child, &child_box, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_style_changed (NbtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (widget)->priv;
 | 
			
		||||
 | 
			
		||||
  nbtk_widget_style_changed (NBTK_WIDGET (priv->hscroll));
 | 
			
		||||
  nbtk_widget_style_changed (NBTK_WIDGET (priv->vscroll));
 | 
			
		||||
 | 
			
		||||
  NBTK_WIDGET_CLASS (nbtk_scroll_view_parent_class)->style_changed (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
nbtk_scroll_view_scroll_event (ClutterActor        *self,
 | 
			
		||||
                               ClutterScrollEvent  *event)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (self)->priv;
 | 
			
		||||
  gdouble lower, value, upper, step;
 | 
			
		||||
  NbtkAdjustment *vadjustment, *hadjustment;
 | 
			
		||||
 | 
			
		||||
  /* don't handle scroll events if requested not to */
 | 
			
		||||
  if (!priv->mouse_scroll)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  hadjustment = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->hscroll));
 | 
			
		||||
  vadjustment = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->vscroll));
 | 
			
		||||
 | 
			
		||||
  switch (event->direction)
 | 
			
		||||
    {
 | 
			
		||||
      case CLUTTER_SCROLL_UP:
 | 
			
		||||
      case CLUTTER_SCROLL_DOWN:
 | 
			
		||||
        if (vadjustment)
 | 
			
		||||
          g_object_get (vadjustment,
 | 
			
		||||
                        "lower", &lower,
 | 
			
		||||
                        "step-increment", &step,
 | 
			
		||||
                        "value", &value,
 | 
			
		||||
                        "upper", &upper,
 | 
			
		||||
                        NULL);
 | 
			
		||||
        else
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        break;
 | 
			
		||||
      case CLUTTER_SCROLL_LEFT:
 | 
			
		||||
      case CLUTTER_SCROLL_RIGHT:
 | 
			
		||||
        if (vadjustment)
 | 
			
		||||
          g_object_get (hadjustment,
 | 
			
		||||
                        "lower", &lower,
 | 
			
		||||
                        "step-increment", &step,
 | 
			
		||||
                        "value", &value,
 | 
			
		||||
                        "upper", &upper,
 | 
			
		||||
                        NULL);
 | 
			
		||||
          else
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  switch (event->direction)
 | 
			
		||||
    {
 | 
			
		||||
      case CLUTTER_SCROLL_UP:
 | 
			
		||||
        if (value == lower)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        else
 | 
			
		||||
          nbtk_adjustment_set_value (vadjustment, value - step);
 | 
			
		||||
        break;
 | 
			
		||||
      case CLUTTER_SCROLL_DOWN:
 | 
			
		||||
        if (value == upper)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        else
 | 
			
		||||
          nbtk_adjustment_set_value (vadjustment, value + step);
 | 
			
		||||
        break;
 | 
			
		||||
      case CLUTTER_SCROLL_LEFT:
 | 
			
		||||
        if (value == lower)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        else
 | 
			
		||||
          nbtk_adjustment_set_value (hadjustment, value - step);
 | 
			
		||||
        break;
 | 
			
		||||
      case CLUTTER_SCROLL_RIGHT:
 | 
			
		||||
        if (value == upper)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        else
 | 
			
		||||
          nbtk_adjustment_set_value (hadjustment, value + step);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_class_init (NbtkScrollViewClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkScrollViewPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = nbtk_scroll_view_get_property;
 | 
			
		||||
  object_class->set_property = nbtk_scroll_view_set_property;
 | 
			
		||||
  object_class->dispose= nbtk_scroll_view_dispose;
 | 
			
		||||
  object_class->finalize = nbtk_scroll_view_finalize;
 | 
			
		||||
 | 
			
		||||
  actor_class->paint = nbtk_scroll_view_paint;
 | 
			
		||||
  actor_class->pick = nbtk_scroll_view_pick;
 | 
			
		||||
  actor_class->get_preferred_width = nbtk_scroll_view_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = nbtk_scroll_view_get_preferred_height;
 | 
			
		||||
  actor_class->allocate = nbtk_scroll_view_allocate;
 | 
			
		||||
  actor_class->scroll_event = nbtk_scroll_view_scroll_event;
 | 
			
		||||
 | 
			
		||||
  widget_class->style_changed = nbtk_scroll_view_style_changed;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_HSCROLL,
 | 
			
		||||
                                   g_param_spec_object ("hscroll",
 | 
			
		||||
                                                        "NbtkScrollBar",
 | 
			
		||||
                                                        "Horizontal scroll indicator",
 | 
			
		||||
                                                        NBTK_TYPE_SCROLL_BAR,
 | 
			
		||||
                                                        G_PARAM_READABLE));
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_VSCROLL,
 | 
			
		||||
                                   g_param_spec_object ("vscroll",
 | 
			
		||||
                                                       "NbtkScrollBar",
 | 
			
		||||
                                                       "Vertical scroll indicator",
 | 
			
		||||
                                                       NBTK_TYPE_SCROLL_BAR,
 | 
			
		||||
                                                       G_PARAM_READABLE));
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("enable-mouse-scrolling",
 | 
			
		||||
                                "Enable Mouse Scrolling",
 | 
			
		||||
                                "Enable automatic mouse wheel scrolling",
 | 
			
		||||
                                TRUE,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_MOUSE_SCROLL,
 | 
			
		||||
                                   pspec);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
child_adjustment_changed_cb (NbtkAdjustment *adjustment,
 | 
			
		||||
                             ClutterActor   *bar)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollView *scroll;
 | 
			
		||||
  gdouble lower, upper, page_size;
 | 
			
		||||
 | 
			
		||||
  scroll = NBTK_SCROLL_VIEW (clutter_actor_get_parent (bar));
 | 
			
		||||
 | 
			
		||||
  /* Determine if this scroll-bar should be visible */
 | 
			
		||||
  nbtk_adjustment_get_values (adjustment, NULL,
 | 
			
		||||
                              &lower, &upper,
 | 
			
		||||
                              NULL, NULL,
 | 
			
		||||
                              &page_size);
 | 
			
		||||
 | 
			
		||||
  if ((upper - lower) > page_size)
 | 
			
		||||
    clutter_actor_show (bar);
 | 
			
		||||
  else
 | 
			
		||||
    clutter_actor_hide (bar);
 | 
			
		||||
 | 
			
		||||
  /* Request a resize */
 | 
			
		||||
  clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
child_hadjustment_notify_cb (GObject *gobject,
 | 
			
		||||
                             GParamSpec *arg1,
 | 
			
		||||
                             gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment *hadjust;
 | 
			
		||||
 | 
			
		||||
  ClutterActor *actor = CLUTTER_ACTOR (gobject);
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (user_data)->priv;
 | 
			
		||||
 | 
			
		||||
  hadjust = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->hscroll));
 | 
			
		||||
  if (hadjust)
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (hadjust,
 | 
			
		||||
                                          child_adjustment_changed_cb,
 | 
			
		||||
                                          priv->hscroll);
 | 
			
		||||
 | 
			
		||||
  nbtk_scrollable_get_adjustments (NBTK_SCROLLABLE (actor), &hadjust, NULL);
 | 
			
		||||
  if (hadjust)
 | 
			
		||||
    {
 | 
			
		||||
      /* Force scroll step if neede. */
 | 
			
		||||
      if (priv->column_size_set)
 | 
			
		||||
        {
 | 
			
		||||
          g_object_set (hadjust,
 | 
			
		||||
                        "step-increment", priv->column_size,
 | 
			
		||||
                        NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      nbtk_scroll_bar_set_adjustment (NBTK_SCROLL_BAR(priv->hscroll), hadjust);
 | 
			
		||||
      g_signal_connect (hadjust, "changed", G_CALLBACK (
 | 
			
		||||
                        child_adjustment_changed_cb), priv->hscroll);
 | 
			
		||||
      child_adjustment_changed_cb (hadjust, priv->hscroll);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
child_vadjustment_notify_cb (GObject *gobject,
 | 
			
		||||
                             GParamSpec *arg1,
 | 
			
		||||
                             gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment *vadjust;
 | 
			
		||||
 | 
			
		||||
  ClutterActor *actor = CLUTTER_ACTOR (gobject);
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (user_data)->priv;
 | 
			
		||||
 | 
			
		||||
  vadjust = nbtk_scroll_bar_get_adjustment (NBTK_SCROLL_BAR(priv->vscroll));
 | 
			
		||||
  if (vadjust)
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (vadjust,
 | 
			
		||||
                                          child_adjustment_changed_cb,
 | 
			
		||||
                                          priv->vscroll);
 | 
			
		||||
 | 
			
		||||
  nbtk_scrollable_get_adjustments (NBTK_SCROLLABLE(actor), NULL, &vadjust);
 | 
			
		||||
  if (vadjust)
 | 
			
		||||
    {
 | 
			
		||||
      /* Force scroll step if neede. */
 | 
			
		||||
      if (priv->row_size_set)
 | 
			
		||||
        {
 | 
			
		||||
          g_object_set (vadjust,
 | 
			
		||||
                        "step-increment", priv->row_size,
 | 
			
		||||
                        NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      nbtk_scroll_bar_set_adjustment (NBTK_SCROLL_BAR(priv->vscroll), vadjust);
 | 
			
		||||
      g_signal_connect (vadjust, "changed", G_CALLBACK (
 | 
			
		||||
                        child_adjustment_changed_cb), priv->vscroll);
 | 
			
		||||
      child_adjustment_changed_cb (vadjust, priv->vscroll);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_init (NbtkScrollView *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = self->priv = SCROLL_VIEW_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  priv->hscroll = CLUTTER_ACTOR (nbtk_scroll_bar_new (NULL));
 | 
			
		||||
  priv->vscroll = g_object_new (NBTK_TYPE_SCROLL_BAR, "vertical", TRUE, NULL);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_parent (priv->hscroll, CLUTTER_ACTOR (self));
 | 
			
		||||
  clutter_actor_set_parent (priv->vscroll, CLUTTER_ACTOR (self));
 | 
			
		||||
 | 
			
		||||
  /* mouse scroll is enabled by default, so we also need to be reactive */
 | 
			
		||||
  priv->mouse_scroll = TRUE;
 | 
			
		||||
  g_object_set (G_OBJECT (self), "reactive", TRUE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_add (ClutterContainer *container,
 | 
			
		||||
                      ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollView *self = NBTK_SCROLL_VIEW (container);
 | 
			
		||||
  NbtkScrollViewPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  if (NBTK_IS_SCROLLABLE (actor))
 | 
			
		||||
    {
 | 
			
		||||
      priv->child = actor;
 | 
			
		||||
 | 
			
		||||
      /* chain up to NbtkBin::add() */
 | 
			
		||||
      nbtk_scroll_view_parent_iface->add (container, actor);
 | 
			
		||||
 | 
			
		||||
      /* Get adjustments for scroll-bars */
 | 
			
		||||
      g_signal_connect (actor, "notify::hadjustment",
 | 
			
		||||
                        G_CALLBACK (child_hadjustment_notify_cb),
 | 
			
		||||
                        container);
 | 
			
		||||
      g_signal_connect (actor, "notify::vadjustment",
 | 
			
		||||
                        G_CALLBACK (child_vadjustment_notify_cb),
 | 
			
		||||
                        container);
 | 
			
		||||
      child_hadjustment_notify_cb (G_OBJECT (actor), NULL, container);
 | 
			
		||||
      child_vadjustment_notify_cb (G_OBJECT (actor), NULL, container);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Attempting to add an actor of type %s to "
 | 
			
		||||
                 "a NbtkScrollView, but the actor does "
 | 
			
		||||
                 "not implement NbtkScrollable.",
 | 
			
		||||
                 g_type_name (G_OBJECT_TYPE (actor)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_remove (ClutterContainer *container,
 | 
			
		||||
                         ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (container)->priv;
 | 
			
		||||
 | 
			
		||||
  if (actor == priv->child)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_ref (priv->child);
 | 
			
		||||
 | 
			
		||||
      /* chain up to NbtkBin::remove() */
 | 
			
		||||
      nbtk_scroll_view_parent_iface->remove (container, actor);
 | 
			
		||||
 | 
			
		||||
      g_signal_handlers_disconnect_by_func (priv->child,
 | 
			
		||||
                                            child_hadjustment_notify_cb,
 | 
			
		||||
                                            container);
 | 
			
		||||
      g_signal_handlers_disconnect_by_func (priv->child,
 | 
			
		||||
                                            child_vadjustment_notify_cb,
 | 
			
		||||
                                            container);
 | 
			
		||||
      nbtk_scrollable_set_adjustments ((NbtkScrollable*) priv->child, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
      g_object_unref (priv->child);
 | 
			
		||||
      priv->child = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scroll_view_foreach_with_internals (ClutterContainer *container,
 | 
			
		||||
                                         ClutterCallback   callback,
 | 
			
		||||
                                         gpointer          user_data)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv = NBTK_SCROLL_VIEW (container)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->child != NULL)
 | 
			
		||||
    callback (priv->child, user_data);
 | 
			
		||||
 | 
			
		||||
  if (priv->hscroll != NULL)
 | 
			
		||||
    callback (priv->hscroll, user_data);
 | 
			
		||||
 | 
			
		||||
  if (priv->vscroll != NULL)
 | 
			
		||||
    callback (priv->vscroll, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_container_iface_init (ClutterContainerIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  /* store a pointer to the NbtkBin implementation of
 | 
			
		||||
   * ClutterContainer so that we can chain up when
 | 
			
		||||
   * overriding the methods
 | 
			
		||||
   */
 | 
			
		||||
  nbtk_scroll_view_parent_iface = g_type_interface_peek_parent (iface);
 | 
			
		||||
 | 
			
		||||
  iface->add = nbtk_scroll_view_add;
 | 
			
		||||
  iface->remove = nbtk_scroll_view_remove;
 | 
			
		||||
  iface->foreach_with_internals = nbtk_scroll_view_foreach_with_internals;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkWidget *
 | 
			
		||||
nbtk_scroll_view_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (NBTK_TYPE_SCROLL_VIEW, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_scroll_view_get_hscroll_bar:
 | 
			
		||||
 * @scroll: a #NbtkScrollView
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the horizontal scrollbar of the scrollbiew
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the horizontal #NbtkScrollbar
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor *
 | 
			
		||||
nbtk_scroll_view_get_hscroll_bar (NbtkScrollView *scroll)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_SCROLL_VIEW (scroll), NULL);
 | 
			
		||||
 | 
			
		||||
  return scroll->priv->hscroll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_scroll_view_get_vscroll_bar:
 | 
			
		||||
 * @scroll: a #NbtkScrollView
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the vertical scrollbar of the scrollbiew
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the vertical #NbtkScrollbar
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor *
 | 
			
		||||
nbtk_scroll_view_get_vscroll_bar (NbtkScrollView *scroll)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_SCROLL_VIEW (scroll), NULL);
 | 
			
		||||
 | 
			
		||||
  return scroll->priv->vscroll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gfloat
 | 
			
		||||
nbtk_scroll_view_get_column_size (NbtkScrollView *scroll)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment  *adjustment;
 | 
			
		||||
  gdouble          column_size;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (scroll, 0);
 | 
			
		||||
 | 
			
		||||
  adjustment = nbtk_scroll_bar_get_adjustment (
 | 
			
		||||
                NBTK_SCROLL_BAR (scroll->priv->hscroll));
 | 
			
		||||
  g_object_get (adjustment,
 | 
			
		||||
                "step-increment", &column_size,
 | 
			
		||||
                NULL);
 | 
			
		||||
 | 
			
		||||
  return column_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_scroll_view_set_column_size (NbtkScrollView *scroll,
 | 
			
		||||
                                  gfloat          column_size)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment  *adjustment;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (scroll);
 | 
			
		||||
 | 
			
		||||
  if (column_size < 0)
 | 
			
		||||
    {
 | 
			
		||||
      scroll->priv->column_size_set = FALSE;
 | 
			
		||||
      scroll->priv->column_size = -1;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      scroll->priv->column_size_set = TRUE;
 | 
			
		||||
      scroll->priv->column_size = column_size;
 | 
			
		||||
 | 
			
		||||
      adjustment = nbtk_scroll_bar_get_adjustment (
 | 
			
		||||
                    NBTK_SCROLL_BAR (scroll->priv->hscroll));
 | 
			
		||||
 | 
			
		||||
      if (adjustment)
 | 
			
		||||
        g_object_set (adjustment,
 | 
			
		||||
                      "step-increment", (gdouble) scroll->priv->column_size,
 | 
			
		||||
                      NULL);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gfloat
 | 
			
		||||
nbtk_scroll_view_get_row_size (NbtkScrollView *scroll)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment  *adjustment;
 | 
			
		||||
  gdouble row_size;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (scroll, 0);
 | 
			
		||||
 | 
			
		||||
  adjustment = nbtk_scroll_bar_get_adjustment (
 | 
			
		||||
                NBTK_SCROLL_BAR (scroll->priv->vscroll));
 | 
			
		||||
  g_object_get (adjustment,
 | 
			
		||||
                "step-increment", &row_size,
 | 
			
		||||
                NULL);
 | 
			
		||||
 | 
			
		||||
  return row_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_scroll_view_set_row_size (NbtkScrollView *scroll,
 | 
			
		||||
                               gfloat          row_size)
 | 
			
		||||
{
 | 
			
		||||
  NbtkAdjustment  *adjustment;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (scroll);
 | 
			
		||||
 | 
			
		||||
  if (row_size < 0)
 | 
			
		||||
    {
 | 
			
		||||
      scroll->priv->row_size_set = FALSE;
 | 
			
		||||
      scroll->priv->row_size = -1;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      scroll->priv->row_size_set = TRUE;
 | 
			
		||||
      scroll->priv->row_size = row_size;
 | 
			
		||||
 | 
			
		||||
      adjustment = nbtk_scroll_bar_get_adjustment (
 | 
			
		||||
                    NBTK_SCROLL_BAR (scroll->priv->vscroll));
 | 
			
		||||
 | 
			
		||||
      if (adjustment)
 | 
			
		||||
        g_object_set (adjustment,
 | 
			
		||||
                      "step-increment", (gdouble) scroll->priv->row_size,
 | 
			
		||||
                      NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_scroll_view_set_mouse_scrolling (NbtkScrollView *scroll,
 | 
			
		||||
                                      gboolean        enabled)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_SCROLL_VIEW (scroll));
 | 
			
		||||
 | 
			
		||||
  priv = NBTK_SCROLL_VIEW (scroll)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->mouse_scroll != enabled)
 | 
			
		||||
    {
 | 
			
		||||
      priv->mouse_scroll = enabled;
 | 
			
		||||
 | 
			
		||||
      /* make sure we can receive mouse wheel events */
 | 
			
		||||
      if (enabled)
 | 
			
		||||
        clutter_actor_set_reactive ((ClutterActor *) scroll, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
nbtk_scroll_view_get_mouse_scrolling (NbtkScrollView *scroll)
 | 
			
		||||
{
 | 
			
		||||
  NbtkScrollViewPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_SCROLL_VIEW (scroll), FALSE);
 | 
			
		||||
 | 
			
		||||
  priv = NBTK_SCROLL_VIEW (scroll)->priv;
 | 
			
		||||
 | 
			
		||||
  return priv->mouse_scroll;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								src/nbtk/nbtk-scroll-view.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/nbtk/nbtk-scroll-view.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-scroll-view.h: Container with scroll-bars
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_SCROLL_VIEW_H__
 | 
			
		||||
#define __NBTK_SCROLL_VIEW_H__
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-bin.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_SCROLL_VIEW            (nbtk_scroll_view_get_type())
 | 
			
		||||
#define NBTK_SCROLL_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SCROLL_VIEW, NbtkScrollView))
 | 
			
		||||
#define NBTK_IS_SCROLL_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SCROLL_VIEW))
 | 
			
		||||
#define NBTK_SCROLL_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_SCROLL_VIEW, NbtkScrollViewClass))
 | 
			
		||||
#define NBTK_IS_SCROLL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_SCROLL_VIEW))
 | 
			
		||||
#define NBTK_SCROLL_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_SCROLL_VIEW, NbtkScrollViewClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkScrollView          NbtkScrollView;
 | 
			
		||||
typedef struct _NbtkScrollViewPrivate   NbtkScrollViewPrivate;
 | 
			
		||||
typedef struct _NbtkScrollViewClass     NbtkScrollViewClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkScrollView:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkScrollView
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkBin parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkScrollViewPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkScrollViewClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_scroll_view_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
NbtkWidget *  nbtk_scroll_view_new             (void);
 | 
			
		||||
 | 
			
		||||
ClutterActor *  nbtk_scroll_view_get_hscroll_bar (NbtkScrollView *scroll);
 | 
			
		||||
ClutterActor *  nbtk_scroll_view_get_vscroll_bar (NbtkScrollView *scroll);
 | 
			
		||||
 | 
			
		||||
gfloat     nbtk_scroll_view_get_column_size (NbtkScrollView *scroll);
 | 
			
		||||
void            nbtk_scroll_view_set_column_size (NbtkScrollView *scroll,
 | 
			
		||||
                                                  gfloat          column_size);
 | 
			
		||||
 | 
			
		||||
gfloat     nbtk_scroll_view_get_row_size    (NbtkScrollView *scroll);
 | 
			
		||||
void            nbtk_scroll_view_set_row_size    (NbtkScrollView *scroll,
 | 
			
		||||
                                                  gfloat          row_size);
 | 
			
		||||
 | 
			
		||||
void nbtk_scroll_view_set_mouse_scrolling (NbtkScrollView *scroll, gboolean enabled);
 | 
			
		||||
gboolean nbtk_scroll_view_get_mouse_scrolling (NbtkScrollView *scroll);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_SCROLL_VIEW_H__ */
 | 
			
		||||
							
								
								
									
										96
									
								
								src/nbtk/nbtk-scrollable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/nbtk/nbtk-scrollable.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-scrollable.c: Scrollable interface
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "nbtk-scrollable.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_scrollable_base_init (gpointer g_iface)
 | 
			
		||||
{
 | 
			
		||||
  static gboolean initialized = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!initialized)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_interface_install_property (g_iface,
 | 
			
		||||
                                   g_param_spec_object ("hadjustment",
 | 
			
		||||
                                                        "NbtkAdjustment",
 | 
			
		||||
                                                        "Horizontal adjustment",
 | 
			
		||||
                                                        NBTK_TYPE_ADJUSTMENT,
 | 
			
		||||
                                                        G_PARAM_READWRITE));
 | 
			
		||||
 | 
			
		||||
      g_object_interface_install_property (g_iface,
 | 
			
		||||
                                   g_param_spec_object ("vadjustment",
 | 
			
		||||
                                                        "NbtkAdjustment",
 | 
			
		||||
                                                        "Vertical adjustment",
 | 
			
		||||
                                                        NBTK_TYPE_ADJUSTMENT,
 | 
			
		||||
                                                        G_PARAM_READWRITE));
 | 
			
		||||
 | 
			
		||||
      initialized = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
nbtk_scrollable_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType type = 0;
 | 
			
		||||
  if (type == 0)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo info =
 | 
			
		||||
        {
 | 
			
		||||
          sizeof (NbtkScrollableInterface),
 | 
			
		||||
          nbtk_scrollable_base_init,        /* base_init */
 | 
			
		||||
          NULL,
 | 
			
		||||
        };
 | 
			
		||||
      type = g_type_register_static (G_TYPE_INTERFACE,
 | 
			
		||||
                                     "NbtkScrollable", &info, 0);
 | 
			
		||||
    }
 | 
			
		||||
  return type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_scrollable_set_adjustments (NbtkScrollable *scrollable,
 | 
			
		||||
                                 NbtkAdjustment *hadjustment,
 | 
			
		||||
                                 NbtkAdjustment *vadjustment)
 | 
			
		||||
{
 | 
			
		||||
  NBTK_SCROLLABLE_GET_INTERFACE (scrollable)->set_adjustments (scrollable,
 | 
			
		||||
                                                               hadjustment,
 | 
			
		||||
                                                               vadjustment);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_scroll_bar_get_adjustments:
 | 
			
		||||
 * @hadjustment: (transfer none) (out) (allow-none): location to store the horizontal adjustment, or %NULL
 | 
			
		||||
 * @vadjustment: (transfer none) (out) (allow-none): location to store the vertical adjustment, or %NULL
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the adjustment objects that store the offsets of the scrollable widget
 | 
			
		||||
 * into its possible scrolling area.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_scrollable_get_adjustments (NbtkScrollable *scrollable,
 | 
			
		||||
                                 NbtkAdjustment **hadjustment,
 | 
			
		||||
                                 NbtkAdjustment **vadjustment)
 | 
			
		||||
{
 | 
			
		||||
  NBTK_SCROLLABLE_GET_INTERFACE (scrollable)->get_adjustments (scrollable,
 | 
			
		||||
                                                               hadjustment,
 | 
			
		||||
                                                               vadjustment);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/nbtk/nbtk-scrollable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/nbtk/nbtk-scrollable.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-scrollable.h: Scrollable interface
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Chris Lord <chris@openedhand.com>
 | 
			
		||||
 * Port to Nbtk by: Robert Staudinger <robsta@openedhand.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_SCROLLABLE_H__
 | 
			
		||||
#define __NBTK_SCROLLABLE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <nbtk/nbtk-adjustment.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_SCROLLABLE                (nbtk_scrollable_get_type ())
 | 
			
		||||
#define NBTK_SCROLLABLE(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SCROLLABLE, NbtkScrollable))
 | 
			
		||||
#define NBTK_IS_SCROLLABLE(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SCROLLABLE))
 | 
			
		||||
#define NBTK_SCROLLABLE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), NBTK_TYPE_SCROLLABLE, NbtkScrollableInterface))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkScrollable NbtkScrollable; /* Dummy object */
 | 
			
		||||
typedef struct _NbtkScrollableInterface NbtkScrollableInterface;
 | 
			
		||||
 | 
			
		||||
struct _NbtkScrollableInterface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface parent;
 | 
			
		||||
 | 
			
		||||
  void (* set_adjustments) (NbtkScrollable  *scrollable,
 | 
			
		||||
                            NbtkAdjustment  *hadjustment,
 | 
			
		||||
                            NbtkAdjustment  *vadjustment);
 | 
			
		||||
  void (* get_adjustments) (NbtkScrollable  *scrollable,
 | 
			
		||||
                            NbtkAdjustment **hadjustment,
 | 
			
		||||
                            NbtkAdjustment **vadjustment);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_scrollable_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void nbtk_scrollable_set_adjustments (NbtkScrollable  *scrollable,
 | 
			
		||||
                                      NbtkAdjustment  *hadjustment,
 | 
			
		||||
                                      NbtkAdjustment  *vadjustment);
 | 
			
		||||
void nbtk_scrollable_get_adjustments (NbtkScrollable  *scrollable,
 | 
			
		||||
                                      NbtkAdjustment **hadjustment,
 | 
			
		||||
                                      NbtkAdjustment **vadjustment);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_SCROLLABLE_H__ */
 | 
			
		||||
							
								
								
									
										575
									
								
								src/nbtk/nbtk-subtexture.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										575
									
								
								src/nbtk/nbtk-subtexture.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,575 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-subtexture.h: Class to wrap a texture and "subframe" it.
 | 
			
		||||
 * based on
 | 
			
		||||
 * nbtk-texture-frame.c: Expandible texture actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-subtexture.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_PARENT_TEXTURE,
 | 
			
		||||
 | 
			
		||||
  PROP_TOP,
 | 
			
		||||
  PROP_LEFT,
 | 
			
		||||
  PROP_WIDTH,
 | 
			
		||||
  PROP_HEIGHT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkSubtexture, nbtk_subtexture, CLUTTER_TYPE_ACTOR);
 | 
			
		||||
 | 
			
		||||
#define NBTK_SUBTEXTURE_GET_PRIVATE(obj)     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_SUBTEXTURE, NbtkSubtexturePrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkSubtexturePrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterTexture *parent_texture;
 | 
			
		||||
 | 
			
		||||
  int left;
 | 
			
		||||
  int top;
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
 | 
			
		||||
  CoglHandle material;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                                        gfloat   for_height,
 | 
			
		||||
                                        gfloat  *min_width_p,
 | 
			
		||||
                                        gfloat  *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (priv->parent_texture == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      if (min_width_p)
 | 
			
		||||
        *min_width_p = 0;
 | 
			
		||||
 | 
			
		||||
      if (natural_width_p)
 | 
			
		||||
        *natural_width_p = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
	if (min_width_p)
 | 
			
		||||
		*min_width_p = priv->width;
 | 
			
		||||
	if (natural_width_p)
 | 
			
		||||
		*natural_width_p = priv->width;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                                         gfloat   for_width,
 | 
			
		||||
                                         gfloat  *min_height_p,
 | 
			
		||||
                                         gfloat  *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (priv->parent_texture == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      if (min_height_p)
 | 
			
		||||
        *min_height_p = 0;
 | 
			
		||||
 | 
			
		||||
      if (natural_height_p)
 | 
			
		||||
        *natural_height_p = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
	if (min_height_p)
 | 
			
		||||
		*min_height_p = priv->height;
 | 
			
		||||
	if (natural_height_p)
 | 
			
		||||
		*natural_height_p = priv->height;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_realize (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->material != COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv->material = cogl_material_new ();
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_unrealize (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->material == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cogl_material_unref (priv->material);
 | 
			
		||||
  priv->material = COGL_INVALID_HANDLE;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_paint (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (self)->priv;
 | 
			
		||||
  CoglHandle cogl_texture = COGL_INVALID_HANDLE;
 | 
			
		||||
  ClutterActorBox box = { 0, 0, 0, 0 };
 | 
			
		||||
  gfloat tx1, ty1, tx2, ty2, tex_width, tex_height, width, height;
 | 
			
		||||
  guint8 opacity;
 | 
			
		||||
 | 
			
		||||
  /* no need to paint stuff if we don't have a texture */
 | 
			
		||||
  if (G_UNLIKELY (priv->parent_texture == NULL))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* parent texture may have been hidden, so need to make sure it gets
 | 
			
		||||
   * realized
 | 
			
		||||
   */
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture))
 | 
			
		||||
    clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture));
 | 
			
		||||
 | 
			
		||||
  cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
 | 
			
		||||
  if (cogl_texture == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tex_width  = cogl_texture_get_width (cogl_texture);
 | 
			
		||||
  tex_height = cogl_texture_get_height (cogl_texture);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_allocation_box (self, &box);
 | 
			
		||||
 | 
			
		||||
  width = box.x2 - box.x1;
 | 
			
		||||
  height = box.y2 - box.y1;
 | 
			
		||||
 | 
			
		||||
  tx1 = 1.0 *  priv->left / tex_width;
 | 
			
		||||
  ty1 = 1.0 * priv->top / tex_height;
 | 
			
		||||
 | 
			
		||||
  tx2 = 1.0 * (priv->left + priv->width) / tex_width;
 | 
			
		||||
  ty2 = 1.0 * (priv->top + priv->height) / tex_height;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  opacity = clutter_actor_get_paint_opacity (self);
 | 
			
		||||
 | 
			
		||||
  g_assert (priv->material != COGL_INVALID_HANDLE);
 | 
			
		||||
 | 
			
		||||
  /* set the source material using the parent texture's COGL handle */
 | 
			
		||||
  cogl_material_set_color4ub (priv->material, 255, 255, 255, opacity);
 | 
			
		||||
  cogl_material_set_layer (priv->material, 0, cogl_texture);
 | 
			
		||||
  cogl_set_source (priv->material);
 | 
			
		||||
 | 
			
		||||
  cogl_rectangle_with_texture_coords (0,0, (float)width, (float)height,
 | 
			
		||||
		tx1, ty1, tx2, ty2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
nbtk_subtexture_set_frame_internal (NbtkSubtexture *frame,
 | 
			
		||||
                                       int            left,
 | 
			
		||||
                                       int            top,
 | 
			
		||||
                                       int            width,
 | 
			
		||||
                                       int            height)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = frame->priv;
 | 
			
		||||
  GObject *gobject = G_OBJECT (frame);
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (gobject);
 | 
			
		||||
 | 
			
		||||
  if (priv->top != top)
 | 
			
		||||
    {
 | 
			
		||||
      priv->top = top;
 | 
			
		||||
      g_object_notify (gobject, "top");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->left != left)
 | 
			
		||||
    {
 | 
			
		||||
      priv->left = left;
 | 
			
		||||
      g_object_notify (gobject, "left");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->width != width)
 | 
			
		||||
    {
 | 
			
		||||
      priv->width = width;
 | 
			
		||||
      g_object_notify (gobject, "width");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->height != height)
 | 
			
		||||
    {
 | 
			
		||||
      priv->height = height;
 | 
			
		||||
      g_object_notify (gobject, "height");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (changed && CLUTTER_ACTOR_IS_VISIBLE (frame))
 | 
			
		||||
    clutter_actor_queue_redraw (CLUTTER_ACTOR (frame));
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_set_property (GObject      *gobject,
 | 
			
		||||
                                 guint         prop_id,
 | 
			
		||||
                                 const GValue *value,
 | 
			
		||||
                                 GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexture *frame = NBTK_SUBTEXTURE (gobject);
 | 
			
		||||
  NbtkSubtexturePrivate *priv = frame->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_PARENT_TEXTURE:
 | 
			
		||||
      nbtk_subtexture_set_parent_texture (frame,
 | 
			
		||||
                                             g_value_get_object (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TOP:
 | 
			
		||||
      nbtk_subtexture_set_frame_internal (frame,
 | 
			
		||||
                                             priv->left,
 | 
			
		||||
                                             g_value_get_int (value),
 | 
			
		||||
                                             priv->width,
 | 
			
		||||
                                             priv->height);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_LEFT:
 | 
			
		||||
      nbtk_subtexture_set_frame_internal (frame,
 | 
			
		||||
                                             g_value_get_int (value),
 | 
			
		||||
                                             priv->top,
 | 
			
		||||
                                             priv->width,
 | 
			
		||||
                                             priv->height);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_WIDTH:
 | 
			
		||||
      nbtk_subtexture_set_frame_internal (frame,
 | 
			
		||||
                                             priv->left,
 | 
			
		||||
                                             priv->top,
 | 
			
		||||
                                             g_value_get_int (value),
 | 
			
		||||
                                             priv->height);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_HEIGHT:
 | 
			
		||||
      nbtk_subtexture_set_frame_internal (frame,
 | 
			
		||||
                                             priv->left,
 | 
			
		||||
                                             priv->top,
 | 
			
		||||
                                             priv->width,
 | 
			
		||||
                                             g_value_get_int (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_get_property (GObject    *gobject,
 | 
			
		||||
                                 guint       prop_id,
 | 
			
		||||
                                 GValue     *value,
 | 
			
		||||
                                 GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_PARENT_TEXTURE:
 | 
			
		||||
      g_value_set_object (value, priv->parent_texture);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_LEFT:
 | 
			
		||||
      g_value_set_int (value, priv->left);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TOP:
 | 
			
		||||
      g_value_set_int (value, priv->top);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_WIDTH:
 | 
			
		||||
      g_value_set_int (value, priv->width);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_HEIGHT:
 | 
			
		||||
      g_value_set_int (value, priv->height);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_dispose (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv = NBTK_SUBTEXTURE (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->parent_texture)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (priv->parent_texture);
 | 
			
		||||
      priv->parent_texture = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->material)
 | 
			
		||||
    {
 | 
			
		||||
      cogl_material_unref (priv->material);
 | 
			
		||||
      priv->material = COGL_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_subtexture_parent_class)->dispose (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_class_init (NbtkSubtextureClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (gobject_class, sizeof (NbtkSubtexturePrivate));
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width =
 | 
			
		||||
    nbtk_subtexture_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height =
 | 
			
		||||
    nbtk_subtexture_get_preferred_height;
 | 
			
		||||
  actor_class->realize = nbtk_subtexture_realize;
 | 
			
		||||
  actor_class->unrealize = nbtk_subtexture_unrealize;
 | 
			
		||||
  actor_class->paint = nbtk_subtexture_paint;
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_subtexture_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_subtexture_get_property;
 | 
			
		||||
  gobject_class->dispose = nbtk_subtexture_dispose;
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_object ("parent-texture",
 | 
			
		||||
                               "Parent Texture",
 | 
			
		||||
                               "The parent ClutterTexture",
 | 
			
		||||
                               CLUTTER_TYPE_TEXTURE,
 | 
			
		||||
                               G_PARAM_READWRITE |
 | 
			
		||||
                               G_PARAM_CONSTRUCT);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_PARENT_TEXTURE, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_int ("left",
 | 
			
		||||
                              "Left",
 | 
			
		||||
                              "Left offset",
 | 
			
		||||
			      0, G_MAXINT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_LEFT, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_int ("top",
 | 
			
		||||
                              "Top",
 | 
			
		||||
                              "Top offset",
 | 
			
		||||
                              0, G_MAXINT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TOP, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_int ("width",
 | 
			
		||||
                              "Width",
 | 
			
		||||
                              "Width",
 | 
			
		||||
                              0, G_MAXINT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_WIDTH, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_int ("height",
 | 
			
		||||
                              "Height",
 | 
			
		||||
                              "Height",
 | 
			
		||||
                              0, G_MAXINT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_HEIGHT, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_subtexture_init (NbtkSubtexture *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  self->priv = priv = NBTK_SUBTEXTURE_GET_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  priv->material = COGL_INVALID_HANDLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_subtexture_new:
 | 
			
		||||
 * @texture: a #ClutterTexture or %NULL
 | 
			
		||||
 * @left: left
 | 
			
		||||
 * @top: top
 | 
			
		||||
 * @width: width
 | 
			
		||||
 * @height: height
 | 
			
		||||
 *
 | 
			
		||||
 * A #NbtkSubtexture is a specialized texture that efficiently clones
 | 
			
		||||
 * an area of the given @texture while keeping preserving portions of the
 | 
			
		||||
 * same texture.
 | 
			
		||||
 *
 | 
			
		||||
 * A #NbtkSubtexture can be used to make a rectangular texture fit a
 | 
			
		||||
 * given size without stretching its borders.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly created #NbtkSubtexture
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor*
 | 
			
		||||
nbtk_subtexture_new (ClutterTexture *texture,
 | 
			
		||||
			gint          left,
 | 
			
		||||
			gint          top,
 | 
			
		||||
			gint          width,
 | 
			
		||||
			gint          height)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL);
 | 
			
		||||
 | 
			
		||||
  return g_object_new (NBTK_TYPE_SUBTEXTURE,
 | 
			
		||||
		       "parent-texture", texture,
 | 
			
		||||
		       "top", top,
 | 
			
		||||
		       "left", left,
 | 
			
		||||
		       "width", width,
 | 
			
		||||
		       "height", height,
 | 
			
		||||
		       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_subtexture_get_parent_texture:
 | 
			
		||||
 * @frame: A #NbtkSubtexture
 | 
			
		||||
 *
 | 
			
		||||
 * Return the texture used by the #NbtkSubtexture
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): a #ClutterTexture owned by the #NbtkSubtexture
 | 
			
		||||
 */
 | 
			
		||||
ClutterTexture *
 | 
			
		||||
nbtk_subtexture_get_parent_texture (NbtkSubtexture *frame)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_SUBTEXTURE (frame), NULL);
 | 
			
		||||
 | 
			
		||||
  return frame->priv->parent_texture;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_subtexture_set_parent_texture:
 | 
			
		||||
 * @frame: A #NbtkSubtexture
 | 
			
		||||
 * @texture: A #ClutterTexture
 | 
			
		||||
 *
 | 
			
		||||
 * Set the #ClutterTexture used by this #NbtkSubtexture
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_subtexture_set_parent_texture (NbtkSubtexture *frame,
 | 
			
		||||
                                       ClutterTexture   *texture)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv;
 | 
			
		||||
  gboolean was_visible;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_SUBTEXTURE (frame));
 | 
			
		||||
  g_return_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture));
 | 
			
		||||
 | 
			
		||||
  priv = frame->priv;
 | 
			
		||||
 | 
			
		||||
  was_visible = CLUTTER_ACTOR_IS_VISIBLE (frame);
 | 
			
		||||
 | 
			
		||||
  if (priv->parent_texture == texture)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->parent_texture)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (priv->parent_texture);
 | 
			
		||||
      priv->parent_texture = NULL;
 | 
			
		||||
 | 
			
		||||
      if (was_visible)
 | 
			
		||||
        clutter_actor_hide (CLUTTER_ACTOR (frame));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (texture)
 | 
			
		||||
    {
 | 
			
		||||
      priv->parent_texture = g_object_ref (texture);
 | 
			
		||||
 | 
			
		||||
      if (was_visible && CLUTTER_ACTOR_IS_VISIBLE (priv->parent_texture))
 | 
			
		||||
        clutter_actor_show (CLUTTER_ACTOR (frame));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (frame), "parent-texture");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_subtexture_set_frame:
 | 
			
		||||
 * @frame: A #NbtkSubtexture
 | 
			
		||||
 * @left: left
 | 
			
		||||
 * @top: top
 | 
			
		||||
 * @width: width
 | 
			
		||||
 * @height: height
 | 
			
		||||
 *
 | 
			
		||||
 * Set the frame of the subtexture
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_subtexture_set_frame (NbtkSubtexture *frame,
 | 
			
		||||
                              gint            left,
 | 
			
		||||
                              gint            top,
 | 
			
		||||
                              gint            width,
 | 
			
		||||
                              gint            height)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (NBTK_IS_SUBTEXTURE (frame));
 | 
			
		||||
 | 
			
		||||
  nbtk_subtexture_set_frame_internal (frame, left, top, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_subtexture_get_frame:
 | 
			
		||||
 * @frame: A #NbtkSubtexture
 | 
			
		||||
 * @left: left
 | 
			
		||||
 * @top: top
 | 
			
		||||
 * @width: width
 | 
			
		||||
 * @height: height
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve the current frame.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_subtexture_get_frame (NbtkSubtexture *frame,
 | 
			
		||||
                              gint           *left,
 | 
			
		||||
                              gint           *top,
 | 
			
		||||
                              gint           *width,
 | 
			
		||||
                              gint           *height)
 | 
			
		||||
{
 | 
			
		||||
  NbtkSubtexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_SUBTEXTURE (frame));
 | 
			
		||||
 | 
			
		||||
  priv = frame->priv;
 | 
			
		||||
 | 
			
		||||
  if (top)
 | 
			
		||||
    *top = priv->top;
 | 
			
		||||
 | 
			
		||||
  if (left)
 | 
			
		||||
    *left = priv->left;
 | 
			
		||||
 | 
			
		||||
  if (width)
 | 
			
		||||
    *width = priv->width;
 | 
			
		||||
 | 
			
		||||
  if (height)
 | 
			
		||||
    *height = priv->height;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								src/nbtk/nbtk-subtexture.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/nbtk/nbtk-subtexture.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-subtexture.h: Class to wrap a texture and "subframe" it.
 | 
			
		||||
 *
 | 
			
		||||
 * Based on
 | 
			
		||||
 * nbtk-texture-frame.h: Expandible texture actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007, 2008 OpenedHand Ltd
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_SUBTEXTURE_H__
 | 
			
		||||
#define __NBTK_SUBTEXTURE_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_SUBTEXTURE                 (nbtk_subtexture_get_type ())
 | 
			
		||||
#define NBTK_SUBTEXTURE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_SUBTEXTURE, NbtkSubtexture))
 | 
			
		||||
#define NBTK_SUBTEXTURE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_SUBTEXTURE, NbtkSubtextureClass))
 | 
			
		||||
#define NBTK_IS_SUBTEXTURE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_SUBTEXTURE))
 | 
			
		||||
#define NBTK_IS_SUBTEXTURE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_SUBTEXTURE))
 | 
			
		||||
#define NBTK_SUBTEXTURE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_SUBTEXTURE, NbtkSubtextureClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkSubtexture                NbtkSubtexture;
 | 
			
		||||
typedef struct _NbtkSubtexturePrivate         NbtkSubtexturePrivate;
 | 
			
		||||
typedef struct _NbtkSubtextureClass           NbtkSubtextureClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkSubtexture:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkSubtexture
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActor parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkSubtexturePrivate    *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkSubtextureClass
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* padding for future expansion */
 | 
			
		||||
  void (*_nbtk_box_1) (void);
 | 
			
		||||
  void (*_nbtk_box_2) (void);
 | 
			
		||||
  void (*_nbtk_box_3) (void);
 | 
			
		||||
  void (*_nbtk_box_4) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType           nbtk_subtexture_get_type           (void) G_GNUC_CONST;
 | 
			
		||||
ClutterActor *  nbtk_subtexture_new                (ClutterTexture   *texture,
 | 
			
		||||
                                                       gint            top,
 | 
			
		||||
                                                       gint            left,
 | 
			
		||||
                                                       gint            width,
 | 
			
		||||
                                                       gint            height);
 | 
			
		||||
void            nbtk_subtexture_set_parent_texture (NbtkSubtexture *frame,
 | 
			
		||||
                                                       ClutterTexture   *texture);
 | 
			
		||||
ClutterTexture *nbtk_subtexture_get_parent_texture (NbtkSubtexture *frame);
 | 
			
		||||
void            nbtk_subtexture_set_frame          (NbtkSubtexture *frame,
 | 
			
		||||
                                                       gint            top,
 | 
			
		||||
                                                       gint            left,
 | 
			
		||||
                                                       gint            width,
 | 
			
		||||
                                                       gint            height);
 | 
			
		||||
void            nbtk_subtexture_get_frame          (NbtkSubtexture *frame,
 | 
			
		||||
                                                       gint           *top,
 | 
			
		||||
                                                       gint           *left,
 | 
			
		||||
                                                       gint           *width,
 | 
			
		||||
                                                       gint           *height);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_SUBTEXTURE_H__ */
 | 
			
		||||
							
								
								
									
										456
									
								
								src/nbtk/nbtk-texture-cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										456
									
								
								src/nbtk/nbtk-texture-cache.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,456 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-widget.h: Base class for Nbtk actors
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-texture-cache
 | 
			
		||||
 * @short_description: A per-process store to cache textures
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkTextureCache allows an application to re-use an previously loaded
 | 
			
		||||
 * textures.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-texture-cache.h"
 | 
			
		||||
#include "nbtk-marshal.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
#include "nbtk-subtexture.h"
 | 
			
		||||
G_DEFINE_TYPE (NbtkTextureCache, nbtk_texture_cache, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
#define TEXTURE_CACHE_PRIVATE(o) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), NBTK_TYPE_TEXTURE_CACHE, NbtkTextureCachePrivate))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkTextureCachePrivate NbtkTextureCachePrivate;
 | 
			
		||||
 | 
			
		||||
struct _NbtkTextureCachePrivate
 | 
			
		||||
{
 | 
			
		||||
  GHashTable  *cache;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct FinalizedClosure
 | 
			
		||||
{
 | 
			
		||||
  gchar             *path;
 | 
			
		||||
  NbtkTextureCache  *cache;
 | 
			
		||||
} FinalizedClosure;
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static NbtkTextureCache* __cache_singleton = NULL;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convention: posX with a value of -1 indicates whole texture
 | 
			
		||||
 */
 | 
			
		||||
typedef struct NbtkTextureCacheItem {
 | 
			
		||||
  char filename[256];
 | 
			
		||||
  int  width, height;
 | 
			
		||||
  int  posX, posY;
 | 
			
		||||
  ClutterActor *ptr;
 | 
			
		||||
} NbtkTextureCacheItem;
 | 
			
		||||
 | 
			
		||||
static NbtkTextureCacheItem *
 | 
			
		||||
nbtk_texture_cache_item_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_slice_new0 (NbtkTextureCacheItem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_item_free (NbtkTextureCacheItem *item)
 | 
			
		||||
{
 | 
			
		||||
  g_slice_free (NbtkTextureCacheItem, item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_set_property (GObject      *object,
 | 
			
		||||
                                 guint         prop_id,
 | 
			
		||||
                                 const GValue *value,
 | 
			
		||||
                                 GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_get_property (GObject    *object,
 | 
			
		||||
                                 guint       prop_id,
 | 
			
		||||
                                 GValue     *value,
 | 
			
		||||
                                 GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  if (G_OBJECT_CLASS (nbtk_texture_cache_parent_class)->dispose)
 | 
			
		||||
    G_OBJECT_CLASS (nbtk_texture_cache_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureCachePrivate *priv = TEXTURE_CACHE_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
  if (priv->cache)
 | 
			
		||||
    {
 | 
			
		||||
      g_hash_table_unref (priv->cache);
 | 
			
		||||
      priv->cache = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_texture_cache_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_class_init (NbtkTextureCacheClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkTextureCachePrivate));
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = nbtk_texture_cache_get_property;
 | 
			
		||||
  object_class->set_property = nbtk_texture_cache_set_property;
 | 
			
		||||
  object_class->dispose = nbtk_texture_cache_dispose;
 | 
			
		||||
  object_class->finalize = nbtk_texture_cache_finalize;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_cache_init (NbtkTextureCache *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureCachePrivate *priv = TEXTURE_CACHE_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
  priv->cache = g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                                       g_str_equal,
 | 
			
		||||
                                       g_free,
 | 
			
		||||
                                       NULL);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_cache_get_default:
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the default texture cache. This is owned by Nbtk and should not be
 | 
			
		||||
 * unreferenced or freed.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): a NbtkTextureCache
 | 
			
		||||
 */
 | 
			
		||||
NbtkTextureCache*
 | 
			
		||||
nbtk_texture_cache_get_default (void)
 | 
			
		||||
{
 | 
			
		||||
  if (G_UNLIKELY (__cache_singleton == NULL))
 | 
			
		||||
    __cache_singleton = g_object_new (NBTK_TYPE_TEXTURE_CACHE, NULL);
 | 
			
		||||
 | 
			
		||||
  return  __cache_singleton;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
static void
 | 
			
		||||
on_texure_finalized (gpointer data,
 | 
			
		||||
		     GObject *where_the_object_was)
 | 
			
		||||
{
 | 
			
		||||
  FinalizedClosure *closure = (FinalizedClosure *)data;
 | 
			
		||||
  NbtkTextureCachePrivate *priv = TEXTURE_CACHE_PRIVATE(closure->cache);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_remove (priv->cache, closure->path);
 | 
			
		||||
 | 
			
		||||
  g_free(closure->path);
 | 
			
		||||
  g_free(closure);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_cache_get_size:
 | 
			
		||||
 * @self: A #NbtkTextureCache
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the number of items in the texture cache
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the current size of the cache
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
nbtk_texture_cache_get_size (NbtkTextureCache *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureCachePrivate *priv = TEXTURE_CACHE_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
  return g_hash_table_size (priv->cache);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_texture_to_cache (NbtkTextureCache     *self,
 | 
			
		||||
                      const gchar          *path,
 | 
			
		||||
                      NbtkTextureCacheItem *item)
 | 
			
		||||
{
 | 
			
		||||
  /*  FinalizedClosure        *closure; */
 | 
			
		||||
  NbtkTextureCachePrivate *priv = TEXTURE_CACHE_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (priv->cache, g_strdup (path), item);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  /* Make sure we can remove from hash */
 | 
			
		||||
  closure = g_new0 (FinalizedClosure, 1);
 | 
			
		||||
  closure->path = g_strdup (path);
 | 
			
		||||
  closure->cache = self;
 | 
			
		||||
 | 
			
		||||
  g_object_weak_ref (G_OBJECT (res), on_texure_finalized, closure);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* NOTE: you should unref the returned texture when not needed */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_cache_get_texture:
 | 
			
		||||
 * @self: A #NbtkTextureCache
 | 
			
		||||
 * @path: A path to a image file
 | 
			
		||||
 * @want_clone: ignored
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new ClutterTexture with the specified image. Adds the image to the
 | 
			
		||||
 * cache if the image had not been previously loaded. Subsequent calls with
 | 
			
		||||
 * the same image path will return a new ClutterTexture with the previously
 | 
			
		||||
 * loaded image.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): a newly created ClutterTexture
 | 
			
		||||
 */
 | 
			
		||||
ClutterTexture*
 | 
			
		||||
nbtk_texture_cache_get_texture (NbtkTextureCache *self,
 | 
			
		||||
                                const gchar      *path,
 | 
			
		||||
                                gboolean          want_clone)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *texture;
 | 
			
		||||
  CoglHandle *handle;
 | 
			
		||||
  NbtkTextureCachePrivate *priv;
 | 
			
		||||
  NbtkTextureCacheItem *item;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_TEXTURE_CACHE (self), NULL);
 | 
			
		||||
  g_return_val_if_fail (path != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  priv = TEXTURE_CACHE_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  if (want_clone)
 | 
			
		||||
    g_warning ("The want_clone parameter of %s is now ignored. This function "
 | 
			
		||||
               "always returns a new ClutterTexture", __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
  item = g_hash_table_lookup (priv->cache, path);
 | 
			
		||||
 | 
			
		||||
  if (item && item->posX != -1)
 | 
			
		||||
    {
 | 
			
		||||
      GError *err = NULL;
 | 
			
		||||
      /*
 | 
			
		||||
       * We have a cache hit, but it's for a partial texture. The only
 | 
			
		||||
       * sane option is to read it from disk and just don't cache it
 | 
			
		||||
       * at all.
 | 
			
		||||
       */
 | 
			
		||||
      return CLUTTER_TEXTURE(clutter_texture_new_from_file(path, &err));
 | 
			
		||||
    }
 | 
			
		||||
  if (!item)
 | 
			
		||||
    {
 | 
			
		||||
      GError *err = NULL;
 | 
			
		||||
 | 
			
		||||
      item = nbtk_texture_cache_item_new ();
 | 
			
		||||
      item->posX = -1;
 | 
			
		||||
      item->posY = -1;
 | 
			
		||||
      item->ptr = clutter_texture_new_from_file (path, &err);
 | 
			
		||||
      clutter_texture_get_base_size (CLUTTER_TEXTURE (item->ptr),
 | 
			
		||||
                                     &item->width, &item->height);
 | 
			
		||||
 | 
			
		||||
      if (!item->ptr)
 | 
			
		||||
        {
 | 
			
		||||
          if (err)
 | 
			
		||||
            {
 | 
			
		||||
              g_warning ("Error loading image: %s", err->message);
 | 
			
		||||
              g_error_free (err);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      add_texture_to_cache (self, path, item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  texture = clutter_texture_new ();
 | 
			
		||||
  handle = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (item->ptr));
 | 
			
		||||
  clutter_texture_set_cogl_texture ((ClutterTexture*) texture, handle);
 | 
			
		||||
 | 
			
		||||
  return (ClutterTexture*) texture;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_cache_get_actor:
 | 
			
		||||
 * @self: A #NbtkTextureCache
 | 
			
		||||
 * @path: A path to a image file
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new ClutterSubTexture with the specified image. Adds the image to the
 | 
			
		||||
 * cache if the image had not been previously loaded. Subsequent calls with
 | 
			
		||||
 * the same image path will return a new ClutterTexture with the previously
 | 
			
		||||
 * loaded image.
 | 
			
		||||
 *
 | 
			
		||||
 * Use this function if all you need is an actor for drawing.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): a newly created ClutterTexture
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor*
 | 
			
		||||
nbtk_texture_cache_get_actor (NbtkTextureCache *self,
 | 
			
		||||
                              const gchar      *path)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureCachePrivate *priv;
 | 
			
		||||
  NbtkTextureCacheItem *item;
 | 
			
		||||
  GError *err = NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_TEXTURE_CACHE (self), NULL);
 | 
			
		||||
  g_return_val_if_fail (path != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  priv = TEXTURE_CACHE_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  item = g_hash_table_lookup (priv->cache, path);
 | 
			
		||||
 | 
			
		||||
  if (item)
 | 
			
		||||
    {
 | 
			
		||||
      int posX = item->posX;
 | 
			
		||||
      int posY = item->posY;
 | 
			
		||||
      if (posX == -1)
 | 
			
		||||
          posX = 0;
 | 
			
		||||
      if (posY == -1)
 | 
			
		||||
          posY = 0;
 | 
			
		||||
      return nbtk_subtexture_new (CLUTTER_TEXTURE (item->ptr), posX, posY,
 | 
			
		||||
                                  item->width, item->height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  item = nbtk_texture_cache_item_new ();
 | 
			
		||||
  item->posX = -1;
 | 
			
		||||
  item->posY = -1;
 | 
			
		||||
  item->ptr = clutter_texture_new_from_file (path, &err);
 | 
			
		||||
  clutter_texture_get_base_size (CLUTTER_TEXTURE (item->ptr),
 | 
			
		||||
                                 &item->width, &item->height);
 | 
			
		||||
 | 
			
		||||
  if (!item->ptr)
 | 
			
		||||
    {
 | 
			
		||||
      if (err)
 | 
			
		||||
        {
 | 
			
		||||
          g_warning ("Error loading image: %s", err->message);
 | 
			
		||||
          g_error_free (err);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  add_texture_to_cache (self, path, item);
 | 
			
		||||
 | 
			
		||||
  return nbtk_subtexture_new (CLUTTER_TEXTURE (item->ptr), 0, 0, item->width,
 | 
			
		||||
                              item->height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
nbtk_texture_cache_load_cache (NbtkTextureCache *self,
 | 
			
		||||
                               const gchar      *filename)
 | 
			
		||||
{
 | 
			
		||||
   FILE *file;
 | 
			
		||||
   NbtkTextureCacheItem *element, head;
 | 
			
		||||
   int ret;
 | 
			
		||||
   ClutterActor *actor;
 | 
			
		||||
   GError *error = NULL;
 | 
			
		||||
   NbtkTextureCachePrivate *priv;
 | 
			
		||||
 | 
			
		||||
   g_return_if_fail (NBTK_IS_TEXTURE_CACHE (self));
 | 
			
		||||
   g_return_if_fail (filename != NULL);
 | 
			
		||||
 | 
			
		||||
   priv = TEXTURE_CACHE_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
   file = fopen(filename, "rm");
 | 
			
		||||
   if (!file)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
   ret = fread (&head, sizeof(NbtkTextureCacheItem), 1, file);
 | 
			
		||||
   if (ret < 0)
 | 
			
		||||
     {
 | 
			
		||||
        fclose (file);
 | 
			
		||||
        return;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
   /* check if we already if this texture in the cache */
 | 
			
		||||
   if (g_hash_table_lookup (priv->cache, head.filename))
 | 
			
		||||
     {
 | 
			
		||||
        /* skip it, we're done */
 | 
			
		||||
        fclose (file);
 | 
			
		||||
        return;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
   actor = clutter_texture_new_from_file (head.filename, &error);
 | 
			
		||||
 | 
			
		||||
   if (error)
 | 
			
		||||
   {
 | 
			
		||||
     g_critical (G_STRLOC ": Error opening cache image file: %s",
 | 
			
		||||
                 error->message);
 | 
			
		||||
     g_clear_error (&error);
 | 
			
		||||
     fclose (file);
 | 
			
		||||
     return;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   element = nbtk_texture_cache_item_new ();
 | 
			
		||||
   element->posX = -1;
 | 
			
		||||
   element->posY = -1;
 | 
			
		||||
   element->ptr = actor;
 | 
			
		||||
   strncpy (element->filename, head.filename, 256);
 | 
			
		||||
   clutter_texture_get_base_size (CLUTTER_TEXTURE (element->ptr),
 | 
			
		||||
                                  &element->width, &element->height);
 | 
			
		||||
   g_hash_table_insert (priv->cache, element->filename, element);
 | 
			
		||||
 | 
			
		||||
   while (!feof (file))
 | 
			
		||||
     {
 | 
			
		||||
        element = nbtk_texture_cache_item_new ();
 | 
			
		||||
        ret = fread (element, sizeof (NbtkTextureCacheItem), 1, file);
 | 
			
		||||
        if (ret < 1)
 | 
			
		||||
          {
 | 
			
		||||
             /* end of file */
 | 
			
		||||
             nbtk_texture_cache_item_free (element);
 | 
			
		||||
             break;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        element->ptr = actor;
 | 
			
		||||
 | 
			
		||||
        if (g_hash_table_lookup (priv->cache, element->filename))
 | 
			
		||||
          {
 | 
			
		||||
            /* file is already in the cache.... */
 | 
			
		||||
            nbtk_texture_cache_item_free (element);
 | 
			
		||||
          } else {
 | 
			
		||||
            g_hash_table_insert (priv->cache, element->filename, element);
 | 
			
		||||
          }
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								src/nbtk/nbtk-texture-cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/nbtk/nbtk-texture-cache.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-texture-cache.h: Cached textures object
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef _NBTK_TEXTURE_CACHE
 | 
			
		||||
#define _NBTK_TEXTURE_CACHE
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_TEXTURE_CACHE nbtk_texture_cache_get_type()
 | 
			
		||||
 | 
			
		||||
#define NBTK_TEXTURE_CACHE(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
 | 
			
		||||
  NBTK_TYPE_TEXTURE_CACHE, NbtkTextureCache))
 | 
			
		||||
 | 
			
		||||
#define NBTK_TEXTURE_CACHE_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_CAST ((klass), \
 | 
			
		||||
  NBTK_TYPE_TEXTURE_CACHE, NbtkTextureCacheClass))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_TEXTURE_CACHE(obj) \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
 | 
			
		||||
  NBTK_TYPE_TEXTURE_CACHE))
 | 
			
		||||
 | 
			
		||||
#define NBTK_IS_TEXTURE_CACHE_CLASS(klass) \
 | 
			
		||||
  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
 | 
			
		||||
  NBTK_TYPE_TEXTURE_CACHE))
 | 
			
		||||
 | 
			
		||||
#define NBTK_TEXTURE_CACHE_GET_CLASS(obj) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
 | 
			
		||||
  NBTK_TYPE_TEXTURE_CACHE, NbtkTextureCacheClass))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkTextureCache:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
} NbtkTextureCache;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  void (* loaded)        (NbtkTextureCache *self,
 | 
			
		||||
                          const gchar      *path,
 | 
			
		||||
                          ClutterTexture   *texture);
 | 
			
		||||
 | 
			
		||||
  void (* error_loading) (NbtkTextureCache *self,
 | 
			
		||||
                          GError           *error);
 | 
			
		||||
} NbtkTextureCacheClass;
 | 
			
		||||
 | 
			
		||||
GType nbtk_texture_cache_get_type (void);
 | 
			
		||||
 | 
			
		||||
NbtkTextureCache* nbtk_texture_cache_get_default (void);
 | 
			
		||||
ClutterTexture*   nbtk_texture_cache_get_texture (NbtkTextureCache *self,
 | 
			
		||||
                                                  const gchar *path,
 | 
			
		||||
                                                  gboolean want_clone);
 | 
			
		||||
ClutterActor*     nbtk_texture_cache_get_actor (NbtkTextureCache *self,
 | 
			
		||||
                                                  const gchar *path);
 | 
			
		||||
 | 
			
		||||
gint              nbtk_texture_cache_get_size    (NbtkTextureCache *self);
 | 
			
		||||
 | 
			
		||||
void nbtk_texture_cache_load_cache(NbtkTextureCache *self, const char *filename);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* _NBTK_TEXTURE_CACHE */
 | 
			
		||||
							
								
								
									
										620
									
								
								src/nbtk/nbtk-texture-frame.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										620
									
								
								src/nbtk/nbtk-texture-frame.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,620 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-texture-frame.h: Expandible texture actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-texture-frame
 | 
			
		||||
 * @short_description: Stretch a texture to fit the entire allocation
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkTextureFrame
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-texture-frame.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_PARENT_TEXTURE,
 | 
			
		||||
 | 
			
		||||
  PROP_TOP,
 | 
			
		||||
  PROP_RIGHT,
 | 
			
		||||
  PROP_BOTTOM,
 | 
			
		||||
  PROP_LEFT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkTextureFrame, nbtk_texture_frame, CLUTTER_TYPE_ACTOR);
 | 
			
		||||
 | 
			
		||||
#define NBTK_TEXTURE_FRAME_GET_PRIVATE(obj)     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_TEXTURE_FRAME, NbtkTextureFramePrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkTextureFramePrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterTexture *parent_texture;
 | 
			
		||||
 | 
			
		||||
  gfloat top;
 | 
			
		||||
  gfloat right;
 | 
			
		||||
  gfloat bottom;
 | 
			
		||||
  gfloat left;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                                        gfloat        for_height,
 | 
			
		||||
                                        gfloat       *min_width_p,
 | 
			
		||||
                                        gfloat       *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv = NBTK_TEXTURE_FRAME (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (priv->parent_texture == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      if (min_width_p)
 | 
			
		||||
        *min_width_p = 0;
 | 
			
		||||
 | 
			
		||||
      if (natural_width_p)
 | 
			
		||||
        *natural_width_p = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorClass *klass;
 | 
			
		||||
 | 
			
		||||
      /* by directly querying the parent texture's class implementation
 | 
			
		||||
       * we are going around any override mechanism the parent texture
 | 
			
		||||
       * might have in place, and we ask directly for the original
 | 
			
		||||
       * preferred width
 | 
			
		||||
       */
 | 
			
		||||
      klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture);
 | 
			
		||||
      klass->get_preferred_width (CLUTTER_ACTOR (priv->parent_texture),
 | 
			
		||||
                                  for_height,
 | 
			
		||||
                                  min_width_p,
 | 
			
		||||
                                  natural_width_p);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                                         gfloat        for_width,
 | 
			
		||||
                                         gfloat       *min_height_p,
 | 
			
		||||
                                         gfloat       *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv = NBTK_TEXTURE_FRAME (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (priv->parent_texture == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      if (min_height_p)
 | 
			
		||||
        *min_height_p = 0;
 | 
			
		||||
 | 
			
		||||
      if (natural_height_p)
 | 
			
		||||
        *natural_height_p = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorClass *klass;
 | 
			
		||||
 | 
			
		||||
      /* by directly querying the parent texture's class implementation
 | 
			
		||||
       * we are going around any override mechanism the parent texture
 | 
			
		||||
       * might have in place, and we ask directly for the original
 | 
			
		||||
       * preferred height
 | 
			
		||||
       */
 | 
			
		||||
      klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture);
 | 
			
		||||
      klass->get_preferred_height (CLUTTER_ACTOR (priv->parent_texture),
 | 
			
		||||
                                   for_width,
 | 
			
		||||
                                   min_height_p,
 | 
			
		||||
                                   natural_height_p);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_paint (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv = NBTK_TEXTURE_FRAME (self)->priv;
 | 
			
		||||
  CoglHandle cogl_texture = COGL_INVALID_HANDLE;
 | 
			
		||||
  CoglHandle cogl_material = COGL_INVALID_HANDLE;
 | 
			
		||||
  ClutterActorBox box = { 0, };
 | 
			
		||||
  gfloat width, height;
 | 
			
		||||
  gfloat tex_width, tex_height;
 | 
			
		||||
  gfloat ex, ey;
 | 
			
		||||
  gfloat tx1, ty1, tx2, ty2;
 | 
			
		||||
  guint8 opacity;
 | 
			
		||||
 | 
			
		||||
  /* no need to paint stuff if we don't have a texture */
 | 
			
		||||
  if (G_UNLIKELY (priv->parent_texture == NULL))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* parent texture may have been hidden, so need to make sure it gets
 | 
			
		||||
   * realized
 | 
			
		||||
   */
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture))
 | 
			
		||||
    clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture));
 | 
			
		||||
 | 
			
		||||
  cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
 | 
			
		||||
  if (cogl_texture == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
  cogl_material = clutter_texture_get_cogl_material (priv->parent_texture);
 | 
			
		||||
  if (cogl_material == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tex_width  = cogl_texture_get_width (cogl_texture);
 | 
			
		||||
  tex_height = cogl_texture_get_height (cogl_texture);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_allocation_box (self, &box);
 | 
			
		||||
  width = box.x2 - box.x1;
 | 
			
		||||
  height = box.y2 - box.y1;
 | 
			
		||||
 | 
			
		||||
  tx1 = priv->left / tex_width;
 | 
			
		||||
  tx2 = (tex_width - priv->right) / tex_width;
 | 
			
		||||
  ty1 = priv->top / tex_height;
 | 
			
		||||
  ty2 = (tex_height - priv->bottom) / tex_height;
 | 
			
		||||
 | 
			
		||||
  ex = width - priv->right;
 | 
			
		||||
  if (ex < 0)
 | 
			
		||||
    ex = priv->right; 		/* FIXME ? */
 | 
			
		||||
 | 
			
		||||
  ey = height - priv->bottom;
 | 
			
		||||
  if (ey < 0)
 | 
			
		||||
    ey = priv->bottom; 		/* FIXME ? */
 | 
			
		||||
 | 
			
		||||
  opacity = clutter_actor_get_paint_opacity (self);
 | 
			
		||||
 | 
			
		||||
  /* Paint using the parent texture's material. It should already have
 | 
			
		||||
     the cogl texture set as the first layer */
 | 
			
		||||
  /* NB: for correct blending we need set a preumultiplied color here: */
 | 
			
		||||
  cogl_material_set_color4ub (cogl_material,
 | 
			
		||||
                              opacity, opacity, opacity, opacity);
 | 
			
		||||
  cogl_set_source (cogl_material);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    GLfloat rectangles[] =
 | 
			
		||||
      {
 | 
			
		||||
        /* top left corner */
 | 
			
		||||
        0, 0, priv->left, priv->top,
 | 
			
		||||
        0.0, 0.0,
 | 
			
		||||
        tx1, ty1,
 | 
			
		||||
 | 
			
		||||
        /* top middle */
 | 
			
		||||
        priv->left, 0, ex, priv->top,
 | 
			
		||||
        tx1, 0.0,
 | 
			
		||||
        tx2, ty1,
 | 
			
		||||
 | 
			
		||||
        /* top right */
 | 
			
		||||
        ex, 0, width, priv->top,
 | 
			
		||||
        tx2, 0.0,
 | 
			
		||||
        1.0, ty1,
 | 
			
		||||
 | 
			
		||||
        /* mid left */
 | 
			
		||||
        0, priv->top, priv->left, ey,
 | 
			
		||||
        0.0, ty1,
 | 
			
		||||
        tx1, ty2,
 | 
			
		||||
 | 
			
		||||
        /* center */
 | 
			
		||||
        priv->left, priv->top, ex, ey,
 | 
			
		||||
        tx1, ty1,
 | 
			
		||||
        tx2, ty2,
 | 
			
		||||
 | 
			
		||||
        /* mid right */
 | 
			
		||||
        ex, priv->top, width, ey,
 | 
			
		||||
        tx2, ty1,
 | 
			
		||||
        1.0, ty2,
 | 
			
		||||
 | 
			
		||||
        /* bottom left */
 | 
			
		||||
        0, ey, priv->left, height,
 | 
			
		||||
        0.0, ty2,
 | 
			
		||||
        tx1, 1.0,
 | 
			
		||||
 | 
			
		||||
        /* bottom center */
 | 
			
		||||
        priv->left, ey, ex, height,
 | 
			
		||||
        tx1, ty2,
 | 
			
		||||
        tx2, 1.0,
 | 
			
		||||
 | 
			
		||||
        /* bottom right */
 | 
			
		||||
        ex, ey, width, height,
 | 
			
		||||
        tx2, ty2,
 | 
			
		||||
        1.0, 1.0
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    cogl_rectangles_with_texture_coords (rectangles, 9);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
nbtk_texture_frame_set_frame_internal (NbtkTextureFrame *frame,
 | 
			
		||||
                                       gfloat            top,
 | 
			
		||||
                                       gfloat            right,
 | 
			
		||||
                                       gfloat            bottom,
 | 
			
		||||
                                       gfloat            left)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv = frame->priv;
 | 
			
		||||
  GObject *gobject = G_OBJECT (frame);
 | 
			
		||||
  gboolean changed = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (gobject);
 | 
			
		||||
 | 
			
		||||
  if (priv->top != top)
 | 
			
		||||
    {
 | 
			
		||||
      priv->top = top;
 | 
			
		||||
      g_object_notify (gobject, "top");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->right != right)
 | 
			
		||||
    {
 | 
			
		||||
      priv->right = right;
 | 
			
		||||
      g_object_notify (gobject, "right");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->bottom != bottom)
 | 
			
		||||
    {
 | 
			
		||||
      priv->bottom = bottom;
 | 
			
		||||
      g_object_notify (gobject, "bottom");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->left != left)
 | 
			
		||||
    {
 | 
			
		||||
      priv->left = left;
 | 
			
		||||
      g_object_notify (gobject, "left");
 | 
			
		||||
      changed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (changed && CLUTTER_ACTOR_IS_VISIBLE (frame))
 | 
			
		||||
    clutter_actor_queue_redraw (CLUTTER_ACTOR (frame));
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_set_property (GObject      *gobject,
 | 
			
		||||
                                 guint         prop_id,
 | 
			
		||||
                                 const GValue *value,
 | 
			
		||||
                                 GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFrame *frame = NBTK_TEXTURE_FRAME (gobject);
 | 
			
		||||
  NbtkTextureFramePrivate *priv = frame->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_PARENT_TEXTURE:
 | 
			
		||||
      nbtk_texture_frame_set_parent_texture (frame,
 | 
			
		||||
                                             g_value_get_object (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TOP:
 | 
			
		||||
      nbtk_texture_frame_set_frame_internal (frame,
 | 
			
		||||
                                             g_value_get_float (value),
 | 
			
		||||
                                             priv->right,
 | 
			
		||||
                                             priv->bottom,
 | 
			
		||||
                                             priv->left);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_RIGHT:
 | 
			
		||||
      nbtk_texture_frame_set_frame_internal (frame,
 | 
			
		||||
                                             priv->top,
 | 
			
		||||
                                             g_value_get_float (value),
 | 
			
		||||
                                             priv->bottom,
 | 
			
		||||
                                             priv->left);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_BOTTOM:
 | 
			
		||||
      nbtk_texture_frame_set_frame_internal (frame,
 | 
			
		||||
                                             priv->top,
 | 
			
		||||
                                             priv->right,
 | 
			
		||||
                                             g_value_get_float (value),
 | 
			
		||||
                                             priv->left);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_LEFT:
 | 
			
		||||
      nbtk_texture_frame_set_frame_internal (frame,
 | 
			
		||||
                                             priv->top,
 | 
			
		||||
                                             priv->right,
 | 
			
		||||
                                             priv->bottom,
 | 
			
		||||
                                             g_value_get_float (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_get_property (GObject    *gobject,
 | 
			
		||||
                                 guint       prop_id,
 | 
			
		||||
                                 GValue     *value,
 | 
			
		||||
                                 GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv = NBTK_TEXTURE_FRAME (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_PARENT_TEXTURE:
 | 
			
		||||
      g_value_set_object (value, priv->parent_texture);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_LEFT:
 | 
			
		||||
      g_value_set_float (value, priv->left);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TOP:
 | 
			
		||||
      g_value_set_float (value, priv->top);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_RIGHT:
 | 
			
		||||
      g_value_set_float (value, priv->right);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_BOTTOM:
 | 
			
		||||
      g_value_set_float (value, priv->bottom);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_dispose (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv = NBTK_TEXTURE_FRAME (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->parent_texture)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (priv->parent_texture);
 | 
			
		||||
      priv->parent_texture = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (nbtk_texture_frame_parent_class)->dispose (gobject);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_class_init (NbtkTextureFrameClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (gobject_class, sizeof (NbtkTextureFramePrivate));
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width =
 | 
			
		||||
    nbtk_texture_frame_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height =
 | 
			
		||||
    nbtk_texture_frame_get_preferred_height;
 | 
			
		||||
  actor_class->paint = nbtk_texture_frame_paint;
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_texture_frame_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_texture_frame_get_property;
 | 
			
		||||
  gobject_class->dispose = nbtk_texture_frame_dispose;
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_object ("parent-texture",
 | 
			
		||||
                               "Parent Texture",
 | 
			
		||||
                               "The parent ClutterTexture",
 | 
			
		||||
                               CLUTTER_TYPE_TEXTURE,
 | 
			
		||||
                               NBTK_PARAM_READWRITE |
 | 
			
		||||
                               G_PARAM_CONSTRUCT);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_PARENT_TEXTURE, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_float ("left",
 | 
			
		||||
                              "Left",
 | 
			
		||||
                              "Left offset",
 | 
			
		||||
			      0, G_MAXFLOAT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_LEFT, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_float ("top",
 | 
			
		||||
                              "Top",
 | 
			
		||||
                              "Top offset",
 | 
			
		||||
                              0, G_MAXFLOAT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TOP, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_float ("bottom",
 | 
			
		||||
                              "Bottom",
 | 
			
		||||
                              "Bottom offset",
 | 
			
		||||
                              0, G_MAXFLOAT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_BOTTOM, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_float ("right",
 | 
			
		||||
                              "Right",
 | 
			
		||||
                              "Right offset",
 | 
			
		||||
                              0, G_MAXFLOAT,
 | 
			
		||||
                              0,
 | 
			
		||||
                              NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_RIGHT, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_texture_frame_init (NbtkTextureFrame *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  self->priv = priv = NBTK_TEXTURE_FRAME_GET_PRIVATE (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_frame_new:
 | 
			
		||||
 * @texture: a #ClutterTexture or %NULL
 | 
			
		||||
 * @left: left margin preserving its content
 | 
			
		||||
 * @top: top margin preserving its content
 | 
			
		||||
 * @right: right margin preserving its content
 | 
			
		||||
 * @bottom: bottom margin preserving its content
 | 
			
		||||
 *
 | 
			
		||||
 * A #NbtkTextureFrame is a specialized texture that efficiently clones
 | 
			
		||||
 * an area of the given @texture while keeping preserving portions of the
 | 
			
		||||
 * same texture.
 | 
			
		||||
 *
 | 
			
		||||
 * A #NbtkTextureFrame can be used to make a rectangular texture fit a
 | 
			
		||||
 * given size without stretching its borders.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the newly created #NbtkTextureFrame
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor*
 | 
			
		||||
nbtk_texture_frame_new (ClutterTexture *texture,
 | 
			
		||||
			gfloat          top,
 | 
			
		||||
			gfloat          right,
 | 
			
		||||
			gfloat          bottom,
 | 
			
		||||
			gfloat          left)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL);
 | 
			
		||||
 | 
			
		||||
  return g_object_new (NBTK_TYPE_TEXTURE_FRAME,
 | 
			
		||||
		       "parent-texture", texture,
 | 
			
		||||
		       "top", top,
 | 
			
		||||
		       "right", right,
 | 
			
		||||
		       "bottom", bottom,
 | 
			
		||||
		       "left", left,
 | 
			
		||||
		       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_frame_get_parent_texture:
 | 
			
		||||
 * @frame: A #NbtkTextureFrame
 | 
			
		||||
 *
 | 
			
		||||
 * Return the texture used by the #NbtkTextureFrame
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): a #ClutterTexture owned by the #NbtkTextureFrame
 | 
			
		||||
 */
 | 
			
		||||
ClutterTexture *
 | 
			
		||||
nbtk_texture_frame_get_parent_texture (NbtkTextureFrame *frame)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_TEXTURE_FRAME (frame), NULL);
 | 
			
		||||
 | 
			
		||||
  return frame->priv->parent_texture;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_frame_set_parent_texture:
 | 
			
		||||
 * @frame: A #NbtkTextureFrame
 | 
			
		||||
 * @texture: A #ClutterTexture
 | 
			
		||||
 *
 | 
			
		||||
 * Set the #ClutterTexture used by this #NbtkTextureFrame
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_texture_frame_set_parent_texture (NbtkTextureFrame *frame,
 | 
			
		||||
                                       ClutterTexture   *texture)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv;
 | 
			
		||||
  gboolean was_visible;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_TEXTURE_FRAME (frame));
 | 
			
		||||
  g_return_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture));
 | 
			
		||||
 | 
			
		||||
  priv = frame->priv;
 | 
			
		||||
 | 
			
		||||
  was_visible = CLUTTER_ACTOR_IS_VISIBLE (frame);
 | 
			
		||||
 | 
			
		||||
  if (priv->parent_texture == texture)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->parent_texture)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (priv->parent_texture);
 | 
			
		||||
      priv->parent_texture = NULL;
 | 
			
		||||
 | 
			
		||||
      if (was_visible)
 | 
			
		||||
        clutter_actor_hide (CLUTTER_ACTOR (frame));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (texture)
 | 
			
		||||
    {
 | 
			
		||||
      priv->parent_texture = g_object_ref_sink (texture);
 | 
			
		||||
 | 
			
		||||
      if (was_visible && CLUTTER_ACTOR_IS_VISIBLE (priv->parent_texture))
 | 
			
		||||
        clutter_actor_show (CLUTTER_ACTOR (frame));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (frame), "parent-texture");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_frame_set_frame:
 | 
			
		||||
 * @frame: A #NbtkTextureFrame
 | 
			
		||||
 * @top: width of the top slice
 | 
			
		||||
 * @right: width of the right slice
 | 
			
		||||
 * @bottom: width of the bottom slice
 | 
			
		||||
 * @left: width of the left slice
 | 
			
		||||
 *
 | 
			
		||||
 * Set the slice lines of the specified frame. The slices are calculated as
 | 
			
		||||
 * widths from the edge of the frame.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_texture_frame_set_frame (NbtkTextureFrame *frame,
 | 
			
		||||
                              gfloat            top,
 | 
			
		||||
                              gfloat            right,
 | 
			
		||||
                              gfloat            bottom,
 | 
			
		||||
                              gfloat            left)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (NBTK_IS_TEXTURE_FRAME (frame));
 | 
			
		||||
 | 
			
		||||
  nbtk_texture_frame_set_frame_internal (frame, top, right, bottom, left);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_texture_frame_get_frame:
 | 
			
		||||
 * @frame: A #NbtkTextureFrame
 | 
			
		||||
 * @top: width of the top slice
 | 
			
		||||
 * @right: width of the right slice
 | 
			
		||||
 * @bottom: width of the bottom slice
 | 
			
		||||
 * @left: width of the left slice
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve the current slice lines from the specified frame.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_texture_frame_get_frame (NbtkTextureFrame *frame,
 | 
			
		||||
                              gfloat           *top,
 | 
			
		||||
                              gfloat           *right,
 | 
			
		||||
                              gfloat           *bottom,
 | 
			
		||||
                              gfloat           *left)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTextureFramePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_TEXTURE_FRAME (frame));
 | 
			
		||||
 | 
			
		||||
  priv = frame->priv;
 | 
			
		||||
 | 
			
		||||
  if (top)
 | 
			
		||||
    *top = priv->top;
 | 
			
		||||
 | 
			
		||||
  if (right)
 | 
			
		||||
    *right = priv->right;
 | 
			
		||||
 | 
			
		||||
  if (bottom)
 | 
			
		||||
    *bottom = priv->bottom;
 | 
			
		||||
 | 
			
		||||
  if (left)
 | 
			
		||||
    *left = priv->left;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								src/nbtk/nbtk-texture-frame.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/nbtk/nbtk-texture-frame.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-texture-frame.h: Expandible texture actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007, 2008 OpenedHand Ltd
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_TEXTURE_FRAME_H__
 | 
			
		||||
#define __NBTK_TEXTURE_FRAME_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_TEXTURE_FRAME                 (nbtk_texture_frame_get_type ())
 | 
			
		||||
#define NBTK_TEXTURE_FRAME(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_TEXTURE_FRAME, NbtkTextureFrame))
 | 
			
		||||
#define NBTK_TEXTURE_FRAME_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_TEXTURE_FRAME, NbtkTextureFrameClass))
 | 
			
		||||
#define NBTK_IS_TEXTURE_FRAME(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_TEXTURE_FRAME))
 | 
			
		||||
#define NBTK_IS_TEXTURE_FRAME_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_TEXTURE_FRAME))
 | 
			
		||||
#define NBTK_TEXTURE_FRAME_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_TEXTURE_FRAME, NbtkTextureFrameClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkTextureFrame                NbtkTextureFrame;
 | 
			
		||||
typedef struct _NbtkTextureFramePrivate         NbtkTextureFramePrivate;
 | 
			
		||||
typedef struct _NbtkTextureFrameClass           NbtkTextureFrameClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkTextureFrame:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure are private and should only be accessed
 | 
			
		||||
 * through the public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkTextureFrame
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActor parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkTextureFramePrivate    *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkTextureFrameClass
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* padding for future expansion */
 | 
			
		||||
  void (*_clutter_box_1) (void);
 | 
			
		||||
  void (*_clutter_box_2) (void);
 | 
			
		||||
  void (*_clutter_box_3) (void);
 | 
			
		||||
  void (*_clutter_box_4) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType           nbtk_texture_frame_get_type           (void) G_GNUC_CONST;
 | 
			
		||||
ClutterActor *  nbtk_texture_frame_new                (ClutterTexture   *texture,
 | 
			
		||||
                                                       gfloat            top,
 | 
			
		||||
                                                       gfloat            right,
 | 
			
		||||
                                                       gfloat            bottom,
 | 
			
		||||
                                                       gfloat            left);
 | 
			
		||||
void            nbtk_texture_frame_set_parent_texture (NbtkTextureFrame *frame,
 | 
			
		||||
                                                       ClutterTexture   *texture);
 | 
			
		||||
ClutterTexture *nbtk_texture_frame_get_parent_texture (NbtkTextureFrame *frame);
 | 
			
		||||
void            nbtk_texture_frame_set_frame          (NbtkTextureFrame *frame,
 | 
			
		||||
                                                       gfloat            top,
 | 
			
		||||
                                                       gfloat            right,
 | 
			
		||||
                                                       gfloat            bottom,
 | 
			
		||||
                                                       gfloat            left);
 | 
			
		||||
void            nbtk_texture_frame_get_frame          (NbtkTextureFrame *frame,
 | 
			
		||||
                                                       gfloat           *top,
 | 
			
		||||
                                                       gfloat           *right,
 | 
			
		||||
                                                       gfloat           *bottom,
 | 
			
		||||
                                                       gfloat           *left);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_TEXTURE_FRAME_H__ */
 | 
			
		||||
							
								
								
									
										664
									
								
								src/nbtk/nbtk-tooltip.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										664
									
								
								src/nbtk/nbtk-tooltip.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,664 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-tooltip.c: Plain tooltip actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:nbtk-tooltip
 | 
			
		||||
 * @short_description: A tooltip widget
 | 
			
		||||
 *
 | 
			
		||||
 * #NbtkTooltip implements a single tooltip. It should not normally be created
 | 
			
		||||
 * by the application but by the widget implementing tooltip capabilities, for
 | 
			
		||||
 * example, #nbtk_button_set_tooltip().
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "nbtk-tooltip.h"
 | 
			
		||||
 | 
			
		||||
#include "nbtk-widget.h"
 | 
			
		||||
#include "nbtk-private.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_LABEL,
 | 
			
		||||
  PROP_TIP_AREA
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define NBTK_TOOLTIP_GET_PRIVATE(obj)    \
 | 
			
		||||
        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_TOOLTIP, NbtkTooltipPrivate))
 | 
			
		||||
 | 
			
		||||
struct _NbtkTooltipPrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *label;
 | 
			
		||||
 | 
			
		||||
  gfloat        arrow_offset;
 | 
			
		||||
  gboolean      actor_below;
 | 
			
		||||
 | 
			
		||||
  ClutterGeometry *tip_area;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (NbtkTooltip, nbtk_tooltip, NBTK_TYPE_WIDGET);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_set_property (GObject      *gobject,
 | 
			
		||||
                           guint         prop_id,
 | 
			
		||||
                           const GValue *value,
 | 
			
		||||
                           GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltip *tooltip = NBTK_TOOLTIP (gobject);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
      nbtk_tooltip_set_label (tooltip, g_value_get_string (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TIP_AREA:
 | 
			
		||||
      nbtk_tooltip_set_tip_area (tooltip, g_value_get_boxed (value));
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_get_property (GObject    *gobject,
 | 
			
		||||
                           guint       prop_id,
 | 
			
		||||
                           GValue     *value,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (gobject)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
      g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->label)));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_TIP_AREA:
 | 
			
		||||
      g_value_set_boxed (value, priv->tip_area);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_style_changed (NbtkWidget *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv;
 | 
			
		||||
  ShellThemeNode *theme_node;
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  const PangoFontDescription *font;
 | 
			
		||||
  gchar *font_string;
 | 
			
		||||
 | 
			
		||||
  priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
  theme_node = nbtk_widget_get_theme_node (self);
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_foreground_color (theme_node, &color);
 | 
			
		||||
  clutter_text_set_color (CLUTTER_TEXT (priv->label), &color);
 | 
			
		||||
 | 
			
		||||
  font = shell_theme_node_get_font (theme_node);
 | 
			
		||||
  font_string = pango_font_description_to_string (font);
 | 
			
		||||
  clutter_text_set_font_name (CLUTTER_TEXT (priv->label), font_string);
 | 
			
		||||
  g_free (font_string);
 | 
			
		||||
 | 
			
		||||
  NBTK_WIDGET_CLASS (nbtk_tooltip_parent_class)->style_changed (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                                  gfloat       for_height,
 | 
			
		||||
                                  gfloat      *min_width_p,
 | 
			
		||||
                                  gfloat      *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (self));
 | 
			
		||||
  gfloat min_label_w, natural_label_w;
 | 
			
		||||
  gfloat label_height, arrow_height;
 | 
			
		||||
  ClutterActor *arrow_image;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_height (theme_node, &for_height);
 | 
			
		||||
 | 
			
		||||
  arrow_image = nbtk_widget_get_background_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (arrow_image)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (arrow_image,
 | 
			
		||||
                                          -1,
 | 
			
		||||
                                          NULL,
 | 
			
		||||
                                          &arrow_height);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      arrow_height = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (for_height > -1)
 | 
			
		||||
    {
 | 
			
		||||
      label_height = for_height - arrow_height;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      label_height = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->label)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_width (priv->label,
 | 
			
		||||
                                         label_height,
 | 
			
		||||
                                         &min_label_w,
 | 
			
		||||
                                         &natural_label_w);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      min_label_w = 0;
 | 
			
		||||
      natural_label_w = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                                   gfloat        for_width,
 | 
			
		||||
                                   gfloat       *min_height_p,
 | 
			
		||||
                                   gfloat       *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (self));
 | 
			
		||||
  gfloat arrow_height;
 | 
			
		||||
  gfloat min_label_h, natural_label_h;
 | 
			
		||||
  ClutterActor *arrow_image;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_for_width (theme_node, &for_width);
 | 
			
		||||
 | 
			
		||||
  arrow_image = nbtk_widget_get_background_image (NBTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  if (arrow_image && !priv->actor_below)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (arrow_image,
 | 
			
		||||
                                          -1,
 | 
			
		||||
                                          NULL,
 | 
			
		||||
                                          &arrow_height);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      arrow_height = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->label)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (priv->label,
 | 
			
		||||
                                          for_width,
 | 
			
		||||
                                          &min_label_h,
 | 
			
		||||
                                          &natural_label_h);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      min_label_h = 0;
 | 
			
		||||
      natural_label_h = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (min_height_p)
 | 
			
		||||
    *min_height_p = arrow_height + min_label_h;
 | 
			
		||||
 | 
			
		||||
  if (natural_height_p)
 | 
			
		||||
    *natural_height_p = arrow_height + natural_label_h;
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_allocate (ClutterActor          *self,
 | 
			
		||||
                       const ClutterActorBox *box,
 | 
			
		||||
                       ClutterAllocationFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
  ShellThemeNode *theme_node = nbtk_widget_get_theme_node (NBTK_WIDGET (self));
 | 
			
		||||
  ClutterActorBox content_box, child_box, arrow_box;
 | 
			
		||||
  gfloat arrow_height, arrow_width;
 | 
			
		||||
  ClutterActor *border_image, *arrow_image;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_tooltip_parent_class)->allocate (self,
 | 
			
		||||
                                                             box,
 | 
			
		||||
                                                             flags);
 | 
			
		||||
 | 
			
		||||
  shell_theme_node_get_content_box (theme_node, box, &content_box);
 | 
			
		||||
 | 
			
		||||
  arrow_image = nbtk_widget_get_background_image (NBTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  if (arrow_image && !priv->actor_below)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_get_preferred_height (arrow_image, -1, NULL, &arrow_height);
 | 
			
		||||
      clutter_actor_get_preferred_width (arrow_image, -1, NULL, &arrow_width);
 | 
			
		||||
 | 
			
		||||
      arrow_box.x1 = (float) (priv->arrow_offset) - (int) (arrow_width / 2);
 | 
			
		||||
      arrow_box.y1 = 0;
 | 
			
		||||
      arrow_box.x2 = arrow_box.x1 + arrow_width;
 | 
			
		||||
      arrow_box.y2 = arrow_box.y1 + arrow_height;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (arrow_image, &arrow_box, flags);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      arrow_height = 0;
 | 
			
		||||
      arrow_width = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  child_box.x1 = child_box.y1 = 0;
 | 
			
		||||
  child_box.x2 = (box->x2 - box->x1);
 | 
			
		||||
  child_box.y2 = (box->y2 - box->y1);
 | 
			
		||||
 | 
			
		||||
  /* remove the space that is used by the arrow */
 | 
			
		||||
  child_box.y1 += arrow_height;
 | 
			
		||||
 | 
			
		||||
  border_image = nbtk_widget_get_border_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (border_image)
 | 
			
		||||
    clutter_actor_allocate (border_image, &child_box, flags);
 | 
			
		||||
 | 
			
		||||
  if (priv->label)
 | 
			
		||||
    {
 | 
			
		||||
      child_box = content_box;
 | 
			
		||||
      child_box.y1 += arrow_height;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (priv->label, &child_box, flags);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_paint (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *border_image, *arrow_image;
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
 | 
			
		||||
  border_image = nbtk_widget_get_border_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (border_image)
 | 
			
		||||
    clutter_actor_paint (border_image);
 | 
			
		||||
 | 
			
		||||
  arrow_image = nbtk_widget_get_background_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (arrow_image && !priv->actor_below)
 | 
			
		||||
    clutter_actor_paint (arrow_image);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_paint (priv->label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_map (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
  ClutterActor *border_image, *arrow_image;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_tooltip_parent_class)->map (self);
 | 
			
		||||
 | 
			
		||||
  border_image = nbtk_widget_get_border_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (border_image)
 | 
			
		||||
    clutter_actor_map (border_image);
 | 
			
		||||
 | 
			
		||||
  arrow_image = nbtk_widget_get_background_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (arrow_image)
 | 
			
		||||
    clutter_actor_map (arrow_image);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_map (priv->label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_unmap (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = NBTK_TOOLTIP (self)->priv;
 | 
			
		||||
  ClutterActor *border_image, *arrow_image;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_tooltip_parent_class)->unmap (self);
 | 
			
		||||
 | 
			
		||||
  border_image = nbtk_widget_get_border_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (border_image)
 | 
			
		||||
    clutter_actor_unmap (border_image);
 | 
			
		||||
 | 
			
		||||
  arrow_image = nbtk_widget_get_background_image (NBTK_WIDGET (self));
 | 
			
		||||
  if (arrow_image)
 | 
			
		||||
    clutter_actor_unmap (arrow_image);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_unmap (priv->label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_class_init (NbtkTooltipClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
  NbtkWidgetClass *widget_class = NBTK_WIDGET_CLASS (klass);
 | 
			
		||||
  GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (NbtkTooltipPrivate));
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = nbtk_tooltip_set_property;
 | 
			
		||||
  gobject_class->get_property = nbtk_tooltip_get_property;
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width = nbtk_tooltip_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = nbtk_tooltip_get_preferred_height;
 | 
			
		||||
  actor_class->allocate = nbtk_tooltip_allocate;
 | 
			
		||||
  actor_class->paint = nbtk_tooltip_paint;
 | 
			
		||||
  actor_class->map = nbtk_tooltip_map;
 | 
			
		||||
  actor_class->unmap = nbtk_tooltip_unmap;
 | 
			
		||||
 | 
			
		||||
  widget_class->style_changed = nbtk_tooltip_style_changed;
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_string ("label",
 | 
			
		||||
                               "Label",
 | 
			
		||||
                               "Label of the tooltip",
 | 
			
		||||
                               NULL, G_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boxed ("tip-area",
 | 
			
		||||
                              "Tip Area",
 | 
			
		||||
                              "Area on the stage the tooltip applies to",
 | 
			
		||||
                              CLUTTER_TYPE_GEOMETRY,
 | 
			
		||||
                              NBTK_PARAM_READWRITE);
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_TIP_AREA, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_init (NbtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
  tooltip->priv = NBTK_TOOLTIP_GET_PRIVATE (tooltip);
 | 
			
		||||
 | 
			
		||||
  tooltip->priv->label = g_object_new (CLUTTER_TYPE_TEXT,
 | 
			
		||||
                                       "line-alignment", PANGO_ALIGN_CENTER,
 | 
			
		||||
                                       "ellipsize", PANGO_ELLIPSIZE_END,
 | 
			
		||||
                                       "use-markup", TRUE,
 | 
			
		||||
                                       NULL);
 | 
			
		||||
 | 
			
		||||
  tooltip->priv->tip_area = NULL;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_parent (CLUTTER_ACTOR (tooltip->priv->label),
 | 
			
		||||
                            CLUTTER_ACTOR (tooltip));
 | 
			
		||||
 | 
			
		||||
  g_object_set (tooltip, "show-on-set-parent", FALSE, NULL);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_reactive (CLUTTER_ACTOR (tooltip), FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_update_position (NbtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv = tooltip->priv;
 | 
			
		||||
  ClutterGeometry *tip_area = tooltip->priv->tip_area;
 | 
			
		||||
  gfloat tooltip_w, tooltip_h, tooltip_x, tooltip_y;
 | 
			
		||||
  gfloat stage_w, stage_h;
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
 | 
			
		||||
  /* ensure the tooltip with is not fixed size */
 | 
			
		||||
  clutter_actor_set_size ((ClutterActor*) tooltip, -1, -1);
 | 
			
		||||
 | 
			
		||||
  /* if no area set, just position ourselves top left */
 | 
			
		||||
  if (!priv->tip_area)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_set_position ((ClutterActor*) tooltip, 0, 0);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* we need to have a style in case there are padding/border values to take into
 | 
			
		||||
   * account when calculating width/height */
 | 
			
		||||
  nbtk_widget_ensure_style ((NbtkWidget *) tooltip);
 | 
			
		||||
 | 
			
		||||
  /* find out the tooltip's size */
 | 
			
		||||
  clutter_actor_get_size ((ClutterActor*) tooltip, &tooltip_w, &tooltip_h);
 | 
			
		||||
 | 
			
		||||
  /* attempt to place the tooltip */
 | 
			
		||||
  tooltip_x = (int) (tip_area->x + (tip_area->width / 2) - (tooltip_w / 2));
 | 
			
		||||
  tooltip_y = (int) (tip_area->y + tip_area->height);
 | 
			
		||||
 | 
			
		||||
  stage = clutter_actor_get_stage ((ClutterActor *) tooltip);
 | 
			
		||||
  if (!stage)
 | 
			
		||||
    {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  clutter_actor_get_size (stage, &stage_w, &stage_h);
 | 
			
		||||
 | 
			
		||||
  /* make sure the tooltip is not off screen vertically */
 | 
			
		||||
  if (tooltip_w > stage_w)
 | 
			
		||||
    {
 | 
			
		||||
      tooltip_x = 0;
 | 
			
		||||
      clutter_actor_set_width ((ClutterActor*) tooltip, stage_w);
 | 
			
		||||
    }
 | 
			
		||||
  else if (tooltip_x < 0)
 | 
			
		||||
    {
 | 
			
		||||
      tooltip_x = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else if (tooltip_x + tooltip_w > stage_w)
 | 
			
		||||
    {
 | 
			
		||||
      tooltip_x = (int) (stage_w) - tooltip_w;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* make sure the tooltip is not off screen horizontally */
 | 
			
		||||
  if (tooltip_y + tooltip_h > stage_h)
 | 
			
		||||
    {
 | 
			
		||||
      priv->actor_below = TRUE;
 | 
			
		||||
 | 
			
		||||
      /* re-query size as may have changed */
 | 
			
		||||
      clutter_actor_get_preferred_height ((ClutterActor*) tooltip,
 | 
			
		||||
                                          -1, NULL, &tooltip_h);
 | 
			
		||||
      tooltip_y = tip_area->y - tooltip_h;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      priv->actor_below = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* calculate the arrow offset */
 | 
			
		||||
  priv->arrow_offset = tip_area->x + tip_area->width / 2 - tooltip_x;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_position ((ClutterActor*) tooltip, tooltip_x, tooltip_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_tooltip_get_label:
 | 
			
		||||
 * @tooltip: a #NbtkTooltip
 | 
			
		||||
 *
 | 
			
		||||
 * Get the text displayed on the tooltip
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the text for the tooltip. This must not be freed by the application
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
nbtk_tooltip_get_label (NbtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_TOOLTIP (tooltip), NULL);
 | 
			
		||||
 | 
			
		||||
  return clutter_text_get_text (CLUTTER_TEXT (tooltip->priv->label));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_tooltip_set_label:
 | 
			
		||||
 * @tooltip: a #NbtkTooltip
 | 
			
		||||
 * @text: text to set the label to
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the text displayed on the tooltip
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_tooltip_set_label (NbtkTooltip *tooltip,
 | 
			
		||||
                        const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_IS_TOOLTIP (tooltip));
 | 
			
		||||
 | 
			
		||||
  priv = tooltip->priv;
 | 
			
		||||
 | 
			
		||||
  clutter_text_set_text (CLUTTER_TEXT (priv->label), text);
 | 
			
		||||
 | 
			
		||||
  g_object_notify (G_OBJECT (tooltip), "label");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_tooltip_show:
 | 
			
		||||
 * @tooltip: a #NbtkTooltip
 | 
			
		||||
 *
 | 
			
		||||
 * Show the tooltip relative to the associated widget.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_tooltip_show (NbtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
  NbtkTooltipPrivate *priv;
 | 
			
		||||
  ClutterActor *parent;
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
  ClutterActor *self = CLUTTER_ACTOR (tooltip);
 | 
			
		||||
  ClutterAnimation *animation;
 | 
			
		||||
 | 
			
		||||
  /* make sure we're not currently already animating (e.g. hiding) */
 | 
			
		||||
  animation = clutter_actor_get_animation (CLUTTER_ACTOR (tooltip));
 | 
			
		||||
  if (animation)
 | 
			
		||||
    clutter_animation_completed (animation);
 | 
			
		||||
 | 
			
		||||
  priv = tooltip->priv;
 | 
			
		||||
  parent = clutter_actor_get_parent (self);
 | 
			
		||||
  stage = clutter_actor_get_stage (self);
 | 
			
		||||
 | 
			
		||||
  if (!stage)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("NbtkTooltip is not on any stage.");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* make sure we're parented on the stage */
 | 
			
		||||
  if (G_UNLIKELY (parent != stage))
 | 
			
		||||
    {
 | 
			
		||||
      g_object_ref (self);
 | 
			
		||||
      clutter_actor_unparent (self);
 | 
			
		||||
      clutter_actor_set_parent (self, stage);
 | 
			
		||||
      g_object_unref (self);
 | 
			
		||||
      parent = stage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* raise the tooltip to the top */
 | 
			
		||||
  clutter_container_raise_child (CLUTTER_CONTAINER (stage),
 | 
			
		||||
                                 CLUTTER_ACTOR (tooltip),
 | 
			
		||||
                                 NULL);
 | 
			
		||||
 | 
			
		||||
  nbtk_tooltip_update_position (tooltip);
 | 
			
		||||
 | 
			
		||||
  /* finally show the tooltip... */
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_tooltip_parent_class)->show (self);
 | 
			
		||||
 | 
			
		||||
  /* and give it some bounce! */
 | 
			
		||||
  g_object_set (G_OBJECT (self),
 | 
			
		||||
                "scale-center-x", priv->arrow_offset,
 | 
			
		||||
                "scale-center-y", (priv->actor_below) ? clutter_actor_get_height (self) : 0,
 | 
			
		||||
                NULL);
 | 
			
		||||
  clutter_actor_set_scale (self, 0.0, 0.0);
 | 
			
		||||
  clutter_actor_animate (self, CLUTTER_EASE_OUT_ELASTIC,
 | 
			
		||||
                         500,
 | 
			
		||||
                         "scale-x", 1.0,
 | 
			
		||||
                         "scale-y", 1.0,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
nbtk_tooltip_hide_complete (ClutterAnimation *animation,
 | 
			
		||||
                            ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (nbtk_tooltip_parent_class)->hide (actor);
 | 
			
		||||
  g_signal_handlers_disconnect_by_func (actor,
 | 
			
		||||
                                        nbtk_tooltip_hide_complete,
 | 
			
		||||
                                        actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_tooltip_hide:
 | 
			
		||||
 * @tooltip: a #NbtkTooltip
 | 
			
		||||
 *
 | 
			
		||||
 * Hide the tooltip
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_tooltip_hide (NbtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
  ClutterAnimation *animation;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (NBTK_TOOLTIP (tooltip));
 | 
			
		||||
 | 
			
		||||
  /* make sure we're not currently already animating (e.g. hiding) */
 | 
			
		||||
  animation = clutter_actor_get_animation (CLUTTER_ACTOR (tooltip));
 | 
			
		||||
  if (animation)
 | 
			
		||||
    clutter_animation_completed (animation);
 | 
			
		||||
 | 
			
		||||
  g_object_set (G_OBJECT (tooltip),
 | 
			
		||||
                "scale-center-x", tooltip->priv->arrow_offset,
 | 
			
		||||
                NULL);
 | 
			
		||||
  animation =
 | 
			
		||||
    clutter_actor_animate (CLUTTER_ACTOR (tooltip), CLUTTER_EASE_IN_SINE,
 | 
			
		||||
                           150,
 | 
			
		||||
                           "scale-x", 0.0,
 | 
			
		||||
                           "scale-y", 0.0,
 | 
			
		||||
                           NULL);
 | 
			
		||||
  g_signal_connect (animation, "completed",
 | 
			
		||||
                    G_CALLBACK (nbtk_tooltip_hide_complete), tooltip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_tooltip_set_tip_area:
 | 
			
		||||
 * @tooltip: A #NbtkTooltip
 | 
			
		||||
 * @area: A #ClutterGeometry
 | 
			
		||||
 *
 | 
			
		||||
 * Set the area on the stage that the tooltip applies to.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
nbtk_tooltip_set_tip_area (NbtkTooltip           *tooltip,
 | 
			
		||||
                           const ClutterGeometry *area)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (NBTK_IS_TOOLTIP (tooltip));
 | 
			
		||||
 | 
			
		||||
  if (tooltip->priv->tip_area)
 | 
			
		||||
    g_boxed_free (CLUTTER_TYPE_GEOMETRY, tooltip->priv->tip_area);
 | 
			
		||||
  tooltip->priv->tip_area = g_boxed_copy (CLUTTER_TYPE_GEOMETRY, area);
 | 
			
		||||
 | 
			
		||||
  nbtk_tooltip_update_position (tooltip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * nbtk_tooltip_get_tip_area:
 | 
			
		||||
 * @tooltip: A #NbtkTooltip
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve the area on the stage that the tooltip currently applies to
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the #ClutterGeometry, owned by the tooltip which must not be freed
 | 
			
		||||
 * by the application.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN ClutterGeometry*
 | 
			
		||||
nbtk_tooltip_get_tip_area (NbtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (NBTK_IS_TOOLTIP (tooltip), NULL);
 | 
			
		||||
 | 
			
		||||
  return tooltip->priv->tip_area;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								src/nbtk/nbtk-tooltip.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/nbtk/nbtk-tooltip.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-tooltip.h: Plain tooltip actor
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by: Thomas Wood <thomas@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_TOOLTIP_H__
 | 
			
		||||
#define __NBTK_TOOLTIP_H__
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#include <nbtk/nbtk-bin.h>
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_TOOLTIP                (nbtk_tooltip_get_type ())
 | 
			
		||||
#define NBTK_TOOLTIP(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_TOOLTIP, NbtkTooltip))
 | 
			
		||||
#define NBTK_IS_TOOLTIP(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_TOOLTIP))
 | 
			
		||||
#define NBTK_TOOLTIP_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_TOOLTIP, NbtkTooltipClass))
 | 
			
		||||
#define NBTK_IS_TOOLTIP_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_TOOLTIP))
 | 
			
		||||
#define NBTK_TOOLTIP_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_TOOLTIP, NbtkTooltipClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkTooltip              NbtkTooltip;
 | 
			
		||||
typedef struct _NbtkTooltipPrivate       NbtkTooltipPrivate;
 | 
			
		||||
typedef struct _NbtkTooltipClass         NbtkTooltipClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkTooltip:
 | 
			
		||||
 *
 | 
			
		||||
 * The contents of this structure is private and should only be accessed using
 | 
			
		||||
 * the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkTooltip
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  NbtkBin parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkTooltipPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _NbtkTooltipClass
 | 
			
		||||
{
 | 
			
		||||
  NbtkBinClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_tooltip_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_tooltip_get_label (NbtkTooltip *tooltip);
 | 
			
		||||
void                  nbtk_tooltip_set_label (NbtkTooltip *tooltip,
 | 
			
		||||
                                              const gchar *text);
 | 
			
		||||
void                  nbtk_tooltip_show      (NbtkTooltip *tooltip);
 | 
			
		||||
void                  nbtk_tooltip_hide      (NbtkTooltip *tooltip);
 | 
			
		||||
 | 
			
		||||
void                  nbtk_tooltip_set_tip_area (NbtkTooltip *tooltip, const ClutterGeometry *area);
 | 
			
		||||
G_CONST_RETURN ClutterGeometry* nbtk_tooltip_get_tip_area (NbtkTooltip *tooltip);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_TOOLTIP_H__ */
 | 
			
		||||
							
								
								
									
										59
									
								
								src/nbtk/nbtk-types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/nbtk/nbtk-types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_TYPES_H__
 | 
			
		||||
#define __NBTK_TYPES_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_PADDING               (nbtk_padding_get_type ())
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkAlignment:
 | 
			
		||||
 * @NBTK_ALIGN_TOP: align to the top (vertically)
 | 
			
		||||
 * @NBTK_ALIGN_RIGHT: align to the right (horizontally)
 | 
			
		||||
 * @NBTK_ALIGN_BOTTOM: align to the bottom (vertically)
 | 
			
		||||
 * @NBTK_ALIGN_LEFT: align to the left (horizontally)
 | 
			
		||||
 * @NBTK_ALIGN_CENTER: align to the center (horizontally or vertically)
 | 
			
		||||
 *
 | 
			
		||||
 * The alignment values for a #NbtkBin.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
  NBTK_ALIGN_TOP,
 | 
			
		||||
  NBTK_ALIGN_RIGHT,
 | 
			
		||||
  NBTK_ALIGN_BOTTOM,
 | 
			
		||||
  NBTK_ALIGN_LEFT,
 | 
			
		||||
  NBTK_ALIGN_CENTER
 | 
			
		||||
} NbtkAlignment;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  NBTK_ALIGN_START,
 | 
			
		||||
  NBTK_ALIGN_MIDDLE,
 | 
			
		||||
  NBTK_ALIGN_END
 | 
			
		||||
} NbtkAlign;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_TYPES_H__ */
 | 
			
		||||
							
								
								
									
										1378
									
								
								src/nbtk/nbtk-widget.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1378
									
								
								src/nbtk/nbtk-widget.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										116
									
								
								src/nbtk/nbtk-widget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/nbtk/nbtk-widget.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
/*
 | 
			
		||||
 * nbtk-widget.h: Base class for Nbtk actors
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007 OpenedHand
 | 
			
		||||
 * Copyright 2008, 2009 Intel Corporation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms and conditions of the GNU Lesser General Public License,
 | 
			
		||||
 * version 2.1, as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(NBTK_H_INSIDE) && !defined(NBTK_COMPILATION)
 | 
			
		||||
#error "Only <nbtk/nbtk.h> can be included directly.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __NBTK_WIDGET_H__
 | 
			
		||||
#define __NBTK_WIDGET_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <nbtk/nbtk-types.h>
 | 
			
		||||
#include <toolkit/shell-theme.h>
 | 
			
		||||
#include <toolkit/shell-theme-node.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define NBTK_TYPE_WIDGET                 (nbtk_widget_get_type ())
 | 
			
		||||
#define NBTK_WIDGET(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), NBTK_TYPE_WIDGET, NbtkWidget))
 | 
			
		||||
#define NBTK_IS_WIDGET(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NBTK_TYPE_WIDGET))
 | 
			
		||||
#define NBTK_WIDGET_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), NBTK_TYPE_WIDGET, NbtkWidgetClass))
 | 
			
		||||
#define NBTK_IS_WIDGET_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), NBTK_TYPE_WIDGET))
 | 
			
		||||
#define NBTK_WIDGET_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), NBTK_TYPE_WIDGET, NbtkWidgetClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _NbtkWidget               NbtkWidget;
 | 
			
		||||
typedef struct _NbtkWidgetPrivate        NbtkWidgetPrivate;
 | 
			
		||||
typedef struct _NbtkWidgetClass          NbtkWidgetClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkWidget:
 | 
			
		||||
 *
 | 
			
		||||
 * Base class for stylable actors. The contents of the #NbtkWidget
 | 
			
		||||
 * structure are private and should only be accessed through the
 | 
			
		||||
 * public API.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkWidget
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActor parent_instance;
 | 
			
		||||
 | 
			
		||||
  NbtkWidgetPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * NbtkWidgetClass:
 | 
			
		||||
 *
 | 
			
		||||
 * Base class for stylable actors.
 | 
			
		||||
 */
 | 
			
		||||
struct _NbtkWidgetClass
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActorClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* vfuncs */
 | 
			
		||||
  void (* draw_background) (NbtkWidget         *self);
 | 
			
		||||
  void (* style_changed)   (NbtkWidget         *self);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType nbtk_widget_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void                  nbtk_widget_set_style_pseudo_class (NbtkWidget   *actor,
 | 
			
		||||
                                                          const gchar  *pseudo_class);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_widget_get_style_pseudo_class (NbtkWidget   *actor);
 | 
			
		||||
void                  nbtk_widget_set_style_class_name   (NbtkWidget   *actor,
 | 
			
		||||
                                                          const gchar  *style_class);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_widget_get_style_class_name   (NbtkWidget   *actor);
 | 
			
		||||
void                  nbtk_widget_set_style              (NbtkWidget   *actor,
 | 
			
		||||
							  const gchar  *style);
 | 
			
		||||
G_CONST_RETURN gchar *nbtk_widget_get_style              (NbtkWidget   *actor);
 | 
			
		||||
 | 
			
		||||
void        nbtk_widget_set_theme (NbtkWidget *actor,
 | 
			
		||||
				   ShellTheme *theme);
 | 
			
		||||
ShellTheme *nbtk_widget_get_theme (NbtkWidget *actor);
 | 
			
		||||
 | 
			
		||||
void     nbtk_widget_set_has_tooltip (NbtkWidget *widget, gboolean has_tooltip);
 | 
			
		||||
gboolean nbtk_widget_get_has_tooltip (NbtkWidget *widget);
 | 
			
		||||
void     nbtk_widget_set_tooltip_text (NbtkWidget *widget, const gchar *text);
 | 
			
		||||
const gchar* nbtk_widget_get_tooltip_text (NbtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
void nbtk_widget_show_tooltip (NbtkWidget *widget);
 | 
			
		||||
void nbtk_widget_hide_tooltip (NbtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
void nbtk_widget_ensure_style (NbtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Only to be used by sub-classes of NbtkWidget */
 | 
			
		||||
void          nbtk_widget_style_changed        (NbtkWidget  *widget);
 | 
			
		||||
 | 
			
		||||
ShellThemeNode *nbtk_widget_get_theme_node     (NbtkWidget  *widget);
 | 
			
		||||
 | 
			
		||||
ClutterActor *nbtk_widget_get_background_image (NbtkWidget  *actor);
 | 
			
		||||
ClutterActor *nbtk_widget_get_border_image     (NbtkWidget  *actor);
 | 
			
		||||
void          nbtk_widget_draw_background      (NbtkWidget  *widget);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __NBTK_WIDGET_H__ */
 | 
			
		||||
@@ -40,6 +40,7 @@ struct _ShellGlobal {
 | 
			
		||||
  
 | 
			
		||||
  MutterPlugin *plugin;
 | 
			
		||||
  ShellWM *wm;
 | 
			
		||||
  const char *datadir;
 | 
			
		||||
  const char *imagedir;
 | 
			
		||||
  const char *configdir;
 | 
			
		||||
 | 
			
		||||
@@ -57,6 +58,7 @@ enum {
 | 
			
		||||
  PROP_STAGE,
 | 
			
		||||
  PROP_WINDOW_GROUP,
 | 
			
		||||
  PROP_WINDOW_MANAGER,
 | 
			
		||||
  PROP_DATADIR,
 | 
			
		||||
  PROP_IMAGEDIR,
 | 
			
		||||
  PROP_CONFIGDIR,
 | 
			
		||||
};
 | 
			
		||||
@@ -128,6 +130,9 @@ shell_global_get_property(GObject         *object,
 | 
			
		||||
    case PROP_WINDOW_MANAGER:
 | 
			
		||||
      g_value_set_object (value, global->wm);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DATADIR:
 | 
			
		||||
      g_value_set_string (value, global->datadir);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_IMAGEDIR:
 | 
			
		||||
      g_value_set_string (value, global->imagedir);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -149,6 +154,7 @@ shell_global_init (ShellGlobal *global)
 | 
			
		||||
 | 
			
		||||
  if (!datadir)
 | 
			
		||||
    datadir = GNOME_SHELL_DATADIR;
 | 
			
		||||
  global->datadir = datadir;
 | 
			
		||||
 | 
			
		||||
  /* We make sure imagedir ends with a '/', since the JS won't have
 | 
			
		||||
   * access to g_build_filename() and so will end up just
 | 
			
		||||
@@ -254,6 +260,13 @@ shell_global_class_init (ShellGlobalClass *klass)
 | 
			
		||||
                                                        "Window management interface",
 | 
			
		||||
                                                        SHELL_TYPE_WM,
 | 
			
		||||
                                                        G_PARAM_READABLE));
 | 
			
		||||
  g_object_class_install_property (gobject_class,
 | 
			
		||||
                                   PROP_DATADIR,
 | 
			
		||||
                                   g_param_spec_string ("datadir",
 | 
			
		||||
                                                        "Data directory",
 | 
			
		||||
                                                        "Directory containing gnome-shell data files",
 | 
			
		||||
                                                        NULL,
 | 
			
		||||
                                                        G_PARAM_READABLE));
 | 
			
		||||
  g_object_class_install_property (gobject_class,
 | 
			
		||||
                                   PROP_IMAGEDIR,
 | 
			
		||||
                                   g_param_spec_string ("imagedir",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,240 +0,0 @@
 | 
			
		||||
#include "shell-panel-window.h"
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
 | 
			
		||||
#define PANEL_HEIGHT 25
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
   PROP_0,
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void shell_panel_window_finalize (GObject *object);
 | 
			
		||||
static void shell_panel_window_size_request (GtkWidget *self, GtkRequisition *req);
 | 
			
		||||
static void shell_panel_window_size_allocate (GtkWidget *self, GtkAllocation *allocation);
 | 
			
		||||
static void shell_panel_window_realize (GtkWidget *self);
 | 
			
		||||
static void shell_panel_window_show (GtkWidget *self);
 | 
			
		||||
static void set_strut (ShellPanelWindow *self);
 | 
			
		||||
static void on_workarea_changed (ShellPanelWindow *self);
 | 
			
		||||
static void handle_new_workarea (ShellPanelWindow *self);
 | 
			
		||||
static GdkFilterReturn filter_func (GdkXEvent *xevent,
 | 
			
		||||
				    GdkEvent *event,
 | 
			
		||||
				    gpointer data);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(ShellPanelWindow, shell_panel_window, GTK_TYPE_WINDOW);
 | 
			
		||||
 | 
			
		||||
struct ShellPanelWindowPrivate {
 | 
			
		||||
  GtkAllocation workarea;
 | 
			
		||||
  guint width;
 | 
			
		||||
  guint height;
 | 
			
		||||
  Atom workarea_atom;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_panel_window_class_init(ShellPanelWindowClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = (GObjectClass *)klass;
 | 
			
		||||
    GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
 | 
			
		||||
 | 
			
		||||
    gobject_class->finalize = shell_panel_window_finalize;
 | 
			
		||||
    
 | 
			
		||||
    widget_class->realize = shell_panel_window_realize;
 | 
			
		||||
    widget_class->size_request = shell_panel_window_size_request;    
 | 
			
		||||
    widget_class->size_allocate = shell_panel_window_size_allocate;
 | 
			
		||||
    widget_class->show = shell_panel_window_show;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void shell_panel_window_init (ShellPanelWindow *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = g_new0 (ShellPanelWindowPrivate, 1);
 | 
			
		||||
 | 
			
		||||
  self->priv->workarea_atom = gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (), "_NET_WORKAREA");
 | 
			
		||||
  
 | 
			
		||||
  gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_DOCK);
 | 
			
		||||
  gtk_window_set_focus_on_map (GTK_WINDOW (self), FALSE);
 | 
			
		||||
  gdk_window_add_filter (NULL, filter_func, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void shell_panel_window_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    ShellPanelWindow *self = (ShellPanelWindow*)object;
 | 
			
		||||
 | 
			
		||||
    g_free (self->priv);
 | 
			
		||||
    g_signal_handlers_destroy(object);
 | 
			
		||||
    G_OBJECT_CLASS (shell_panel_window_parent_class)->finalize(object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ShellPanelWindow* shell_panel_window_new(void) {
 | 
			
		||||
    return (ShellPanelWindow*) g_object_new(SHELL_TYPE_PANEL_WINDOW, 
 | 
			
		||||
        "type", GTK_WINDOW_TOPLEVEL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_strut (ShellPanelWindow *self)
 | 
			
		||||
{
 | 
			
		||||
  long *buf;
 | 
			
		||||
  int strut_size;
 | 
			
		||||
 | 
			
		||||
  strut_size = GTK_WIDGET (self)->allocation.height;
 | 
			
		||||
 | 
			
		||||
  buf = g_new0 (long, 4);
 | 
			
		||||
  buf[0] = 0; /* left */
 | 
			
		||||
  buf[1] = 0; /* right */
 | 
			
		||||
  buf[2] = 0; /* top */
 | 
			
		||||
  buf[3] = strut_size; /* bottom */
 | 
			
		||||
  gdk_property_change (GTK_WIDGET (self)->window, gdk_atom_intern_static_string ("_NET_WM_STRUT"),
 | 
			
		||||
		       gdk_atom_intern_static_string ("CARDINAL"), 32,
 | 
			
		||||
		       GDK_PROP_MODE_REPLACE,
 | 
			
		||||
		       (guchar*) buf, 4);
 | 
			
		||||
  g_free (buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_panel_window_size_request (GtkWidget *widget, GtkRequisition *requisition)
 | 
			
		||||
{
 | 
			
		||||
  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);  
 | 
			
		||||
  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->size_request(widget, requisition);  
 | 
			
		||||
  requisition->width = self->priv->width;
 | 
			
		||||
  requisition->height = PANEL_HEIGHT; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_panel_window_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);
 | 
			
		||||
  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->size_allocate(widget, allocation);
 | 
			
		||||
  if (GTK_WIDGET_REALIZED (self))
 | 
			
		||||
    set_strut (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_panel_window_realize (GtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);
 | 
			
		||||
  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->realize(widget);
 | 
			
		||||
  set_strut (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_panel_window_show (GtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);
 | 
			
		||||
  on_workarea_changed (self);
 | 
			
		||||
  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->show(widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_new_workarea (ShellPanelWindow *self)
 | 
			
		||||
{
 | 
			
		||||
  GtkRequisition requisition;
 | 
			
		||||
  int x, y;
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
  int x_target, y_target;
 | 
			
		||||
 | 
			
		||||
  gtk_widget_size_request (GTK_WIDGET (self), &requisition);
 | 
			
		||||
 | 
			
		||||
  /* If we don't have a workarea, just use monitor */
 | 
			
		||||
  if (self->priv->workarea.width == 0) 
 | 
			
		||||
    {
 | 
			
		||||
      int monitor;
 | 
			
		||||
      GdkRectangle monitor_geometry;      
 | 
			
		||||
      
 | 
			
		||||
      monitor = gdk_screen_get_monitor_at_point (gdk_screen_get_default (),
 | 
			
		||||
                                                 0, 0);
 | 
			
		||||
      gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
 | 
			
		||||
                                       monitor, &monitor_geometry);      
 | 
			
		||||
      x = monitor_geometry.x;
 | 
			
		||||
      y = monitor_geometry.y;
 | 
			
		||||
      width = monitor_geometry.width;
 | 
			
		||||
      height = monitor_geometry.height;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      x = self->priv->workarea.x;
 | 
			
		||||
      y = self->priv->workarea.y;
 | 
			
		||||
      width = self->priv->workarea.width;
 | 
			
		||||
      height = self->priv->workarea.height;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  x_target = x;
 | 
			
		||||
  y_target = y + height - requisition.height;
 | 
			
		||||
 | 
			
		||||
  self->priv->width = width;
 | 
			
		||||
  self->priv->height = height;
 | 
			
		||||
  gtk_widget_set_size_request (GTK_WIDGET (self), width - x_target, PANEL_HEIGHT);
 | 
			
		||||
  gtk_window_move (GTK_WINDOW (self), x_target, y_target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_workarea_changed (ShellPanelWindow *self)
 | 
			
		||||
{
 | 
			
		||||
  gulong bytes_after, nitems;
 | 
			
		||||
  Atom type;
 | 
			
		||||
  gint format;
 | 
			
		||||
  guchar *data;
 | 
			
		||||
  long *data32;
 | 
			
		||||
  Atom workarea = gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (), "_NET_WORKAREA");
 | 
			
		||||
 | 
			
		||||
  XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
 | 
			
		||||
		      workarea,
 | 
			
		||||
		      0, 4, FALSE, workarea,
 | 
			
		||||
		      &type, &format, &nitems, &bytes_after, &data);
 | 
			
		||||
  if ((format == 32) && (nitems == 4) && (bytes_after == 0))
 | 
			
		||||
    {
 | 
			
		||||
      int x, y, width, height;
 | 
			
		||||
      data32 = (long*) data;
 | 
			
		||||
      x = data32[0];
 | 
			
		||||
      y = data32[1];
 | 
			
		||||
      width = data32[2];
 | 
			
		||||
      height = data32[3];
 | 
			
		||||
      if (x == self->priv->workarea.x && y == self->priv->workarea.y 
 | 
			
		||||
          && width == self->priv->workarea.width 
 | 
			
		||||
          && height == self->priv->workarea.height)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      self->priv->workarea.x = x;
 | 
			
		||||
      self->priv->workarea.y = y;
 | 
			
		||||
      self->priv->workarea.width = width;
 | 
			
		||||
      self->priv->workarea.height = height;
 | 
			
		||||
 | 
			
		||||
      handle_new_workarea (self);
 | 
			
		||||
    }
 | 
			
		||||
  else if (nitems == 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* We have no workarea set; assume there are no other panels at this time */
 | 
			
		||||
      self->priv->workarea.x = self->priv->workarea.y = 0;
 | 
			
		||||
      self->priv->workarea.width = self->priv->workarea.height = 0;
 | 
			
		||||
      handle_new_workarea (self);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_printerr ("unexpected return from XGetWindowProperty: %d %ld %ld\n",
 | 
			
		||||
          format, nitems, bytes_after);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GdkFilterReturn
 | 
			
		||||
filter_func (GdkXEvent *gdk_xevent,
 | 
			
		||||
	     GdkEvent *event,
 | 
			
		||||
	     gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  ShellPanelWindow *self = SHELL_PANEL_WINDOW (data);
 | 
			
		||||
  GdkFilterReturn ret = GDK_FILTER_CONTINUE;
 | 
			
		||||
  XEvent *xevent = (XEvent *) event;
 | 
			
		||||
 | 
			
		||||
  switch (xevent->type) 
 | 
			
		||||
  {
 | 
			
		||||
  case PropertyNotify:
 | 
			
		||||
    {
 | 
			
		||||
      if (xevent->xproperty.atom != self->priv->workarea_atom)
 | 
			
		||||
	break;
 | 
			
		||||
      on_workarea_changed (self);
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
#ifndef __SHELL_PANEL_WINDOW_H__
 | 
			
		||||
#define __SHELL_PANEL_WINDOW_H__
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#define SHELL_TYPE_PANEL_WINDOW                 (shell_panel_window_get_type ())
 | 
			
		||||
#define SHELL_PANEL_WINDOW(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_PANEL_WINDOW, ShellPanelWindow))
 | 
			
		||||
#define SHELL_PANEL_WINDOW_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_PANEL_WINDOW, ShellPanelWindowClass))
 | 
			
		||||
#define SHELL_IS_PANEL_WINDOW(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_PANEL_WINDOW))
 | 
			
		||||
#define SHELL_IS_PANEL_WINDOW_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_PANEL_WINDOW))
 | 
			
		||||
#define SHELL_PANEL_WINDOW_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_PANEL_WINDOW, ShellPanelWindowClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _ShellPanelWindow ShellPanelWindow;
 | 
			
		||||
typedef struct _ShellPanelWindowClass ShellPanelWindowClass;
 | 
			
		||||
 | 
			
		||||
typedef struct ShellPanelWindowPrivate ShellPanelWindowPrivate;
 | 
			
		||||
 | 
			
		||||
struct _ShellPanelWindow
 | 
			
		||||
{
 | 
			
		||||
    GtkWindow parent;
 | 
			
		||||
 | 
			
		||||
    ShellPanelWindowPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ShellPanelWindowClass
 | 
			
		||||
{
 | 
			
		||||
    GtkWindowClass parent_class;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType shell_panel_window_get_type (void) G_GNUC_CONST;
 | 
			
		||||
ShellPanelWindow* shell_panel_window_new(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_PANEL_WINDOW_H__ */
 | 
			
		||||
							
								
								
									
										92
									
								
								src/toolkit/shell-border-image.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/toolkit/shell-border-image.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "shell-border-image.h"
 | 
			
		||||
 | 
			
		||||
struct _ShellBorderImage {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  char *filename;
 | 
			
		||||
  int border_top;
 | 
			
		||||
  int border_right;
 | 
			
		||||
  int border_bottom;
 | 
			
		||||
  int border_left;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ShellBorderImageClass {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (ShellBorderImage, shell_border_image, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_border_image_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ShellBorderImage *image = SHELL_BORDER_IMAGE (object);
 | 
			
		||||
 | 
			
		||||
  g_free (image->filename);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (shell_border_image_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_border_image_class_init (ShellBorderImageClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = shell_border_image_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_border_image_init (ShellBorderImage *image)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ShellBorderImage *
 | 
			
		||||
shell_border_image_new (const char *filename,
 | 
			
		||||
                       int         border_top,
 | 
			
		||||
                       int         border_right,
 | 
			
		||||
                       int         border_bottom,
 | 
			
		||||
                       int         border_left)
 | 
			
		||||
{
 | 
			
		||||
  ShellBorderImage *image;
 | 
			
		||||
 | 
			
		||||
  image = g_object_new (SHELL_TYPE_BORDER_IMAGE, NULL);
 | 
			
		||||
 | 
			
		||||
  image->filename = g_strdup (filename);
 | 
			
		||||
  image->border_top = border_top;
 | 
			
		||||
  image->border_right = border_right;
 | 
			
		||||
  image->border_bottom = border_bottom;
 | 
			
		||||
  image->border_left = border_left;
 | 
			
		||||
 | 
			
		||||
  return image;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
shell_border_image_get_filename (ShellBorderImage *image)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (SHELL_IS_BORDER_IMAGE (image), NULL);
 | 
			
		||||
 | 
			
		||||
  return image->filename;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
shell_border_image_get_borders (ShellBorderImage *image,
 | 
			
		||||
                                int              *border_top,
 | 
			
		||||
                                int              *border_right,
 | 
			
		||||
                                int              *border_bottom,
 | 
			
		||||
                                int              *border_left)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (SHELL_IS_BORDER_IMAGE (image));
 | 
			
		||||
 | 
			
		||||
  if (border_top)
 | 
			
		||||
    *border_top = image->border_top;
 | 
			
		||||
  if (border_right)
 | 
			
		||||
    *border_right = image->border_right;
 | 
			
		||||
  if (border_bottom)
 | 
			
		||||
    *border_bottom = image->border_bottom;
 | 
			
		||||
  if (border_left)
 | 
			
		||||
    *border_left = image->border_left;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/toolkit/shell-border-image.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/toolkit/shell-border-image.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __SHELL_BORDER_IMAGE_H__
 | 
			
		||||
#define __SHELL_BORDER_IMAGE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/* A ShellBorderImage encapsulates an image with specified unscaled borders on each edge.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _ShellBorderImage      ShellBorderImage;
 | 
			
		||||
typedef struct _ShellBorderImageClass ShellBorderImageClass;
 | 
			
		||||
 | 
			
		||||
#define SHELL_TYPE_BORDER_IMAGE             (shell_border_image_get_type ())
 | 
			
		||||
#define SHELL_BORDER_IMAGE(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_BORDER_IMAGE, ShellBorderImage))
 | 
			
		||||
#define SHELL_BORDER_IMAGE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_BORDER_IMAGE, ShellBorderImageClass))
 | 
			
		||||
#define SHELL_IS_BORDER_IMAGE(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_BORDER_IMAGE))
 | 
			
		||||
#define SHELL_IS_BORDER_IMAGE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_BORDER_IMAGE))
 | 
			
		||||
#define SHELL_BORDER_IMAGE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_BORDER_IMAGE, ShellBorderImageClass))
 | 
			
		||||
 | 
			
		||||
GType             shell_border_image_get_type          (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
ShellBorderImage *shell_border_image_new (const char *filename,
 | 
			
		||||
                                          int         border_top,
 | 
			
		||||
                                          int         border_right,
 | 
			
		||||
                                          int         border_bottom,
 | 
			
		||||
                                          int         border_left);
 | 
			
		||||
 | 
			
		||||
const char *shell_border_image_get_filename (ShellBorderImage *image);
 | 
			
		||||
void        shell_border_image_get_borders  (ShellBorderImage *image,
 | 
			
		||||
                                             int             *border_top,
 | 
			
		||||
                                             int             *border_right,
 | 
			
		||||
                                             int             *border_bottom,
 | 
			
		||||
                                             int             *border_left);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_BORDER_IMAGE_H__ */
 | 
			
		||||
							
								
								
									
										218
									
								
								src/toolkit/shell-theme-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								src/toolkit/shell-theme-context.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "shell-theme.h"
 | 
			
		||||
#include "shell-theme-context.h"
 | 
			
		||||
 | 
			
		||||
struct _ShellThemeContext {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  double resolution;
 | 
			
		||||
  PangoFontDescription *font;
 | 
			
		||||
  ShellThemeNode *root_node;
 | 
			
		||||
  ShellTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _ShellThemeContextClass {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CHANGED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (ShellThemeContext, shell_theme_context, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_theme_context_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ShellThemeContext *context = SHELL_THEME_CONTEXT (object);
 | 
			
		||||
 | 
			
		||||
  if (context->root_node)
 | 
			
		||||
    g_object_unref (context->root_node);
 | 
			
		||||
  if (context->theme)
 | 
			
		||||
    g_object_unref (context->theme);
 | 
			
		||||
  
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (shell_theme_context_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_theme_context_class_init (ShellThemeContextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = shell_theme_context_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new ("changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, /* no default handler slot */
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shell_theme_context_init (ShellThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  context->resolution = 96.;
 | 
			
		||||
  context->font = pango_font_description_from_string ("sans-serif 10");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ShellThemeContext *
 | 
			
		||||
shell_theme_context_new (void)
 | 
			
		||||
{
 | 
			
		||||
  ShellThemeContext *context;
 | 
			
		||||
 | 
			
		||||
  context = g_object_new (SHELL_TYPE_THEME_CONTEXT, NULL);
 | 
			
		||||
 | 
			
		||||
  return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_stage_destroy (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  ShellThemeContext *context = shell_theme_context_get_for_stage (stage);
 | 
			
		||||
 | 
			
		||||
  g_object_set_data (G_OBJECT (stage), "shell-theme-context", NULL);
 | 
			
		||||
  g_object_unref (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * shell_theme_context_get_for_stage:
 | 
			
		||||
 * @stage: a #ClutterStage
 | 
			
		||||
 *
 | 
			
		||||
 * Gets a singleton theme context associated with the stage.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the singleton theme context for the stage
 | 
			
		||||
 */
 | 
			
		||||
ShellThemeContext *
 | 
			
		||||
shell_theme_context_get_for_stage (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  ShellThemeContext *context;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
 | 
			
		||||
 | 
			
		||||
  context = g_object_get_data (G_OBJECT (stage), "shell-theme-context");
 | 
			
		||||
  if (context)
 | 
			
		||||
    return context;
 | 
			
		||||
 | 
			
		||||
  context = shell_theme_context_new ();
 | 
			
		||||
  g_object_set_data (G_OBJECT (stage), "shell-theme-context", context);
 | 
			
		||||
  g_signal_connect (stage, "destroy",
 | 
			
		||||
                    G_CALLBACK (on_stage_destroy), NULL);
 | 
			
		||||
 | 
			
		||||
  return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * shell_theme_context_set_theme:
 | 
			
		||||
 * @context: a #ShellThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default set of theme stylesheets for the context. This theme will
 | 
			
		||||
 * be used for the root node and for nodes descending from it, unless some other
 | 
			
		||||
 * style is explicitely specified.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
shell_theme_context_set_theme (ShellThemeContext          *context,
 | 
			
		||||
                               ShellTheme                 *theme)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (SHELL_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (theme == NULL || SHELL_IS_THEME (theme));
 | 
			
		||||
 | 
			
		||||
  if (context->theme != theme)
 | 
			
		||||
    {
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
      context->theme = theme;
 | 
			
		||||
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_ref (context->theme);
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (context, signals[CHANGED], 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * shell_theme_context_get_theme:
 | 
			
		||||
 * @context: a #ShellThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default theme for the context. See shell_theme_context_set_theme()
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the default theme for the context
 | 
			
		||||
 */
 | 
			
		||||
ShellTheme *
 | 
			
		||||
shell_theme_context_get_theme (ShellThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (SHELL_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
shell_theme_context_set_resolution (ShellThemeContext *context,
 | 
			
		||||
                                    double             resolution)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (SHELL_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  context->resolution = resolution;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double
 | 
			
		||||
shell_theme_context_get_resolution (ShellThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (SHELL_IS_THEME_CONTEXT (context), 96.);
 | 
			
		||||
 | 
			
		||||
  return context->resolution;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
shell_theme_context_set_font (ShellThemeContext          *context,
 | 
			
		||||
                              const PangoFontDescription *font)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (SHELL_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (context->font == font)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
  context->font = pango_font_description_copy (font);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PangoFontDescription *
 | 
			
		||||
shell_theme_context_get_font (ShellThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (SHELL_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->font;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * shell_theme_context_get_root_node:
 | 
			
		||||
 * @context: a #ShellThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the root node of the tree of theme style nodes that associated with this
 | 
			
		||||
 * context. For the node tree associated with a stage, this node represents
 | 
			
		||||
 * styles applied to the stage itself.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the root node of the context's style tree
 | 
			
		||||
 */
 | 
			
		||||
ShellThemeNode *
 | 
			
		||||
shell_theme_context_get_root_node (ShellThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  if (context->root_node == NULL)
 | 
			
		||||
    context->root_node = shell_theme_node_new (context, NULL, context->theme,
 | 
			
		||||
                                               G_TYPE_NONE, NULL, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return context->root_node;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/toolkit/shell-theme-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/toolkit/shell-theme-context.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __SHELL_THEME_CONTEXT_H__
 | 
			
		||||
#define __SHELL_THEME_CONTEXT_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "shell-theme-node.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _ShellThemeContextClass ShellThemeContextClass;
 | 
			
		||||
 | 
			
		||||
#define SHELL_TYPE_THEME_CONTEXT             (shell_theme_context_get_type ())
 | 
			
		||||
#define SHELL_THEME_CONTEXT(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_THEME_CONTEXT, ShellThemeContext))
 | 
			
		||||
#define SHELL_THEME_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_THEME_CONTEXT, ShellThemeContextClass))
 | 
			
		||||
#define SHELL_IS_THEME_CONTEXT(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define SHELL_IS_THEME_CONTEXT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define SHELL_THEME_CONTEXT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_THEME_CONTEXT, ShellThemeContextClass))
 | 
			
		||||
 | 
			
		||||
GType shell_theme_context_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
ShellThemeContext *shell_theme_context_new           (void);
 | 
			
		||||
ShellThemeContext *shell_theme_context_get_for_stage (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
void                        shell_theme_context_set_theme      (ShellThemeContext          *context,
 | 
			
		||||
                                                                ShellTheme                 *theme);
 | 
			
		||||
ShellTheme *                shell_theme_context_get_theme      (ShellThemeContext          *context);
 | 
			
		||||
 | 
			
		||||
void                        shell_theme_context_set_resolution (ShellThemeContext          *context,
 | 
			
		||||
                                                                gdouble                     resolution);
 | 
			
		||||
double                      shell_theme_context_get_resolution (ShellThemeContext          *context);
 | 
			
		||||
void                        shell_theme_context_set_font       (ShellThemeContext          *context,
 | 
			
		||||
                                                                const PangoFontDescription *font);
 | 
			
		||||
const PangoFontDescription *shell_theme_context_get_font       (ShellThemeContext          *context);
 | 
			
		||||
 | 
			
		||||
ShellThemeNode *            shell_theme_context_get_root_node  (ShellThemeContext          *context);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_THEME_CONTEXT_H__ */
 | 
			
		||||
							
								
								
									
										2113
									
								
								src/toolkit/shell-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2113
									
								
								src/toolkit/shell-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										143
									
								
								src/toolkit/shell-theme-node.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/toolkit/shell-theme-node.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __SHELL_THEME_NODE_H__
 | 
			
		||||
#define __SHELL_THEME_NODE_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include "shell-border-image.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _ShellTheme          ShellTheme;
 | 
			
		||||
typedef struct _ShellThemeContext   ShellThemeContext;
 | 
			
		||||
 | 
			
		||||
typedef struct _ShellThemeNode      ShellThemeNode;
 | 
			
		||||
typedef struct _ShellThemeNodeClass ShellThemeNodeClass;
 | 
			
		||||
 | 
			
		||||
#define SHELL_TYPE_THEME_NODE              (shell_theme_node_get_type ())
 | 
			
		||||
#define SHELL_THEME_NODE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_THEME_NODE, ShellThemeNode))
 | 
			
		||||
#define SHELL_THEME_NODE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass),     SHELL_TYPE_THEME_NODE, ShellThemeNodeClass))
 | 
			
		||||
#define SHELL_IS_THEME_NODE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_THEME_NODE))
 | 
			
		||||
#define SHELL_IS_THEME_NODE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass),     SHELL_TYPE_THEME_NODE))
 | 
			
		||||
#define SHELL_THEME_NODE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj),     SHELL_TYPE_THEME_NODE, ShellThemeNodeClass))
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    SHELL_SIDE_TOP,
 | 
			
		||||
    SHELL_SIDE_RIGHT,
 | 
			
		||||
    SHELL_SIDE_BOTTOM,
 | 
			
		||||
    SHELL_SIDE_LEFT
 | 
			
		||||
} ShellSide;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    SHELL_CORNER_TOPLEFT,
 | 
			
		||||
    SHELL_CORNER_TOPRIGHT,
 | 
			
		||||
    SHELL_CORNER_BOTTOMRIGHT,
 | 
			
		||||
    SHELL_CORNER_BOTTOMLEFT
 | 
			
		||||
} ShellCorner;
 | 
			
		||||
 | 
			
		||||
/* These are the CSS values; that doesn't mean we have to implement blink... */
 | 
			
		||||
typedef enum {
 | 
			
		||||
    SHELL_TEXT_DECORATION_UNDERLINE    = 1 << 0,
 | 
			
		||||
    SHELL_TEXT_DECORATION_OVERLINE     = 1 << 1,
 | 
			
		||||
    SHELL_TEXT_DECORATION_LINE_THROUGH = 1 << 2,
 | 
			
		||||
    SHELL_TEXT_DECORATION_BLINK        = 1 << 3
 | 
			
		||||
} ShellTextDecoration;
 | 
			
		||||
 | 
			
		||||
GType shell_theme_node_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/* An element_type of G_TYPE_NONE means this style was created for the stage
 | 
			
		||||
 * actor and matches a selector element name of 'stage'
 | 
			
		||||
 */
 | 
			
		||||
ShellThemeNode *shell_theme_node_new (ShellThemeContext *context,
 | 
			
		||||
                                      ShellThemeNode    *parent_node,   /* can be null */
 | 
			
		||||
                                      ShellTheme        *theme,         /* can be null */
 | 
			
		||||
                                      GType              element_type,
 | 
			
		||||
                                      const char        *element_id,
 | 
			
		||||
                                      const char        *element_class,
 | 
			
		||||
                                      const char        *pseudo_class,
 | 
			
		||||
                                      const char        *inline_style);
 | 
			
		||||
 | 
			
		||||
ShellThemeNode *shell_theme_node_get_parent (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
ShellTheme *shell_theme_node_get_theme (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
GType       shell_theme_node_get_element_type  (ShellThemeNode *node);
 | 
			
		||||
const char *shell_theme_node_get_element_id    (ShellThemeNode *node);
 | 
			
		||||
const char *shell_theme_node_get_element_class (ShellThemeNode *node);
 | 
			
		||||
const char *shell_theme_node_get_pseudo_class  (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
/* Generic getters ... these are not cached so are less efficient. The other
 | 
			
		||||
 * reason for adding the more specific version is that we can handle the
 | 
			
		||||
 * details of the actual CSS rules, which can be complicated, especially
 | 
			
		||||
 * for fonts
 | 
			
		||||
 */
 | 
			
		||||
gboolean shell_theme_node_get_color (ShellThemeNode *node,
 | 
			
		||||
                                     const char     *property_name,
 | 
			
		||||
                                     gboolean        inherit,
 | 
			
		||||
                                     ClutterColor   *color);
 | 
			
		||||
 | 
			
		||||
gboolean shell_theme_node_get_double (ShellThemeNode *node,
 | 
			
		||||
                                      const char     *property_name,
 | 
			
		||||
                                      gboolean        inherit,
 | 
			
		||||
                                      double         *value);
 | 
			
		||||
 | 
			
		||||
/* The length here is already resolved to pixels
 | 
			
		||||
 */
 | 
			
		||||
gboolean shell_theme_node_get_length (ShellThemeNode *node,
 | 
			
		||||
                                      const char     *property_name,
 | 
			
		||||
                                      gboolean        inherit,
 | 
			
		||||
                                      gdouble        *length);
 | 
			
		||||
 | 
			
		||||
/* Specific getters for particular properties: cached
 | 
			
		||||
 */
 | 
			
		||||
void shell_theme_node_get_background_color (ShellThemeNode *node,
 | 
			
		||||
                                            ClutterColor   *color);
 | 
			
		||||
void shell_theme_node_get_foreground_color (ShellThemeNode *node,
 | 
			
		||||
                                            ClutterColor   *color);
 | 
			
		||||
 | 
			
		||||
const char *shell_theme_node_get_background_image (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
double shell_theme_node_get_border_width  (ShellThemeNode *node,
 | 
			
		||||
                                           ShellSide       side);
 | 
			
		||||
double shell_theme_node_get_border_radius (ShellThemeNode *node,
 | 
			
		||||
                                           ShellCorner     corner);
 | 
			
		||||
void   shell_theme_node_get_border_color  (ShellThemeNode *node,
 | 
			
		||||
                                           ShellSide       side,
 | 
			
		||||
                                           ClutterColor   *color);
 | 
			
		||||
 | 
			
		||||
double  shell_theme_node_get_padding      (ShellThemeNode *node,
 | 
			
		||||
                                           ShellSide       side);
 | 
			
		||||
 | 
			
		||||
ShellTextDecoration shell_theme_node_get_text_decoration (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
/* Font rule processing is pretty complicated, so we just hardcode it
 | 
			
		||||
 * under the standard font/font-family/font-size/etc names. This means
 | 
			
		||||
 * you can't have multiple separate styled fonts for a single item,
 | 
			
		||||
 * but that should be OK.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *shell_theme_node_get_font (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
ShellBorderImage *shell_theme_node_get_border_image (ShellThemeNode *node);
 | 
			
		||||
 | 
			
		||||
/* Helpers for get_preferred_width()/get_preferred_height() ClutterActor vfuncs */
 | 
			
		||||
void shell_theme_node_adjust_for_height       (ShellThemeNode  *node,
 | 
			
		||||
                                               float           *for_height);
 | 
			
		||||
void shell_theme_node_adjust_preferred_width  (ShellThemeNode  *node,
 | 
			
		||||
                                               float           *min_width_p,
 | 
			
		||||
                                               float           *natural_width_p);
 | 
			
		||||
void shell_theme_node_adjust_for_width        (ShellThemeNode  *node,
 | 
			
		||||
                                               float           *for_width);
 | 
			
		||||
void shell_theme_node_adjust_preferred_height (ShellThemeNode  *node,
 | 
			
		||||
                                               float           *min_height_p,
 | 
			
		||||
                                               float           *natural_height_p);
 | 
			
		||||
 | 
			
		||||
/* Helper for allocate() ClutterActor vfunc */
 | 
			
		||||
void shell_theme_node_get_content_box         (ShellThemeNode        *node,
 | 
			
		||||
                                               const ClutterActorBox *actor_box,
 | 
			
		||||
                                               ClutterActorBox       *content_box);
 | 
			
		||||
 | 
			
		||||
gboolean shell_theme_node_geometry_equal (ShellThemeNode *node,
 | 
			
		||||
                                          ShellThemeNode *other);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_THEME_NODE_H__ */
 | 
			
		||||
							
								
								
									
										20
									
								
								src/toolkit/shell-theme-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/toolkit/shell-theme-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __SHELL_THEME_PRIVATE_H__
 | 
			
		||||
#define __SHELL_THEME_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <libcroco/libcroco.h>
 | 
			
		||||
#include "shell-theme.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GPtrArray *_shell_theme_get_matched_properties (ShellTheme       *theme,
 | 
			
		||||
                                                ShellThemeNode   *node);
 | 
			
		||||
 | 
			
		||||
/* Resolve an URL from the stylesheet to a filename */
 | 
			
		||||
char *_shell_theme_resolve_url (ShellTheme   *theme,
 | 
			
		||||
                                CRStyleSheet *base_stylesheet,
 | 
			
		||||
                                const char   *url);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_THEME_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										1029
									
								
								src/toolkit/shell-theme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1029
									
								
								src/toolkit/shell-theme.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										28
									
								
								src/toolkit/shell-theme.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/toolkit/shell-theme.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __SHELL_THEME_H__
 | 
			
		||||
#define __SHELL_THEME_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "shell-theme-node.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _ShellThemeClass ShellThemeClass;
 | 
			
		||||
 | 
			
		||||
#define SHELL_TYPE_THEME              (shell_theme_get_type ())
 | 
			
		||||
#define SHELL_THEME(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_THEME, ShellTheme))
 | 
			
		||||
#define SHELL_THEME_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_THEME, ShellThemeClass))
 | 
			
		||||
#define SHELL_IS_THEME(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_THEME))
 | 
			
		||||
#define SHELL_IS_THEME_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_THEME))
 | 
			
		||||
#define SHELL_THEME_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_THEME, ShellThemeClass))
 | 
			
		||||
 | 
			
		||||
GType  shell_theme_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
ShellTheme *shell_theme_new (const char *application_stylesheet,
 | 
			
		||||
                             const char *theme_stylesheet,
 | 
			
		||||
                             const char *default_stylesheet);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_THEME_H__ */
 | 
			
		||||
							
								
								
									
										392
									
								
								src/toolkit/test-theme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										392
									
								
								src/toolkit/test-theme.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,392 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include "shell-theme.h"
 | 
			
		||||
#include "shell-theme-context.h"
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static ShellThemeNode *root;
 | 
			
		||||
static ShellThemeNode *group1;
 | 
			
		||||
static ShellThemeNode *text1;
 | 
			
		||||
static ShellThemeNode *text2;
 | 
			
		||||
static ShellThemeNode *group2;
 | 
			
		||||
static ShellThemeNode *text3;
 | 
			
		||||
static ShellThemeNode *text4;
 | 
			
		||||
static ShellThemeNode *group3;
 | 
			
		||||
static ShellThemeNode *cairo_texture;
 | 
			
		||||
static gboolean fail;
 | 
			
		||||
 | 
			
		||||
static const char *test;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_font (ShellThemeNode *node,
 | 
			
		||||
	     const char     *node_description,
 | 
			
		||||
	     const char     *expected)
 | 
			
		||||
{
 | 
			
		||||
  char *value = pango_font_description_to_string (shell_theme_node_get_font (node));
 | 
			
		||||
 | 
			
		||||
  if (strcmp (expected, value) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_print ("%s: %s.font: expected: %s, got: %s\n",
 | 
			
		||||
	       test, node_description, expected, value);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
text_decoration_to_string (ShellTextDecoration decoration)
 | 
			
		||||
{
 | 
			
		||||
  GString *result = g_string_new (NULL);
 | 
			
		||||
 | 
			
		||||
  if (decoration & SHELL_TEXT_DECORATION_UNDERLINE)
 | 
			
		||||
    g_string_append(result, " underline");
 | 
			
		||||
  if (decoration & SHELL_TEXT_DECORATION_OVERLINE)
 | 
			
		||||
    g_string_append(result, " overline");
 | 
			
		||||
  if (decoration & SHELL_TEXT_DECORATION_LINE_THROUGH)
 | 
			
		||||
    g_string_append(result, " line_through");
 | 
			
		||||
  if (decoration & SHELL_TEXT_DECORATION_BLINK)
 | 
			
		||||
    g_string_append(result, " blink");
 | 
			
		||||
 | 
			
		||||
  if (result->len > 0)
 | 
			
		||||
    g_string_erase (result, 0, 1);
 | 
			
		||||
  else
 | 
			
		||||
    g_string_append(result, "none");
 | 
			
		||||
 | 
			
		||||
  return g_string_free (result, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_text_decoration (ShellThemeNode     *node,
 | 
			
		||||
			const char         *node_description,
 | 
			
		||||
			ShellTextDecoration expected)
 | 
			
		||||
{
 | 
			
		||||
  ShellTextDecoration value = shell_theme_node_get_text_decoration (node);
 | 
			
		||||
  if (expected != value)
 | 
			
		||||
    {
 | 
			
		||||
      char *es = text_decoration_to_string (expected);
 | 
			
		||||
      char *vs = text_decoration_to_string (value);
 | 
			
		||||
 | 
			
		||||
      g_print ("%s: %s.text-decoration: expected: %s, got: %s\n",
 | 
			
		||||
	       test, node_description, es, vs);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
 | 
			
		||||
      g_free (es);
 | 
			
		||||
      g_free (vs);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_foreground_color (ShellThemeNode *node,
 | 
			
		||||
			 const char     *node_description,
 | 
			
		||||
			 guint32         expected)
 | 
			
		||||
{
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  shell_theme_node_get_foreground_color (node, &color);
 | 
			
		||||
  guint32 value = clutter_color_to_pixel (&color);
 | 
			
		||||
 | 
			
		||||
  if (expected != value)
 | 
			
		||||
    {
 | 
			
		||||
      g_print ("%s: %s.color: expected: #%08x, got: #%08x\n",
 | 
			
		||||
	       test, node_description, expected, value);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_background_color (ShellThemeNode *node,
 | 
			
		||||
			 const char     *node_description,
 | 
			
		||||
			 guint32         expected)
 | 
			
		||||
{
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  shell_theme_node_get_background_color (node, &color);
 | 
			
		||||
  guint32 value = clutter_color_to_pixel (&color);
 | 
			
		||||
 | 
			
		||||
  if (expected != value)
 | 
			
		||||
    {
 | 
			
		||||
      g_print ("%s: %s.background-color: expected: #%08x, got: #%08x\n",
 | 
			
		||||
	       test, node_description, expected, value);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
side_to_string (ShellSide side)
 | 
			
		||||
{
 | 
			
		||||
  switch (side)
 | 
			
		||||
    {
 | 
			
		||||
    case SHELL_SIDE_TOP:
 | 
			
		||||
      return "top";
 | 
			
		||||
    case SHELL_SIDE_RIGHT:
 | 
			
		||||
      return "right";
 | 
			
		||||
    case SHELL_SIDE_BOTTOM:
 | 
			
		||||
      return "bottom";
 | 
			
		||||
    case SHELL_SIDE_LEFT:
 | 
			
		||||
      return "left";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return "<unknown>";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_border_color (ShellThemeNode *node,
 | 
			
		||||
                     const char     *node_description,
 | 
			
		||||
                     ShellSide       side,
 | 
			
		||||
                     guint32         expected)
 | 
			
		||||
{
 | 
			
		||||
  ClutterColor color;
 | 
			
		||||
  shell_theme_node_get_border_color (node, side, &color);
 | 
			
		||||
  guint32 value = clutter_color_to_pixel (&color);
 | 
			
		||||
 | 
			
		||||
  if (expected != value)
 | 
			
		||||
    {
 | 
			
		||||
      g_print ("%s: %s.border-%s-color: expected: #%08x, got: #%08x\n",
 | 
			
		||||
	       test, node_description, side_to_string (side), expected, value);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_background_image (ShellThemeNode *node,
 | 
			
		||||
			 const char     *node_description,
 | 
			
		||||
			 const char     *expected)
 | 
			
		||||
{
 | 
			
		||||
  const char *value = shell_theme_node_get_background_image (node);
 | 
			
		||||
  if (expected == NULL)
 | 
			
		||||
    expected = "(null)";
 | 
			
		||||
  if (value == NULL)
 | 
			
		||||
    value = "(null)";
 | 
			
		||||
 | 
			
		||||
  if (strcmp (expected, value) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_print ("%s: %s.background-image: expected: %s, got: %s\n",
 | 
			
		||||
	       test, node_description, expected, value);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define LENGTH_EPSILON 0.001
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
assert_length (const char     *node_description,
 | 
			
		||||
	       const char     *property_description,
 | 
			
		||||
	       double          expected,
 | 
			
		||||
	       double          value)
 | 
			
		||||
{
 | 
			
		||||
  if (fabs (expected - value) > LENGTH_EPSILON)
 | 
			
		||||
    {
 | 
			
		||||
      g_print ("%s %s.%s: expected: %3f, got: %3f\n",
 | 
			
		||||
	       test, node_description, property_description, expected, value);
 | 
			
		||||
      fail = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_defaults (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "defaults";
 | 
			
		||||
  /* font comes from context */
 | 
			
		||||
  assert_font (root, "stage", "sans-serif 12");
 | 
			
		||||
  /* black is the default foreground color */
 | 
			
		||||
  assert_foreground_color (root, "stage", 0x00000ff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_lengths (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "lengths";
 | 
			
		||||
  /* 12pt == 16px at 96dpi */
 | 
			
		||||
  assert_length ("group1", "padding-top", 16.,
 | 
			
		||||
		 shell_theme_node_get_padding (group1, SHELL_SIDE_TOP));
 | 
			
		||||
  /* 12px == 12px */
 | 
			
		||||
  assert_length ("group1", "padding-right", 12.,
 | 
			
		||||
		 shell_theme_node_get_padding (group1, SHELL_SIDE_RIGHT));
 | 
			
		||||
  /* 2em == 32px (with a 12pt font) */
 | 
			
		||||
  assert_length ("group1", "padding-bottom", 32.,
 | 
			
		||||
		 shell_theme_node_get_padding (group1, SHELL_SIDE_BOTTOM));
 | 
			
		||||
  /* 1in == 72pt == 96px, at 96dpi */
 | 
			
		||||
  assert_length ("group1", "padding-left", 96.,
 | 
			
		||||
		 shell_theme_node_get_padding (group1, SHELL_SIDE_LEFT));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_classes (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "classes";
 | 
			
		||||
  /* .special-text class overrides size and style;
 | 
			
		||||
   * the ClutterTexture.special-text selector doesn't match */
 | 
			
		||||
  assert_font (text1, "text1", "sans-serif Italic 32px");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_type_inheritance (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "type_inheritance";
 | 
			
		||||
  /* From ClutterTexture element selector */
 | 
			
		||||
  assert_length ("cairoTexture", "padding-top", 10.,
 | 
			
		||||
		 shell_theme_node_get_padding (cairo_texture, SHELL_SIDE_TOP));
 | 
			
		||||
  /* From ClutterCairoTexture element selector */
 | 
			
		||||
  assert_length ("cairoTexture", "padding-right", 20.,
 | 
			
		||||
		 shell_theme_node_get_padding (cairo_texture, SHELL_SIDE_RIGHT));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_adjacent_selector (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "adjacent_selector";
 | 
			
		||||
  /* #group1 > #text1 matches text1 */
 | 
			
		||||
  assert_foreground_color (text1, "text1", 0x00ff00ff);
 | 
			
		||||
  /* stage > #text2 doesn't match text2 */
 | 
			
		||||
  assert_foreground_color (text2, "text2", 0x000000ff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_padding (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "padding";
 | 
			
		||||
  /* Test that a 4-sided padding property assigns the right paddings to
 | 
			
		||||
   * all sides */
 | 
			
		||||
  assert_length ("group2", "padding-top", 1.,
 | 
			
		||||
		 shell_theme_node_get_padding (group2, SHELL_SIDE_TOP));
 | 
			
		||||
  assert_length ("group2", "padding-right", 2.,
 | 
			
		||||
		 shell_theme_node_get_padding (group2, SHELL_SIDE_RIGHT));
 | 
			
		||||
  assert_length ("group2", "padding-bottom", 3.,
 | 
			
		||||
		 shell_theme_node_get_padding (group2, SHELL_SIDE_BOTTOM));
 | 
			
		||||
  assert_length ("group2", "padding-left", 4.,
 | 
			
		||||
		 shell_theme_node_get_padding (group2, SHELL_SIDE_LEFT));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_border (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "border";
 | 
			
		||||
 | 
			
		||||
  /* group2 is defined as having a thin black border along the top three
 | 
			
		||||
   * sides with rounded joins, then a square-joined green border at the
 | 
			
		||||
   * botttom
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  assert_length ("group2", "border-top-width", 2.,
 | 
			
		||||
		 shell_theme_node_get_border_width (group2, SHELL_SIDE_TOP));
 | 
			
		||||
  assert_length ("group2", "border-right-width", 2.,
 | 
			
		||||
		 shell_theme_node_get_border_width (group2, SHELL_SIDE_RIGHT));
 | 
			
		||||
  assert_length ("group2", "border-bottom-width", 5.,
 | 
			
		||||
		 shell_theme_node_get_border_width (group2, SHELL_SIDE_BOTTOM));
 | 
			
		||||
  assert_length ("group2", "border-left-width", 2.,
 | 
			
		||||
		 shell_theme_node_get_border_width (group2, SHELL_SIDE_LEFT));
 | 
			
		||||
 | 
			
		||||
  assert_border_color (group2, "group2", SHELL_SIDE_TOP,    0x000000ff);
 | 
			
		||||
  assert_border_color (group2, "group2", SHELL_SIDE_RIGHT,  0x000000ff);
 | 
			
		||||
  assert_border_color (group2, "group2", SHELL_SIDE_BOTTOM, 0x0000ffff);
 | 
			
		||||
  assert_border_color (group2, "group2", SHELL_SIDE_LEFT,   0x000000ff);
 | 
			
		||||
 | 
			
		||||
  assert_length ("group2", "border-radius-topleft", 10.,
 | 
			
		||||
		 shell_theme_node_get_border_radius (group2, SHELL_CORNER_TOPLEFT));
 | 
			
		||||
  assert_length ("group2", "border-radius-topright", 10.,
 | 
			
		||||
		 shell_theme_node_get_border_radius (group2, SHELL_CORNER_TOPRIGHT));
 | 
			
		||||
  assert_length ("group2", "border-radius-bottomright", 0.,
 | 
			
		||||
		 shell_theme_node_get_border_radius (group2, SHELL_CORNER_BOTTOMRIGHT));
 | 
			
		||||
  assert_length ("group2", "border-radius-bottomleft", 0.,
 | 
			
		||||
		 shell_theme_node_get_border_radius (group2, SHELL_CORNER_BOTTOMLEFT));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_background (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "background";
 | 
			
		||||
  /* group1 has a background: shortcut property setting color and image */
 | 
			
		||||
  assert_background_color (group1, "group1", 0xff0000ff);
 | 
			
		||||
  assert_background_image (group1, "group1", "toolkit/some-background.png");
 | 
			
		||||
  /* text1 inherits the background image but not the color */
 | 
			
		||||
  assert_background_color (text1,  "text1",  0x00000000);
 | 
			
		||||
  assert_background_image (text1,  "text1",  "toolkit/some-background.png");
 | 
			
		||||
  /* text1 inherits inherits both, but then background: none overrides both */
 | 
			
		||||
  assert_background_color (text2,  "text2",  0x00000000);
 | 
			
		||||
  assert_background_image (text2,  "text2",  NULL);
 | 
			
		||||
  /* background-image property */
 | 
			
		||||
  assert_background_image (group2, "group2", "toolkit/other-background.png");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_font (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "font";
 | 
			
		||||
  /* font specified with font: */
 | 
			
		||||
  assert_font (group2, "group2", "serif Italic 12px");
 | 
			
		||||
  /* text3 inherits and overrides individually properties */
 | 
			
		||||
  assert_font (text3,  "text3",  "serif Bold Oblique Small-Caps 24px");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_pseudo_class (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "pseudo_class";
 | 
			
		||||
  /* text4 has :visited and :hover pseudo-classes, so should pick up both of these */
 | 
			
		||||
  assert_foreground_color (text4,   "text4",  0x888888ff);
 | 
			
		||||
  assert_text_decoration  (text4,   "text4",  SHELL_TEXT_DECORATION_UNDERLINE);
 | 
			
		||||
  /* :hover pseudo-class matches, but class doesn't match */
 | 
			
		||||
  assert_text_decoration  (group3,  "group3", 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_inline_style (void)
 | 
			
		||||
{
 | 
			
		||||
  test = "inline_style";
 | 
			
		||||
  /* These properties come from the inline-style specified when creating the node */
 | 
			
		||||
  assert_foreground_color (text3,   "text3",  0x00000ffff);
 | 
			
		||||
  assert_length ("text3", "padding-bottom", 12.,
 | 
			
		||||
		 shell_theme_node_get_padding (text3, SHELL_SIDE_BOTTOM));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  ShellTheme *theme;
 | 
			
		||||
  ShellThemeContext *context;
 | 
			
		||||
 | 
			
		||||
  clutter_init (&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  theme = shell_theme_new ("toolkit/test-theme.css",
 | 
			
		||||
			   NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  context = shell_theme_context_new ();
 | 
			
		||||
  shell_theme_context_set_theme (context, theme);
 | 
			
		||||
  shell_theme_context_set_resolution (context, 96.);
 | 
			
		||||
  shell_theme_context_set_font (context,
 | 
			
		||||
				pango_font_description_from_string ("sans-serif 12"));
 | 
			
		||||
 | 
			
		||||
  root = shell_theme_context_get_root_node (context);
 | 
			
		||||
  group1 = shell_theme_node_new (context, root, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_GROUP, "group1", NULL, NULL, NULL);
 | 
			
		||||
  text1 = shell_theme_node_new  (context, group1, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_TEXT, "text1", "special-text", NULL, NULL);
 | 
			
		||||
  text2 = shell_theme_node_new  (context, group1, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_TEXT, "text2", NULL, NULL, NULL);
 | 
			
		||||
  group2 = shell_theme_node_new (context, root, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_GROUP, "group2", NULL, NULL, NULL);
 | 
			
		||||
  text3 = shell_theme_node_new  (context, group2, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_TEXT, "text3", NULL, NULL,
 | 
			
		||||
                                 "color: #0000ff; padding-bottom: 12px;");
 | 
			
		||||
  text4 = shell_theme_node_new  (context, group2, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_TEXT, "text4", NULL, "visited hover", NULL);
 | 
			
		||||
  group3 = shell_theme_node_new (context, group2, NULL,
 | 
			
		||||
				 CLUTTER_TYPE_GROUP, "group3", NULL, "hover", NULL);
 | 
			
		||||
  cairo_texture = shell_theme_node_new (context, root, NULL,
 | 
			
		||||
					CLUTTER_TYPE_CAIRO_TEXTURE, "cairoTexture", NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  test_defaults ();
 | 
			
		||||
  test_lengths ();
 | 
			
		||||
  test_classes ();
 | 
			
		||||
  test_type_inheritance ();
 | 
			
		||||
  test_adjacent_selector ();
 | 
			
		||||
  test_padding ();
 | 
			
		||||
  test_border ();
 | 
			
		||||
  test_background ();
 | 
			
		||||
  test_font ();
 | 
			
		||||
  test_pseudo_class ();
 | 
			
		||||
  test_inline_style ();
 | 
			
		||||
 | 
			
		||||
  return fail ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								src/toolkit/test-theme.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/toolkit/test-theme.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
stage {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#group1 {
 | 
			
		||||
    padding: 12pt;
 | 
			
		||||
    padding-right: 12px;
 | 
			
		||||
    padding-bottom: 2em;
 | 
			
		||||
    padding-left: 1in;
 | 
			
		||||
 | 
			
		||||
    background: #ff0000 url('some-background.png');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#text1 {
 | 
			
		||||
    background-image: inherit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.special-text {
 | 
			
		||||
    font-size: 24pt;
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterTexture.special-text {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#text2 {
 | 
			
		||||
    background: inherit;
 | 
			
		||||
    background: none; /* also overrides the color */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#group2 {
 | 
			
		||||
    font: italic 12px serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#text3 {
 | 
			
		||||
    font-variant: small-caps;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    font-style: oblique;
 | 
			
		||||
    font-size: 200%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterTexture {
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterCairoTexture {
 | 
			
		||||
    padding-right: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#group1 > #text1 {
 | 
			
		||||
    color: #00ff00;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stage > #text2 {
 | 
			
		||||
    color: #ff0000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#group2 {
 | 
			
		||||
    background-image: url('other-background.png');
 | 
			
		||||
    padding: 1px 2px 3px 4px;
 | 
			
		||||
 | 
			
		||||
    border: 2px solid #000000;
 | 
			
		||||
    border-bottom: 5px solid #0000ff;
 | 
			
		||||
    border-radius: 10px 10px 0px 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterText:hover {
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterText:visited {
 | 
			
		||||
    color: #888888;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								tests/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tests/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
noinst_SCRIPTS = run-test.sh
 | 
			
		||||
EXTRA_DIST = run-test.sh.in
 | 
			
		||||
 | 
			
		||||
TEST_JS =					\
 | 
			
		||||
	testcommon/ui.js			\
 | 
			
		||||
	interactive/box-layout.js
 | 
			
		||||
EXTRA_DIST += $(TEST_JS)
 | 
			
		||||
 | 
			
		||||
TEST_MISC =					\
 | 
			
		||||
	testcommon/test.css
 | 
			
		||||
EXTRA_DIST += $(TEST_MISC)
 | 
			
		||||
 | 
			
		||||
# We substitute in bindir so it works as an autostart
 | 
			
		||||
# file when built in a non-system prefix
 | 
			
		||||
run-test.sh: run-test.sh.in
 | 
			
		||||
	$(AM_V_GEN) sed \
 | 
			
		||||
	    -e "s|@GJS_JS_DIR[@]|$(GJS_JS_DIR)|" \
 | 
			
		||||
	    -e "s|@GJS_JS_NATIVE_DIR[@]|$(GJS_JS_NATIVE_DIR)|" \
 | 
			
		||||
	    -e "s|@MUTTER_LIB_DIR[@]|$(MUTTER_LIB_DIR)|" \
 | 
			
		||||
	    -e "s|@srcdir[@]|$(srcdir)|" \
 | 
			
		||||
	    $< > $@ && chmod a+x $@
 | 
			
		||||
							
								
								
									
										63
									
								
								tests/interactive/borders.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								tests/interactive/borders.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
 | 
			
		||||
const UI = imports.testcommon.ui;
 | 
			
		||||
 | 
			
		||||
UI.init();
 | 
			
		||||
let stage = Clutter.Stage.get_default();
 | 
			
		||||
stage.width = 600;
 | 
			
		||||
stage.height = 700;
 | 
			
		||||
 | 
			
		||||
let vbox = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
				width: stage.width,
 | 
			
		||||
			        height: stage.height,
 | 
			
		||||
                                spacing: 20,
 | 
			
		||||
                                style: 'padding: 10px; background: #ffee88;' });
 | 
			
		||||
stage.add_actor(vbox);
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Hello World",
 | 
			
		||||
                          style: 'border: 1px solid black; '
 | 
			
		||||
                                 + 'padding: 5px;' }));
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Hello Round World",
 | 
			
		||||
                          style: 'border: 3px solid green; '
 | 
			
		||||
                                 + 'border-radius: 8px; '
 | 
			
		||||
                                 + 'padding: 5px;' }));
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Hello Background",
 | 
			
		||||
                          style: 'border: 3px solid green; '
 | 
			
		||||
                                 + 'border-radius: 8px; '
 | 
			
		||||
                                 + 'background: white; '
 | 
			
		||||
                                 + 'padding: 5px;' }));
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Border, Padding, Content: 20px" }));
 | 
			
		||||
 | 
			
		||||
let b1 = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
                              style: 'border: 20px solid black; '
 | 
			
		||||
                                     + 'background: white; '
 | 
			
		||||
                                     + 'padding: 20px;' });
 | 
			
		||||
vbox.add(b1);
 | 
			
		||||
 | 
			
		||||
b1.add(new Nbtk.BoxLayout({ width: 20, height: 20,
 | 
			
		||||
                            style: 'background: black' }));
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Translucent blue border, with rounding",
 | 
			
		||||
                          style: 'border: 20px solid rgba(0, 0, 255, 0.2); '
 | 
			
		||||
                                 + 'border-radius: 10px; '
 | 
			
		||||
                                 + 'background: white; '
 | 
			
		||||
                                 + 'padding: 10px;' }));
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Transparent border",
 | 
			
		||||
                          style: 'border: 20px solid transparent; '
 | 
			
		||||
                                 + 'background: white; '
 | 
			
		||||
                                 + 'padding: 10px;' }));
 | 
			
		||||
 | 
			
		||||
vbox.add(new Nbtk.Label({ text: "Border Image",
 | 
			
		||||
                          style_class: "border-image",
 | 
			
		||||
                          style: "padding: 10px;" }));
 | 
			
		||||
 | 
			
		||||
stage.show();
 | 
			
		||||
Clutter.main();
 | 
			
		||||
stage.destroy();
 | 
			
		||||
							
								
								
									
										87
									
								
								tests/interactive/box-layout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								tests/interactive/box-layout.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
 | 
			
		||||
const UI = imports.testcommon.ui;
 | 
			
		||||
 | 
			
		||||
UI.init();
 | 
			
		||||
let stage = Clutter.Stage.get_default();
 | 
			
		||||
 | 
			
		||||
let vbox = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
                                width: stage.width,
 | 
			
		||||
                                height: stage.height,
 | 
			
		||||
                                spacing: 10,
 | 
			
		||||
                                style: 'padding: 10px' });
 | 
			
		||||
stage.add_actor(vbox);
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
let colored_boxes = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
                                         width:  200,
 | 
			
		||||
                                         height: 200,
 | 
			
		||||
                                         style: 'border: 2px solid black;' });
 | 
			
		||||
vbox.add(colored_boxes, { x_fill: false,
 | 
			
		||||
                          x_align: Nbtk.Align.MIDDLE });
 | 
			
		||||
 | 
			
		||||
let b2 = new Nbtk.BoxLayout({ style: 'border: 2px solid #666666' });
 | 
			
		||||
colored_boxes.add(b2, { expand: true });
 | 
			
		||||
 | 
			
		||||
b2.add(new Nbtk.Label({ text: "Expand",
 | 
			
		||||
                        style: 'border: 1px solid #aaaaaa; '
 | 
			
		||||
                               + 'background: #ffeecc' }),
 | 
			
		||||
       { expand: true });
 | 
			
		||||
b2.add(new Nbtk.Label({ text: "Expand\nNo Fill",
 | 
			
		||||
                        style: 'border: 1px solid #aaaaaa; '
 | 
			
		||||
                               + 'background: #ccffaa' }),
 | 
			
		||||
       { expand: true,
 | 
			
		||||
         x_fill: false,
 | 
			
		||||
         x_align: Nbtk.Align.MIDDLE,
 | 
			
		||||
         y_fill: false,
 | 
			
		||||
         y_align: Nbtk.Align.MIDDLE });
 | 
			
		||||
 | 
			
		||||
colored_boxes.add(new Nbtk.Label({ text: "Default",
 | 
			
		||||
                                   style: 'border: 1px solid #aaaaaa; '
 | 
			
		||||
                                          + 'background: #cceeff' }));
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
function createCollapsableBox(width) {
 | 
			
		||||
    let b = new Nbtk.BoxLayout({ width: width,
 | 
			
		||||
                                 style: 'border: 1px solid black;'
 | 
			
		||||
                                        + 'font: 13px Sans;' });
 | 
			
		||||
    b.add(new Nbtk.Label({ text: "Very Very Very Long",
 | 
			
		||||
                           style: 'background: #ffaacc;'
 | 
			
		||||
                                  + 'padding: 5px; '
 | 
			
		||||
                                  + 'border: 1px solid #666666;' }),
 | 
			
		||||
          { expand: true });
 | 
			
		||||
    b.add(new Nbtk.Label({ text: "Very Very Long",
 | 
			
		||||
                           style: 'background: #ffeecc; '
 | 
			
		||||
                                  + 'padding: 5px; '
 | 
			
		||||
                                  + 'border: 1px solid #666666;' }),
 | 
			
		||||
          { expand: true });
 | 
			
		||||
    b.add(new Nbtk.Label({ text: "Very Long",
 | 
			
		||||
                           style: 'background: #ccffaa; '
 | 
			
		||||
                                  + 'padding: 5px; '
 | 
			
		||||
                                  + 'border: 1px solid #666666;' }),
 | 
			
		||||
          { expand: true });
 | 
			
		||||
    b.add(new Nbtk.Label({ text: "Short",
 | 
			
		||||
                           style: 'background: #cceeff; '
 | 
			
		||||
                                  + 'padding: 5px; '
 | 
			
		||||
                                  + 'border: 1px solid #666666;' }),
 | 
			
		||||
          { expand: true });
 | 
			
		||||
 | 
			
		||||
    return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for (let width = 200; width <= 500; width += 60 ) {
 | 
			
		||||
    vbox.add(createCollapsableBox (width),
 | 
			
		||||
             { x_fill: false,
 | 
			
		||||
               x_align: Nbtk.Align.MIDDLE });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
stage.show();
 | 
			
		||||
Clutter.main();
 | 
			
		||||
							
								
								
									
										39
									
								
								tests/interactive/css-fonts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								tests/interactive/css-fonts.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
 | 
			
		||||
const UI = imports.testcommon.ui;
 | 
			
		||||
 | 
			
		||||
UI.init();
 | 
			
		||||
let stage = Clutter.Stage.get_default();
 | 
			
		||||
 | 
			
		||||
let b = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
			     width: stage.width,
 | 
			
		||||
			     height: stage.height });
 | 
			
		||||
stage.add_actor(b);
 | 
			
		||||
 | 
			
		||||
let t;
 | 
			
		||||
 | 
			
		||||
t = new Nbtk.Label({ "text": "Bold", style_class: "bold" });
 | 
			
		||||
b.add(t);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Monospace", style_class: "monospace" });
 | 
			
		||||
b.add(t);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Italic", style_class: "italic" });
 | 
			
		||||
b.add(t);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Bold Italic", style_class: "bold italic" });
 | 
			
		||||
b.add(t);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Big Italic", style_class: "big italic" });
 | 
			
		||||
b.add(t);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Big Bold", style_class: "big bold" });
 | 
			
		||||
b.add(t);
 | 
			
		||||
 | 
			
		||||
let b2 = new Nbtk.BoxLayout({ vertical: true, style_class: "monospace" });
 | 
			
		||||
b.add(b2);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Big Monospace", style_class: "big" });
 | 
			
		||||
b2.add(t);
 | 
			
		||||
t = new Nbtk.Label({ "text": "Italic Monospace", style_class: "italic" });
 | 
			
		||||
b2.add(t);
 | 
			
		||||
 | 
			
		||||
stage.show();
 | 
			
		||||
Clutter.main();
 | 
			
		||||
							
								
								
									
										47
									
								
								tests/interactive/inline-style.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								tests/interactive/inline-style.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
 | 
			
		||||
const UI = imports.testcommon.ui;
 | 
			
		||||
 | 
			
		||||
UI.init();
 | 
			
		||||
let stage = Clutter.Stage.get_default();
 | 
			
		||||
 | 
			
		||||
let vbox = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
  			        width: stage.width,
 | 
			
		||||
			        height: stage.height });
 | 
			
		||||
stage.add_actor(vbox);
 | 
			
		||||
 | 
			
		||||
let hbox = new Nbtk.BoxLayout({ spacing: 12 });
 | 
			
		||||
vbox.add(hbox);
 | 
			
		||||
 | 
			
		||||
let text = new Nbtk.Label({ text: "Styled Text" });
 | 
			
		||||
vbox.add (text);
 | 
			
		||||
 | 
			
		||||
let size = 24;
 | 
			
		||||
function update_size() {
 | 
			
		||||
    text.style = 'font-size: ' + size + 'pt';
 | 
			
		||||
}
 | 
			
		||||
update_size();
 | 
			
		||||
 | 
			
		||||
let button;
 | 
			
		||||
 | 
			
		||||
button = new Nbtk.Button ({ label: 'Smaller' });
 | 
			
		||||
hbox.add (button);
 | 
			
		||||
button.connect('clicked', function() {
 | 
			
		||||
                   size /= 1.2;
 | 
			
		||||
                   update_size ();
 | 
			
		||||
               });
 | 
			
		||||
 | 
			
		||||
button = new Nbtk.Button ({ label: 'Bigger' });
 | 
			
		||||
hbox.add (button);
 | 
			
		||||
button.connect('clicked', function() {
 | 
			
		||||
                   size *= 1.2;
 | 
			
		||||
                   update_size ();
 | 
			
		||||
               });
 | 
			
		||||
 | 
			
		||||
stage.show();
 | 
			
		||||
Clutter.main();
 | 
			
		||||
stage.destroy();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								tests/interactive/scrolling.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								tests/interactive/scrolling.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
 | 
			
		||||
const UI = imports.testcommon.ui;
 | 
			
		||||
 | 
			
		||||
UI.init();
 | 
			
		||||
let stage = Clutter.Stage.get_default();
 | 
			
		||||
 | 
			
		||||
let vbox = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
                                width: stage.width,
 | 
			
		||||
                                height: stage.height,
 | 
			
		||||
                                style: "padding: 10px;" });
 | 
			
		||||
stage.add_actor(vbox);
 | 
			
		||||
 | 
			
		||||
let v = new Nbtk.ScrollView();
 | 
			
		||||
vbox.add(v, { expand: true });
 | 
			
		||||
 | 
			
		||||
let b = new Nbtk.BoxLayout({ vertical: true,
 | 
			
		||||
                             style: "border: 2px solid #880000; border-radius: 10px; padding: 0px 5px;" });
 | 
			
		||||
v.add_actor(b);
 | 
			
		||||
 | 
			
		||||
let cc_a = "a".charCodeAt(0);
 | 
			
		||||
let s = "";
 | 
			
		||||
for (let i = 0; i < 26 * 3; i++) {
 | 
			
		||||
    s += String.fromCharCode(cc_a + i % 26);
 | 
			
		||||
 | 
			
		||||
    let t = new Nbtk.Label({ text: s,
 | 
			
		||||
                             reactive: true });
 | 
			
		||||
    let line = i + 1;
 | 
			
		||||
    t.connect('button-press-event',
 | 
			
		||||
              function() {
 | 
			
		||||
                  log("Click on line " + line);
 | 
			
		||||
              });
 | 
			
		||||
    b.add(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stage.show();
 | 
			
		||||
Clutter.main();
 | 
			
		||||
stage.destroy();
 | 
			
		||||
							
								
								
									
										48
									
								
								tests/run-test.sh.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/run-test.sh.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
usage() {
 | 
			
		||||
    echo >&2 "Usage run-test.sh [-v|--verbose] <test_js>..."
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tests=
 | 
			
		||||
verbose=false
 | 
			
		||||
debug=
 | 
			
		||||
for arg in $@ ; do
 | 
			
		||||
    case $arg in
 | 
			
		||||
	-g|--debug)
 | 
			
		||||
	    debug="gdb --args"
 | 
			
		||||
	    ;;
 | 
			
		||||
	-v|--verbose)
 | 
			
		||||
	    verbose=true
 | 
			
		||||
	    ;;
 | 
			
		||||
	-*)
 | 
			
		||||
	    usage
 | 
			
		||||
	    ;;
 | 
			
		||||
	*)
 | 
			
		||||
	    tests="$tests $arg"
 | 
			
		||||
	    ;;
 | 
			
		||||
    esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
builddir=`dirname $0`
 | 
			
		||||
builddir=`cd $builddir && pwd`
 | 
			
		||||
srcdir=$builddir/@srcdir@
 | 
			
		||||
srcdir=`cd $srcdir && pwd`
 | 
			
		||||
 | 
			
		||||
GI_TYPELIB_PATH="@MUTTER_LIB_DIR@/mutter:$builddir/../src"
 | 
			
		||||
GJS_DEBUG_OUTPUT=stderr
 | 
			
		||||
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
 | 
			
		||||
GNOME_SHELL_TESTSDIR="$srcdir/"
 | 
			
		||||
LD_PRELOAD="$builddir/../src/.libs/libgnome-shell.so"
 | 
			
		||||
 | 
			
		||||
export GI_TYPELIB_PATH GJS_DEBUG_OUTPUT GJS_DEBUG_TOPICS GNOME_SHELL_JS GNOME_SHELL_TESTSDIR LD_PRELOAD
 | 
			
		||||
 | 
			
		||||
gjs_args=
 | 
			
		||||
for i in $srcdir $srcdir/../js @GJS_JS_DIR@ @GJS_JS_NATIVE_DIR@ ; do
 | 
			
		||||
    gjs_args="$gjs_args -I $i"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
for test in $tests ; do
 | 
			
		||||
    $debug gjs-console $gjs_args $test || exit $?
 | 
			
		||||
done
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								tests/testcommon/border-image.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tests/testcommon/border-image.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 981 B  | 
							
								
								
									
										53
									
								
								tests/testcommon/test.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/testcommon/test.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
@import "../../data/theme/gnome-shell.css";
 | 
			
		||||
 | 
			
		||||
stage {
 | 
			
		||||
    font: 16pt serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.red {
 | 
			
		||||
    background-color: red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.green {
 | 
			
		||||
    background-color: green;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.blue {
 | 
			
		||||
    background-color: blue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bold {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.italic {
 | 
			
		||||
    font-style: italic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.big {
 | 
			
		||||
    font-size: 150%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.monospace {
 | 
			
		||||
    font-family: monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.border-image {
 | 
			
		||||
    border: 15px;
 | 
			
		||||
    border-image: url('border-image.png') 16;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton {
 | 
			
		||||
    background: #eeddbb;
 | 
			
		||||
    border: 1px solid black;
 | 
			
		||||
    border-radius: 8px;
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton:hover {
 | 
			
		||||
    background: #ffeecc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NbtkButton:active {
 | 
			
		||||
    background: #ccbb99;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								tests/testcommon/ui.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/testcommon/ui.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const Nbtk = imports.gi.Nbtk;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
 | 
			
		||||
const Environment = imports.ui.environment;
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
    Clutter.init(null, null);
 | 
			
		||||
    Environment.init();
 | 
			
		||||
 | 
			
		||||
    let stage = Clutter.Stage.get_default();
 | 
			
		||||
    let context = Shell.ThemeContext.get_for_stage (stage);
 | 
			
		||||
    let stylesheetPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/test.css";
 | 
			
		||||
    let theme = new Shell.Theme ({ application_stylesheet: stylesheetPath });
 | 
			
		||||
    context.set_theme (theme);
 | 
			
		||||
}
 | 
			
		||||
@@ -7,6 +7,8 @@
 | 
			
		||||
      href="git://git.clutter-project.org/"/>
 | 
			
		||||
  <repository type="git" name="git.gnome.org"
 | 
			
		||||
      href="git://git.gnome.org/"/>
 | 
			
		||||
  <repository type="git" name="git.moblin.org"
 | 
			
		||||
      href="git://git.moblin.org"/>
 | 
			
		||||
 | 
			
		||||
  <autotools id="gobject-introspection">
 | 
			
		||||
    <branch repo="git.gnome.org" module="gobject-introspection"/>
 | 
			
		||||
@@ -36,6 +38,13 @@
 | 
			
		||||
    </dependencies>
 | 
			
		||||
  </autotools>
 | 
			
		||||
 | 
			
		||||
  <autotools id="clutter-imcontext">
 | 
			
		||||
    <branch repo="git.moblin.org" module="clutter-imcontext"/>
 | 
			
		||||
    <dependencies>
 | 
			
		||||
        <dep package="clutter"/>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
  </autotools>
 | 
			
		||||
 | 
			
		||||
  <autotools id="gconf" autogenargs="--disable-defaults-service">
 | 
			
		||||
    <branch repo="git.gnome.org" module="gconf"/>
 | 
			
		||||
  </autotools>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user