ayatana-ido-0.4.2/AUTHORS0000644000000000000000000000006013211262407011634 0ustar Mike Gabriel ayatana-ido-0.4.2/AUTHORS.Canonical0000644000000000000000000000004713211262407013527 0ustar Cody Russell ayatana-ido-0.4.2/autogen.sh0000755000000000000000000000026013211262407012567 0ustar #!/bin/sh PKG_NAME="ido" which mate-autogen || { echo "You need mate-common from https://git.mate-desktop.org/mate-common" exit 1 } mate-autogen --enable-gtk-doc $@ ayatana-ido-0.4.2/ChangeLog0000644000000000000000000017276013211262407012357 0ustar 2017-12-04 16:07:01 +0100 Mike Gabriel (96f0fe7) * release 0.4.2 (HEAD -> master) 2017-12-04 15:06:40 +0000 Mike Gabriel (dbf93d9) * release 0.4.2 2017-12-04 15:03:31 +0000 Mike Gabriel (511562e) * tests/Makefile.am: Fix static lib name (libido -> libayatana-ido). 2017-12-04 15:57:58 +0100 Mike Gabriel (bb3f64f) * debian/control: Bump Standards-Version: to 4.1.1. No changes needed. 2017-12-04 15:56:27 +0100 Mike Gabriel (3fcfc52) * libayatana-ido3.pc.in: Fix pkg-config name (libido -> libayatana-ido). 2017-10-26 19:14:36 +0200 Mike Gabriel (f87b429) * Makefile.am: Drop distcheck features. (origin/master) 2017-10-22 21:11:28 +0200 Mike Gabriel (35eeb7e) * debian/changelog: Fix source project name in most recent changelog stanza. 2017-09-15 23:53:19 +0200 Mike Gabriel (75bbddb) * release 0.4.1 (tag: 0.4.1) 2017-06-23 21:03:18 +0200 Mike Gabriel (1202ada) * debian/control: Add versioned B-D: dpkg-dev (>= 1.16.1.1) 2017-06-23 21:00:02 +0200 Mike Gabriel (d54247b) * debian/upstream: Add upstream signing keys. 2017-06-23 20:59:16 +0200 Mike Gabriel (cf2fe65) * debian/watch: Add file. 2017-06-23 20:59:06 +0200 Mike Gabriel (9ade6cd) * debian/patches: Add README for patches folder. 2017-06-23 20:58:21 +0200 Mike Gabriel (c17595f) * debian/rules: Add get-orig-source rule. 2017-06-23 20:58:07 +0200 Mike Gabriel (b7ac3e9) * debian/rules: Enable all hardening flags. 2017-06-23 20:57:24 +0200 Mike Gabriel (9c9bd9d) * debian/control: Don't duplicate Section: for shared library package. 2017-06-23 20:56:52 +0200 Mike Gabriel (eb4383f) * debian/control: Bump Standards-Version: to 3.9.8. No changes needed. 2017-06-23 20:55:51 +0200 Mike Gabriel (4f7b60c) * debian/copyright: Adopt minor changes from official Debian package. 2017-05-22 14:09:42 +0200 Mike Gabriel (03ae439) * configure.ac: Let AC_CONFIG_SRCDIR point to src/libayatana-ido.h. 2017-05-22 13:59:03 +0200 Mike Gabriel (e835f22) * src/libido.h: Drop empty file (artifact of fork). 2017-05-22 13:24:02 +0200 Mike Gabriel (33c6c13) * debian/copyright: Adopt from official Debian package. (origin/release-builds, release-builds) 2017-05-22 13:06:21 +0200 Mike Gabriel (2c5700f) * release 0.4.0 (tag: 0.4.0) 2017-05-22 12:56:31 +0200 Mike Gabriel (fda91d4) * configure.ac: Update shared library name, bug tracker URL, homepage URL. 2017-05-22 12:55:25 +0200 Mike Gabriel (39d0d9f) * Build system: Drop remnants of GTK-2+ support. 2017-05-22 12:50:03 +0200 Mike Gabriel (fec55f9) * debian/{control,gir1.2-ayatana-ido3-0.4.install}: Turn into Multi-Arch: same package. 2017-05-22 12:48:59 +0200 Mike Gabriel (81e6487) * debian/control: Update SYNOPSIS and LONG_DESCRIPTION fields. 2017-05-22 12:48:21 +0200 Mike Gabriel (6b027ab) * autogen.sh: Drop references to deprecated shell variables. 2017-05-22 12:31:49 +0200 Mike Gabriel (5ff2bc1) * Drop .bzr-builddeb/default.conf. We are on Git. 2017-05-16 11:01:13 +0200 Mike Gabriel (4daacc4) * One step back... Mimick Canonical's API. Use their namespace for item attributes. 2017-05-16 10:33:15 +0200 Mike Gabriel (7956f5b) * Move NEWS file from Canonical out of the way. 2017-05-15 12:13:45 +0200 Marco Trevisan (Treviño) (61e95ac) * IdoCalendarMenuItem: disconnect from parent signals on item destruction (LP: #1506427) 2017-05-15 10:27:21 +0200 Mike Gabriel (89f8b57) * build system: Switch to mate-common. 2015-11-16 16:04:57 +0100 Mike Gabriel (4a43575) * Use x-ayatanaindicator-* instead of x-canonical-*. 2015-11-16 15:15:09 +0100 Mike Gabriel (fcf7848) * Makefile.am 2015-11-11 05:52:47 +0100 Mike Gabriel (656e57d) * Drop .bzrignore file. 2015-11-06 15:22:44 +0000 Mike Gabriel (ffebaca) * libayatana-ido fork: Fix include paths for public header files. 2015-11-06 14:58:47 +0000 Mike Gabriel (8acfbb7) * Adapt pkconfig .pc files to library name changes. 2015-11-06 14:12:51 +0000 Mike Gabriel (3790a17) * debian/rules: Drop override_dh_auto_test rule. Tests are disabled in tests/Makefile.am at the moment, anyway. 2015-11-06 14:55:02 +0100 Mike Gabriel (17de78b) * make: Improve distclean ruleset. 2015-11-06 14:56:35 +0100 Mike Gabriel (0087253) * Re-add forgotten files after fork: libayatana-ido.pc.in, libayatana-ido3.pc.in. 2015-11-06 13:49:07 +0100 Mike Gabriel (76d1509) * Fork ayatana-ido from Ubuntu's ido shared library. 2015-10-02 15:32:36 +0000 CI Train Bot (d1b09d9) * Releasing 13.10.0+15.10.20151002-0ubuntu1 (refs/bzr/origin/tags/13.10.0+15.10.20151002-0ubuntu1, refs/bzr/origin/heads/master) 2015-10-02 15:32:33 +0000 Lars Uebernickel (771ce0c) * idosourcemenuitem: change misplaced g_return_val_if_fail() Approved by: Sebastien Bacher, PS Jenkins bot 2015-10-02 14:33:56 +0200 Lars Uebernickel (fd3ea18) * idosourcemenuitem: change misplaced g_return_val_if_fail() 2015-07-28 21:12:27 +0000 CI Train Bot (f007376) * Releasing 13.10.0+15.10.20150728-0ubuntu1 (refs/bzr/origin/tags/13.10.0+15.10.20150728-0ubuntu1) 2015-07-28 21:12:24 +0000 Marco Trevisan (Treviño) (0358338) * IdoCalendarMenuItem: add crash guard on ido_calendar_menu_item_key_press 2015-07-22 16:00:57 +0200 Marco Trevisan (Treviño) (ac4bbf0) * IdoCalendarMenuItem: add crash guard on ido_calendar_menu_item_key_press 2015-03-19 16:24:01 +0000 CI Train Bot (6f2f647) * Releasing 13.10.0+15.04.20150319-0ubuntu1 (refs/bzr/origin/tags/13.10.0+15.04.20150319-0ubuntu1) 2015-03-19 16:23:58 +0000 Lars Uebernickel (4c578ba) * idoscalemenuitem: fix scale hover state Approved by: Sebastien Bacher, PS Jenkins bot, Simon Steinbeiß 2015-03-10 12:38:25 +0100 Lars Uebernickel (3bef6a1) * idoscalemenuitem: set focus flag on scale 2015-03-10 12:14:50 +0100 Lars Uebernickel (07a3027) * idoscalemenuitem: translate motion event coordinates 2015-01-30 14:25:14 +0000 CI Train Bot (fced82c) * Releasing 13.10.0+15.04.20150130-0ubuntu1 (refs/bzr/origin/tags/13.10.0+15.04.20150130-0ubuntu1) 2015-01-30 14:25:03 +0000 Lars Uebernickel (3445894) * idoplaybackmenuitem: don't set the spinner class 2015-01-30 15:06:46 +0100 Lars Uebernickel (1f922e5) * idoplaybackmenuitem: don't set the spinner class 2015-01-22 11:56:22 +0000 CI Train Bot (467b70e) * Releasing 13.10.0+15.04.20150122-0ubuntu1 (refs/bzr/origin/tags/13.10.0+15.04.20150122-0ubuntu1) 2015-01-22 11:56:09 +0000 Lars Uebernickel (9f8609c) * idoscalemenuitem: fix slider event forwarding Approved by: Iain Lane, PS Jenkins bot 2015-01-21 19:21:23 +0100 Lars Uebernickel (22e14c5) * idoscalemenuitem: remove extraneous line 2015-01-21 19:14:49 +0100 Lars Uebernickel (3ae1abb) * idoscalemenuitem: only forward button events that are inside the scale 2015-01-21 18:47:36 +0100 Lars Uebernickel (b42893f) * idoscalemenuitem: don't translate event coordinates 2014-11-03 20:57:41 +0000 CI bot (d69f78b) * Releasing 13.10.0+15.04.20141103-0ubuntu1 (refs/bzr/origin/tags/13.10.0+15.04.20141103-0ubuntu1) 2014-11-03 20:57:33 +0000 Ted Gould (2d4009b) * Update tags for newer GObject Introsepction Scanner and disable xorg-gtest tests Fixes: 1382020 Approved by: PS Jenkins bot 2014-11-03 10:42:36 -0600 Ted Gould (c3c628d) * Filter out symbols in the library 2014-11-03 10:04:09 -0600 Ted Gould (fae005a) * Comment out xorg-gtest tests 2014-10-16 08:45:32 -0500 Ted Gould (e9522b4) * Add lcov version 1.11 2014-10-16 08:17:14 -0500 Ted Gould (5c4cf2d) * Update tags for newer GObject Introsepction Scanner 2014-04-23 17:03:36 +0000 CI bot (01ce8c3) * Releasing 13.10.0+14.04.20140423-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140423-0ubuntu1) 2014-04-23 17:03:27 +0000 Lars Uebernickel (bc444da) * Make long track infos better readable 2014-04-23 16:37:18 +0200 Lars Uebernickel (82c094a) * idoplaybackmenuitem: don't introduce even more magic numbers 2014-04-23 12:02:32 +0200 Lars Uebernickel (8844b19) * idoplaybackmenuitem: center the controls horizontally 2014-04-23 12:01:33 +0200 Lars Uebernickel (3c5e4d8) * idomediaplayermenuitem: don't hardcode width 2014-04-23 11:59:00 +0200 Lars Uebernickel (560f933) * idomediaplayermenuitem: use small font for track info labels 2014-04-07 12:30:17 +0000 CI bot (c734bb8) * Releasing 13.10.0+14.04.20140407-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140407-0ubuntu1) 2014-04-07 12:30:06 +0000 Lars Uebernickel (c3fc9b1) * idobasicmenuitem: update icon when the theme changes 2014-04-04 19:37:23 +0200 Lars Uebernickel (220d43c) * idobasicmenuitem: don't export update_image() 2014-04-04 19:01:44 +0200 Lars Uebernickel (b7ec0fe) * idobasicmenuitem: update icon when the theme changes 2014-03-28 11:27:53 +0000 CI bot (1c842fe) * Releasing 13.10.0+14.04.20140328-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140328-0ubuntu1) 2014-03-28 11:27:50 +0000 CI bot (0627003) * Update symbols 2014-03-28 11:27:41 +0000 Lars Uebernickel (d973b78) * idoplaybackmenuitem: propagate events in the menu keyrelease handler 2014-03-28 11:27:32 +0000 Lars Uebernickel (6e90a5c) * expose idobasicmenuitem, a normal menu item that supports non-square icons 2014-03-28 11:27:23 +0000 Lars Uebernickel (34b23e2) * Highlight back/forward buttons when hovering them with the pointer 2014-03-28 11:27:12 +0100 Lars Uebernickel (8269c14) * idobasicmenuitem: check return value of gtk_icon_info_get_filename() for NULL 2014-03-27 17:10:17 +0100 Lars Uebernickel (ab158b1) * idobasicmenuitem: add symbol for _new_from_model() 2014-03-27 13:16:39 +0100 Lars Uebernickel (d1403eb) * idobasicmenuitem: support non-square icons 2014-03-27 13:16:10 +0100 Lars Uebernickel (b5fe1d7) * Expose IdoBasicMenuItem as com.canonical.indicator.basic 2014-03-26 17:07:21 +0100 Lars Uebernickel (7614e88) * idobasicmenuitem: put progress menu item into its own file 2014-03-26 14:35:19 +0100 Lars Uebernickel (0ddb492) * idoplaybackmenuitem: propagate events in the menu keyrelease handler 2014-03-25 19:00:21 +0100 Lars Uebernickel (02c9ed6) * Highlight back/forward buttons when hovering them with the pointer 2014-03-25 18:57:25 +0100 Lars Uebernickel (a877446) * idoplaybackmenuitem: put action names into array keyed by buttons 2014-03-24 17:45:12 +0000 CI bot (e14ab5d) * Releasing 13.10.0+14.04.20140324-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140324-0ubuntu1) 2014-03-24 17:45:04 +0000 Lars Uebernickel (f592103) * idoplaybackmenuitem: set active flag when player is launching 2014-03-24 16:09:02 +0100 Lars Uebernickel (5a77702) * idoplaybackmenuitem: set active flag when player is launching 2014-03-24 16:08:30 +0100 Lars Uebernickel (ab0798e) * idoplaybackmenuitem: don't add .menu css class on the menu item 2014-03-21 06:56:56 +0000 CI bot (bfd8fef) * Releasing 13.10.0+14.04.20140321-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140321-0ubuntu1) 2014-03-21 06:56:47 +0000 Lars Uebernickel (96d791b) * idoapplicationmenuitem: request correct size for empty icons 2014-03-20 14:16:59 +0100 Lars Uebernickel (69e211f) * idoapplicationmenuitem: request correct size for empty icons 2014-03-13 10:15:45 +0000 CI bot (5cdbd5d) * Releasing 13.10.0+14.04.20140313-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140313-0ubuntu1) 2014-03-13 10:15:33 +0000 Lars Uebernickel (60495e0) * idoscalemenuitem: use the scale's actual size allocation for events Fixes: 1069762 2014-03-12 18:25:55 +0100 Lars Uebernickel (40079a7) * Put some space between scale and min/max buttons 2014-03-12 18:24:35 +0100 Lars Uebernickel (3c6efc9) * Remove toggle-size-allocate handler 2014-03-12 18:18:58 +0100 Lars Uebernickel (b500b83) * idoscalemenuitem: use the scale's actual size allocation for events 2014-02-13 15:54:16 +0000 CI bot (a52c1a6) * Releasing 13.10.0+14.04.20140213-0ubuntu1 (refs/bzr/origin/tags/13.10.0+14.04.20140213-0ubuntu1) 2014-02-13 15:54:06 +0000 Sebastien Bacher (4a24fe6) * Update the Standards-Version 2014-02-13 10:52:33 +0100 Sebastien Bacher (a1b73d7) * Update the Standards-Version 2014-01-07 20:27:09 +0000 Ken VanDine (8f62a0c) * Sync changes uploaded to the archive back to trunk . 2014-01-07 13:57:50 -0500 Ken VanDine (3ebe5c1) * Build with -Wno-error=deprecated-declarations. 2013-12-19 08:50:47 -0600 Ted Gould (b475408) * Allow gcov 1.10 2013-12-19 08:50:11 -0600 Ted Gould (77d4d12) * No error for deprecations 2013-12-18 16:41:21 -0600 Ted Gould (abf7494) * Allow gcov 1.10 2013-12-18 15:59:07 -0600 Ted Gould (ba3a014) * No error for deprecations 2013-11-28 11:18:59 +0000 Lars Uebernickel (e3f4d1d) * IdoScaleMenuItem: intercept left and right keys. Fixes: https://bugs.launchpad.net/bugs/1242550. 2013-11-28 11:28:05 +0100 Lars Uebernickel (8035c97) * IdoScaleMenuItem: allow changing value with left/right and +/- keys 2013-11-27 12:49:11 +0000 Automatic PS uploader (d0714b7) * Releasing 13.10.0+14.04.20131127-0ubuntu1 (revision 162 from lp:ido). 2013-11-27 11:37:40 +0000 Automatic PS uploader (a5b1e91) * Releasing 13.10.0+14.04.20131127-0ubuntu1, based on r162 2013-11-27 10:51:10 +0000 Lars Uebernickel (b4f0d45) * idoactionhelper: remove potentially stray idle source when finalizing. 2013-11-27 10:53:47 +0100 Lars Uebernickel (ee400c2) * idoactionhelper: remove potentially stray idle source when finalizing 2013-11-26 22:03:58 +0000 Automatic PS uploader (74a2e43) * Releasing 13.10.0+14.04.20131126-0ubuntu1 (revision 160 from lp:ido). 2013-11-26 19:28:37 +0000 Automatic PS uploader (b4af2fc) * Releasing 13.10.0+14.04.20131126-0ubuntu1, based on r160 2013-11-26 19:23:37 +0000 Lars Uebernickel (04c85ff) * ido_calendar_menu_item_new_from_model: initialize local variables with NULL 2013-11-26 19:52:21 +0100 Lars Uebernickel (8d76820) * ido_calendar_menu_item_new_from_model: initialize local variables with NULL 2013-11-06 13:04:14 +0000 Automatic PS uploader (d1cdca8) * Releasing 13.10.0+14.04.20131106-0ubuntu1 (revision 158 from lp:ido). 2013-11-06 11:23:53 +0000 Automatic PS uploader (9bb7ffc) * Releasing 13.10.0+14.04.20131106-0ubuntu1, based on r158 2013-11-06 09:53:02 +0000 Lars Uebernickel (48b2262) * ido_user_menu_item: remove superfluous unref 2013-11-06 10:28:02 +0100 Lars Uebernickel (bb2f459) * ido_user_menu_item: remove superfluous unref 2013-11-05 17:51:51 +0000 Automatic PS uploader (0a01da4) * Releasing 13.10.0+14.04.20131105.1-0ubuntu1 (revision 156 from lp:ido). 2013-11-05 11:01:57 +0000 Automatic PS uploader (3f79da9) * Releasing 13.10.0+14.04.20131105.1-0ubuntu1, based on r156 2013-11-05 11:01:43 +0000 Automatic PS uploader (447b26e) * Update symbols 2013-10-31 19:51:36 +0000 Lars Uebernickel (e1fa7c7) * idoscalemenuitem: disconnect signal from parent 2013-10-31 11:07:00 -0700 Lars Uebernickel (10c52b7) * idoscalemenuitem: disconnect signal from parent 2013-10-28 18:45:52 +0000 Lars Uebernickel (28427a3) * IdoUserMenuItem: only allow file icons as avatars 2013-10-28 10:16:39 -0700 Lars Uebernickel (6485128) * ido_user_menu_item_set_icon_from_file_icon: don't initialize width and height 2013-10-28 10:12:52 -0700 Lars Uebernickel (a2e6b66) * ido_user_menu_item_set_icon_from_file_icon: free file 2013-10-27 07:24:09 -0700 Lars Uebernickel (0e079e8) * Don't export ido_user_menu_item_set_icon_from_file_icon() 2013-10-26 15:03:51 -0400 Lars Uebernickel (dc577ba) * IdoUserMenuItem: only allow file icons as avatars 2013-10-24 11:01:59 -0400 Lars Uebernickel (cd88b8a) * Also allow using + and - keys to change the slider 2013-10-22 20:13:38 +0000 Lars Uebernickel (596e38b) * Make IdoSwitchMenuItem accessible from gtk_menu_new_from_model. 2013-10-22 15:35:22 -0400 Lars Uebernickel (bccb3fb) * Unref serialized_icon 2013-10-22 15:34:23 -0400 Lars Uebernickel (180ab33) * Don't call gtk_image_clear() on a NULL widget 2013-10-22 12:11:56 -0400 Lars Uebernickel (f5c03fb) * debian: add new ido symbols 2013-10-22 12:09:37 -0400 Lars Uebernickel (d910f41) * examples: use new IdoSwitchMenuItem API 2013-10-22 11:38:57 -0400 Lars Uebernickel (898a221) * Make IdoSwitchMenuItem accessible from gtk_menu_new_from_model 2013-10-22 11:30:11 -0400 Lars Uebernickel (8a99ede) * IdoSwitchMenuItem: deprecate get_content_area and add set_{label,icon} 2013-10-21 17:41:51 -0400 Lars Uebernickel (8fe2bdf) * IdoScaleMenuItem: intercept left and right keys 2013-10-11 10:23:45 +0000 Automatic PS uploader (6e849d5) * Releasing 13.10.0+13.10.20131011-0ubuntu1 (revision 152 from lp:ido). 2013-10-11 04:28:12 +0000 Automatic PS uploader (845d114) * Releasing 13.10.0+13.10.20131011-0ubuntu1, based on r152 2013-10-10 21:32:13 +0000 Lars Uebernickel (302d244) * idoscalemenuitem: request a minimum width of 200px. 2013-10-10 07:30:45 +0200 Lars Uebernickel (30289d8) * idoscalemenuitem: request a minimum width of 200px 2013-09-30 14:34:36 +0000 Lars Uebernickel (ebffc6d) * idousermenuitem: center avatar and adjust spacing. 2013-09-30 12:24:55 +0000 Automatic PS uploader (5c5055d) * Releasing 13.10.0+13.10.20130930-0ubuntu1 (revision 149 from lp:ido). 2013-09-30 12:48:24 +0200 Lars Uebernickel (a5ee7a6) * idousermenuitem: center user avatars and adjust spacing 2013-09-30 06:32:59 +0000 Automatic PS uploader (9db63ea) * Releasing 13.10.0+13.10.20130930-0ubuntu1, based on r149 2013-09-25 15:09:18 +0000 Lars Uebernickel (8a9333d) * idoscalemenuitem: don't update the action state when the action state changes 2013-09-25 00:11:13 +0200 Lars Uebernickel (ed88015) * idoscalemenuitem: don't update the action state when the action state changes 2013-09-20 12:25:24 +0000 Automatic PS uploader (4bc9bfd) * Releasing 13.10.0+13.10.20130920-0ubuntu1 (revision 147 from lp:ido). 2013-09-20 10:20:28 +0000 Automatic PS uploader (93686c5) * Releasing 13.10.0+13.10.20130920-0ubuntu1, based on r147 2013-09-16 14:38:53 +0000 Lars Uebernickel (d6cd512) * Reverse slider movement when scrolling by default. Fixes: https://bugs.launchpad.net/bugs/1225330. 2013-09-15 20:21:14 +0200 Lars Uebernickel (a947c80) * Revert slider movement when scrolling by default 2013-08-14 06:19:54 +0000 Automatic PS uploader (e95f316) * Releasing 13.10.0+13.10.20130814-0ubuntu1 (revision 145 from lp:ido). 2013-08-14 02:58:11 +0000 Automatic PS uploader (8e3c2c4) * Releasing 13.10.0+13.10.20130814-0ubuntu1, based on r145 2013-08-14 02:58:07 +0000 Automatic PS uploader (4c88448) * Update symbols 2013-08-13 21:28:03 +0000 Lars Uebernickel (05443b6) * Add widgets for messaging menu. 2013-08-13 15:28:16 -0500 Ted Gould (bb86413) * Library functions taking GVariant params need to ref_sink() and unref() always. (reason #24 to not like GVariant) 2013-08-13 14:36:18 -0500 Ted Gould (f19d539) * Adding new symbols 2013-08-13 18:50:26 +0200 Lars Uebernickel (be7301a) * Add IdoSourceMenuItem 2013-08-13 16:05:52 +0200 Lars Uebernickel (8b1bba6) * Add IdoApplicationMenuItem 2013-07-31 09:31:45 +0000 Automatic PS uploader (242477c) * Releasing 13.10.0+13.10.20130731-0ubuntu1 (revision 143 from lp:ido). 2013-07-31 02:02:57 +0000 Automatic PS uploader (c835e93) * Releasing 13.10.0+13.10.20130731-0ubuntu1, based on r143 2013-07-31 02:02:53 +0000 Automatic PS uploader (a79b455) * Update symbols 2013-07-30 22:17:45 +0000 Charles Kerr (86b63cf) * Support x-canonical-type: "com.canonical.indicator.progress" and "com.canonical.indicator.alarm". 2013-07-25 22:19:28 -0500 Charles Kerr (ad7dd27) * sync two removed API functions: ido_location_menu_item_set_format, ido_location_menu_item_set_name 2013-07-25 18:57:29 -0500 Charles Kerr (5761e8d) * implement IdoLocationMenuItem as a subclass of IdoTimeStampMenuItem 2013-07-25 18:53:48 -0500 Charles Kerr (1b71666) * add support for com.canonical.indicator.alarm menuitems. 2013-07-25 18:34:23 -0500 Charles Kerr (c823c87) * implement IdoAppointmentMenuItem as a specialization of IdoTimeStampMenuItem 2013-07-25 18:22:08 -0500 Charles Kerr (8978437) * add IdoTimeStampMenuItem, a base class for appointments, locations, and alarms 2013-07-25 16:24:49 -0500 Charles Kerr (3565dad) * subclass IdoAppointmentMenuItem from IdoBasicMenuItem 2013-07-25 16:22:45 -0500 Charles Kerr (b4cc30d) * add a 6px margin between the icon and primary text iff the icon is visible 2013-07-25 15:53:36 -0500 Charles Kerr (124564d) * subclass IdoLocationMenuItem from IdoBasicMenuItem 2013-07-25 15:51:57 -0500 Charles Kerr (8a9b4b8) * add make the type macro for IdoBasicMenuItem follow the standard naming scheme 2013-07-24 13:10:19 -0500 Charles Kerr (2ef49dc) * don't hardcode making com.canonical.indicator.progress insensitive; its sensitivity should follow its action's sensitivity. 2013-07-24 13:09:24 -0500 Charles Kerr (69f5f2c) * add public API symbols to debian/ 2013-07-24 00:08:29 -0500 Charles Kerr (79875b4) * add a menuitem that renders com.canonical.indicator.progress as laid out in https://wiki.ubuntu.com/Power#Phone 2013-07-03 17:35:51 +0000 Automatic PS uploader (f3e64f7) * Releasing 13.10.0+13.10.20130703.1-0ubuntu1 to ubuntu. 2013-07-03 14:16:50 +0000 Automatic PS uploader (e7bf359) * Releasing 13.10.0+13.10.20130703.1-0ubuntu1, based on r141 2013-07-03 03:19:42 +0000 Ted Gould (f40fb90) * Fix broken comments for the introspection scanner. 2013-07-02 21:13:03 -0500 Ted Gould (fd29ab9) * Fixing some small introspection errors 2013-07-02 22:54:31 +0000 Charles Kerr (829c2c2) * fix IdoLocationMenuItem label alignment issue reported by ted. 2013-07-02 15:38:01 -0500 Charles Kerr (644fe6e) * revert the UBUNTU_MENUPROXY line since will's reverting the gtk menu proxy to support it as before 2013-07-02 08:54:23 -0500 Charles Kerr (3eb1596) * add test cases of IdoLocationMenuItem to the 'menus' example app 2013-07-02 08:53:21 -0500 Charles Kerr (8c347eb) * in idolocationmenuitem, fix slight alignment issue in the city label 2013-07-02 09:21:41 +0000 Automatic PS uploader (20247ad) * Releasing 13.10.0+13.10.20130702-0ubuntu1 to ubuntu. 2013-07-02 02:02:50 +0000 Automatic PS uploader (4f76867) * Releasing 13.10.0+13.10.20130702-0ubuntu1, based on r138 2013-07-01 20:34:31 +0000 Charles Kerr (43222b3) * Test to see if a user's avatar is loadable before we use it. 2013-07-01 12:23:13 -0500 Charles Kerr (14e5eeb) * in ido_user_menu_item_set_icon(), remove a g_warning iff icon is NULL 2013-07-01 11:56:15 -0500 Charles Kerr (059926d) * don't load the icon twice 2013-07-01 11:11:26 -0500 Charles Kerr (e31ab7b) * if a user's avatar icon file doesn't exist or isn't readable, fall back to the default avatar 2013-06-28 16:55:04 +0000 Automatic PS uploader (5c6e761) * Releasing 13.10.0+13.10.20130628-0ubuntu1 to ubuntu. 2013-06-28 02:03:07 +0000 Automatic PS uploader (c0080ba) * Releasing 13.10.0+13.10.20130628-0ubuntu1, based on r136 2013-06-28 02:02:57 +0000 Automatic PS uploader (9d1a1d7) * Update symbols 2013-06-27 19:25:56 +0000 Charles Kerr (fbabe33) * one-liner fix to a copy-paste error in GuestMenuItem's handling of online/active guests. 2013-06-27 12:02:41 -0500 Charles Kerr (549a1b5) * fix a copy-paste bug in the last commit's GuestMenuItem code 2013-06-24 02:34:25 +0000 Charles Kerr (49b6a15) * Adds support for the guest menuitem. 2013-06-23 19:20:58 -0500 Charles Kerr (db32e75) * oops, that @replaceme should have been 0replaceme... 2013-06-23 18:44:39 -0500 Charles Kerr (9011650) * in debian/libido3-0.1-0.symbols, add the new symbols 2013-06-23 18:37:38 -0500 Charles Kerr (1f0bfc0) * silence console warnings when a NULL filename is passed into ido_user_menu_item_set_icon_from_filename() 2013-06-23 18:06:39 -0500 Charles Kerr (8008ec3) * add ido_guest_menu_item_new_for_model() 2013-06-23 17:43:19 -0500 Charles Kerr (61ce727) * add an 'icon' property to idousermenuitem 2013-06-20 01:51:44 +0000 Lars Uebernickel (8f8d487) * Add IdoMediaPlayerMenuItem and IdoPlaybackMenuItem. 2013-06-19 18:50:42 -0400 Lars Uebernickel (e88a842) * ido_playback_menu_item_parent_key_press_event: be more explicit 2013-06-19 18:49:38 -0400 Lars Uebernickel (80a024e) * idoplaybackmenuitem: remove redundant 'else' 2013-06-19 18:48:26 -0400 Lars Uebernickel (5aca3b4) * idoplaybackmenuitem: warn before crashing in g_str_equal 2013-06-19 17:16:20 -0400 Lars Uebernickel (e2de482) * ido_playback_menu_item_get_button_at_pos: add ascii blueprint 2013-06-19 17:07:59 -0400 Lars Uebernickel (5d9faae) * ido_media_player_menu_item_state_changed: declare constant variables as const 2013-06-19 17:06:38 -0400 Lars Uebernickel (ba02d52) * idomediaplayermenuitem: allow non-local album art 2013-06-19 16:03:34 -0400 Lars Uebernickel (52a73fd) * idomediaplayermenuitem: make album art size a #define 2013-06-19 16:00:59 -0400 Lars Uebernickel (810627e) * debian: add new symbols 2013-06-19 16:00:36 -0400 Lars Uebernickel (bf73049) * idoplaybackmenuitem.c: mark internal functions as static 2013-06-19 10:58:55 -0400 Lars Uebernickel (9bf880d) * Merge trunk 2013-06-19 13:08:31 +0000 Automatic PS uploader (e84fd15) * Releasing 13.10.0daily13.06.19-0ubuntu1 to ubuntu. 2013-06-19 02:02:29 +0000 Automatic PS uploader (a2aa0cb) * Releasing 13.10.0daily13.06.19-0ubuntu1, based on r132 2013-06-19 02:02:15 +0000 Automatic PS uploader (f9589a7) * Update symbols 2013-06-17 17:50:43 -0400 Lars Uebernickel (bfb0755) * IdoPlaybackMenuItem: listen to state changes of the 'play' action 2013-06-17 16:37:33 +0000 Charles Kerr (7265359) * Better handling of IdoMenuItem construction from GMenuItems, better public API documentation. 2013-06-17 12:15:34 -0400 Lars Uebernickel (01d0c0b) * Add IdoPlaybackMenuItem 2013-06-17 11:14:36 -0500 Charles Kerr (0aa36d9) * copyediting: fix copy/paste errors in the documentation 2013-06-17 11:09:43 -0500 Charles Kerr (3291597) * in IdoAppointmentMenuItem's update_timestamp_label(), clear the label text if either the time or format properties are unset 2013-06-17 10:59:26 -0500 Charles Kerr (0348539) * add documentation for the public API calls 2013-06-17 10:41:25 -0500 Charles Kerr (9205983) * when building location and appointment menuitems from a GMenu, grab all the parameters and then pass them to object_new() as a block to avoid them getting set twice -- once with the constructor's default values, and then once afterwards 2013-06-17 10:04:35 -0500 Charles Kerr (6de8e03) * in idoappointmentmenuitem.c, fix startup issue arising from updating the timestamp label when the strftime format string hasn't been initialized yet. 2013-06-15 17:37:22 +0000 Charles Kerr (83e4735) * adds the ido widgets needed for indicator-datetime. 2013-06-15 10:39:53 -0500 Charles Kerr (53ee722) * in debian/libido3-0.1-0.symbols, that should be '0replaceme'... 2013-06-14 22:59:40 -0500 Charles Kerr (1a47ea1) * add the new calendar, appointment, location symbols to debian/ 2013-06-14 19:10:26 -0500 Charles Kerr (2e5b7f3) * fix time_t issue in idocalendarmenuitem's gmenu code 2013-06-14 19:10:05 -0500 Charles Kerr (5d6dce1) * bump version from 13.10.0 to 13.10.1 2013-06-14 14:15:11 -0500 Charles Kerr (2e2f7e3) * in idolocationmenuitem, assume seconds are shown in the timestamp when the time format string includes '%s', '%S', '%T', '%X', or '%c' 2013-06-14 13:22:03 -0500 Charles Kerr (5988e06) * add ted's name to idoappointmentmenuitem.c for create_color_icon_pixbuf() 2013-06-14 13:21:27 -0500 Charles Kerr (914258f) * remove g_message that leaked into last commit 2013-06-14 13:04:45 -0500 Charles Kerr (17c7bd1) * add calendar, location, and appointment menuitems to the IDO factory 2013-06-14 13:04:00 -0500 Charles Kerr (9373536) * add ido_calendar_menu_item_new_from_model() 2013-06-14 13:03:08 -0500 Charles Kerr (88522dc) * add location menuitem 2013-06-14 13:02:50 -0500 Charles Kerr (3db9d6f) * add appointment menuitem 2013-06-12 17:43:36 -0400 Lars Uebernickel (ef70e33) * Add IdoMediaPlayerMenuItem 2013-06-08 03:52:10 +0000 Jeremy Bicha (7610132) * Depend on valac instead of valac-0.16 for easier transitions Have libido3-0.1-dev depend on gir1.2-ido3-0.1 Drop unnecessary gir build-depends. 2013-06-07 22:57:57 -0400 Jeremy Bicha (f265a16) * Depend on valac instead of valac-0.16 for easier transitions Have libido3-0.1-dev depend on gir1.2-ido3-0.1 Drop unnecessary gir build-depends 2013-06-07 21:41:53 +0000 Lars Uebernickel (c80dc60) * Add support for creating scale menu items from a menu model. 2013-06-07 17:31:39 -0400 Lars Uebernickel (62ed83c) * Merge trunk 2013-06-07 16:55:11 -0400 Lars Uebernickel (8db174a) * idoscalemenuitem: look "{min,max}-icon" on the GMenuItem 2013-06-07 09:54:07 +0000 Automatic PS uploader (b36e57d) * Releasing 13.10.0daily13.06.07-0ubuntu1 to ubuntu. 2013-06-07 02:02:41 +0000 Automatic PS uploader (c9dba5a) * Releasing 13.10.0daily13.06.07-0ubuntu1, based on r127 2013-06-07 02:02:38 +0000 Automatic PS uploader (5dc4419) * Update symbols 2013-05-31 19:38:19 -0400 Lars Uebernickel (c23cdfc) * debian: add new symbols 2013-05-31 18:51:10 -0400 Lars Uebernickel (26d057c) * Add support for creating scale menu items from a menu model 2013-05-31 18:50:09 -0400 Lars Uebernickel (03dc54f) * Add ido_action_helper_change_state 2013-05-31 17:26:12 -0400 Lars Uebernickel (cb6475e) * idoscalemenuitem: make the scale expand and fill in the menu item 2013-05-31 19:51:15 +0000 Charles Kerr (e5d2187) * Put a framework in place to move custom menu items from the indicator packages into ido. It depends on a vendor-patch to gtk (see bug #1183505), because gtk+ does not yet have an API for inserting arbitrary menu items into menus created with gtk_menu_new_from_model(). 2013-05-31 14:42:41 -0400 Lars Uebernickel (18f2ca9) * debian: add new symbols 2013-05-31 14:02:40 -0400 Lars Uebernickel (52b6ef7) * Bump glib and gtk dependencies 2013-05-31 11:15:39 -0400 Lars Uebernickel (3578bb3) * ido_user_menu_item_new_from_model: fix docstring 2013-05-27 12:04:11 -0400 Lars Uebernickel (e863f12) * Move crate_user_menu_item into idousermenuitem.c 2013-05-27 11:11:02 -0400 Lars Uebernickel (07f7907) * IdoActionHelper: document signals and properties 2013-05-27 11:10:39 -0400 Lars Uebernickel (d447489) * debian/changelog: bump version 2013-05-24 15:17:47 -0400 Lars Uebernickel (2c0fa18) * GtkMenuItemFactory -> UbuntuMenuItemFactory 2013-05-23 18:41:17 -0400 Lars Uebernickel (725c0ad) * Bumb version to 13.10 2013-05-23 08:58:55 -0400 Lars Uebernickel (424d5f4) * Create IdoUserMenuItems for indicator.user-menu-item 2013-05-22 23:35:52 -0400 Lars Uebernickel (1856933) * Merge IdoUserMenuItem branch 2013-05-22 23:19:50 -0400 Lars Uebernickel (12a5f15) * Add IdoActionHelper 2013-05-22 22:51:19 -0400 Lars Uebernickel (3f3aa14) * Add IdoMenuItemFactory 2013-03-27 08:30:38 -0500 Charles Kerr (e9c82c3) * rename idousermenuitem's "icon" property as "icon-filename" for a little more clarity. 2013-03-26 16:30:46 -0500 Charles Kerr (0430322) * in ido_user_menu_item_primitive_draw_cb_gtk_3(), remove deprecated use of gtk_widget_get_style(), gtk_widget_get_state() 2013-03-26 16:25:04 -0500 Charles Kerr (49c57fd) * add idousermenuitem to the examples 2013-03-26 16:24:47 -0500 Charles Kerr (259c7ad) * add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem 2013-03-26 15:14:33 -0500 Charles Kerr (2d8eac6) * rename user-widget.[ch] to idousermenuitem.[ch]. Not building yet, next step is to decouple from dbusmenu. 2013-03-26 15:05:06 -0500 Charles Kerr (bf3b14f) * add user-widget.[ch] from indicator-session's trunk 2013-03-01 14:54:13 +0000 Automatic PS uploader (27f3661) * Releasing 12.10.3daily13.03.01-0ubuntu1 to ubuntu. 2013-03-01 02:02:45 +0000 Automatic PS uploader (34b7cb3) * Releasing 12.10.3daily13.03.01-0ubuntu1, based on r125 2013-02-27 15:19:49 +0000 Mathieu Trudel-Lapierre (3f9644c) * Fix linking against X11 and Xi which xorg-gtest now seems to require. I'll fix xorg-gtest directly too (in progress), but this is to avoid blocking builds and daily release. Fixes: https://bugs.launchpad.net/bugs/1126353. 2013-02-27 09:49:27 -0500 Mathieu Trudel-Lapierre (3fae0ab) * Explicitly link against X11 and Xi while xorg-gtest doesn't. 2013-02-06 18:36:45 +0000 Mathieu Trudel-Lapierre (f294976) * Fix building against gtest/xorg-gtest. Fixes: https://bugs.launchpad.net/bugs/1112775. 2013-02-06 11:54:10 -0500 Mathieu Trudel-Lapierre (f81bc0d) * Guard against CID:12651, division by zero of FPS value due to its use for timing timeline updates. 2013-02-06 10:10:11 -0500 Mathieu Trudel-Lapierre (d9aa6f0) * Shut up coverity about CID:12650. 2013-02-05 16:23:25 -0500 Mathieu Trudel-Lapierre (fe1d726) * Avoid FTBFS due to conflicting paths to gtest source, or because the relevant gtest files aren't found -- always use the xorg-gtest gtest source, and adjust path accordingly. 2013-01-11 16:14:38 +0000 Automatic PS uploader (22a384d) * Releasing 12.10.3daily13.01.11-0ubuntu1 to ubuntu. 2013-01-11 02:02:27 +0000 Automatic PS uploader (5b7d735) * Releasing 12.10.3daily13.01.11-0ubuntu1, based on r122 2013-01-04 11:18:51 +0000 Robert Ancell (2db941f) * Add introspection and vala support. Fixes: https://bugs.launchpad.net/bugs/582985. 2012-12-18 17:11:13 +0000 Allan LeSage (b7c4bed) * Testing with cyphermox--removing the special Xvfb auto_test override appears to resolve flaky tests under Jenkins. 2012-12-17 16:47:09 -0600 Allan LeSage (d5a5d41) * Update changelog. 2012-12-17 16:28:49 -0600 Allan LeSage (6c95630) * Remove Xvfb from debian/control. 2012-12-17 16:19:06 -0600 Allan LeSage (0219eb9) * Remove auto_test override. 2012-12-15 20:39:02 +1300 Robert Ancell (bdb9026) * Update packing for introspection/vapi 2012-12-15 11:13:12 +1300 Robert Ancell (8830da3) * Add introspection dependencies 2012-12-14 09:58:39 +1300 Robert Ancell (6c9a668) * Add introspection and Vala support to IDO 2012-12-05 16:10:09 +0000 Mathieu Trudel-Lapierre (21040fc) * Run tests through xfvb-run. 2012-12-05 10:40:53 -0500 Mathieu Trudel-Lapierre (57be74b) * - Add xvfb to Build-Depends. - Override dh_auto_test to run them through xvfb-run. 2012-11-26 17:40:13 +0000 Didier Roche (7fc48c2) * Bootstrapping ido. 2012-11-26 17:43:09 +0100 Didier Roche (638bd11) * add bootstrap comment 2012-11-26 16:37:35 +0000 Mathieu Trudel-Lapierre (2d8dd25) * Inline packaging. 2012-11-26 10:35:20 -0500 Mathieu Trudel-Lapierre (7dc37ec) * Reactivate tests, they don't fail. 2012-11-26 09:04:04 -0500 Mathieu Trudel-Lapierre (cc01061) * Drop the override for dh_makeshlibs. 2012-11-19 17:50:42 -0500 Mathieu Trudel-Lapierre (a06895c) * Temporarily disable tests via overriding dh_auto_test; they fail to properly start X in a schroot. 2012-11-19 14:12:44 -0500 Mathieu Trudel-Lapierre (6432279) * Add Vcs-Bzr, Vcs-Browser fields with a notice to uploaders. 2012-11-19 14:07:42 -0500 Mathieu Trudel-Lapierre (10bad32) * - Reorganize Build-Depends: move libxorg-gtest-dev up to be consistent with other indicator stack packages. - List libgtest-dev explicitly in Build-Depends. 2012-11-19 14:06:24 -0500 Mathieu Trudel-Lapierre (1e30ac2) * Add gnome-common to Build-Depends. 2012-11-19 14:05:55 -0500 Mathieu Trudel-Lapierre (dfaa0f4) * Override dh_autoreconf to call autogen.sh and not run configure... 2012-11-19 14:04:49 -0500 Mathieu Trudel-Lapierre (634fa1b) * * debian/rules: - Add and export DPKG_GENSYMBOLS_CHECK_LEVEL instead of passing -c4 to dh_makeshlibs. 2012-11-19 14:00:50 -0500 Mathieu Trudel-Lapierre (e1ee782) * * debian/control: - Update to match style with other indicator stack packages: use trailing commas at the end of dependency lists. 2012-11-19 13:59:30 -0500 Mathieu Trudel-Lapierre (3432ef3) * Specify that bzr-builddeb should use split mode to build the package 2012-11-19 13:58:43 -0500 Mathieu Trudel-Lapierre (804ec33) * Manually import debian/ from ido 12.10.2-0ubuntu1. 2012-11-08 09:37:00 -0600 Charles Kerr (ae5b229) * one-liner to add 'check-news' to our AM_INIT_AUTOMAKE invocation 2012-11-06 22:45:17 -0600 Charles Kerr (8b984ae) * add tests for ido_entry_menu_item_get_entry, bringing package line coverage up to 55.5% 2012-11-06 22:40:20 -0600 Charles Kerr (38965ac) * add tests for IdoCalendarMenuItems's mark/unmark/clear days, bringing package line coverage up to 55.2% 2012-11-06 22:31:24 -0600 Charles Kerr (07d422b) * add tests for IdoScaleMenuItem, bringing package line coverage to 54% 2012-11-06 22:20:20 -0600 Charles Kerr (33683f3) * add more coverage for idocalendar. total package's line coverage is up to 50% now 2012-11-06 22:06:59 -0600 Charles Kerr (0b83123) * add tests for idomessagedialog 2012-11-06 21:18:21 -0600 Charles Kerr (12437e9) * add missing G_BEGIN_DECLS call 2012-11-06 21:04:57 -0600 Charles Kerr (9d88f5c) * add IdoSwitchMenuItem test 2012-11-06 20:59:43 -0600 Charles Kerr (d2c974f) * extract-method: TestMenuItems::PutInMenu() 2012-09-20 10:59:26 -0500 Charles Kerr (3e84f25) * 12.10.2 (refs/bzr/origin/tags/12.10.2) 2012-09-20 12:11:22 +0000 Charles Kerr (b98fedd) * the calendar widget shouldn't eat the ESC key.. Fixes: https://bugs.launchpad.net/bugs/964005. Approved by Lars Uebernickel, jenkins. 2012-09-19 23:32:58 -0500 Charles Kerr (20fe9d4) * the calendar widget shouldn't eat the ESC key. 2012-08-27 22:11:59 +0200 Lars Uebernickel (63717ff) * 12.10.1 (refs/bzr/origin/tags/12.10.1) 2012-08-27 22:01:07 +0200 Lars Uebernickel (bfdc842) * Merge lp:~larsu/ido/remove-slider-hack-953757 2012-08-22 09:57:08 -0500 Charles Kerr (2481b74) * merge lp:~charlesk/ido/nogtk2 to remove gtk2 support from the configure script and the source 2012-08-22 09:44:00 -0500 Charles Kerr (7330280) * remove the gtk2 conditional compiles for IdoMessageDialog 2012-08-22 09:43:24 -0500 Charles Kerr (2c68871) * remove the gtk2 conditional compiles for IdoCalendarMenuItem 2012-08-22 09:41:36 -0500 Charles Kerr (821b008) * remove the gtk2 conditional compiles for IdoEntryMenuItem 2012-08-22 09:39:22 -0500 Charles Kerr (fc8fad2) * sync with lp:ido 2012-08-21 20:59:37 -0500 Charles Kerr (8f279d3) * merge lp:~ken-vandine/ido/link-libm to AC_CHECK_LIBM to get -lm now that gtk doesn't include that in it's .pc file (refs/bzr/origin/tags/12.10.0) 2012-08-21 20:51:24 -0500 Charles Kerr (a0631d3) * merge lp:~charlesk/ido/switch to add GtkSwitchMenuItem 2012-08-21 20:06:46 -0500 Charles Kerr (d4f4fa3) * bump to 12.10.0 2012-08-21 16:43:49 -0500 Charles Kerr (402fffb) * revert the event delegation for now, it's not necessary for FF 2012-08-21 15:19:12 -0500 Charles Kerr (fbd76f4) * when the mouse is over the GtkSwitch widget, the menuitem should delegate the mouse down and motion events to it. 2012-08-21 14:34:16 -0500 Charles Kerr (fb4b306) * use gtk_menu_shell_deactivate() rather than gtk_menu_popdown(); the latter handles the issue of the menu title being painted as if the menu were still open 2012-08-21 14:27:04 -0500 Charles Kerr (791d004) * ...and if we're not clearing that in dispose(), then we don't need dispose() anymore 2012-08-21 14:24:38 -0500 Charles Kerr (c0af3f5) * don't keep the GBinding pointer around, it'll be destroyed automatically when the menuitem's destroyed 2012-08-21 13:19:50 -0500 Charles Kerr (0f1f31d) * comment tweaks 2012-08-21 13:10:11 -0500 Charles Kerr (e99fb9f) * make the glib 2.32 requirement explicit in configure.ac 2012-08-21 12:22:51 -0500 Charles Kerr (992e746) * add IdoSwitchMenuItem 2012-07-24 11:18:32 -0400 Ken VanDine (cfbf3b9) * Use AC_CHECK_LIBM to get -lm now that gtk doesn't include that in it's .pc file 2012-05-07 17:18:10 -0700 Charles Kerr (84a6303) * require gtk3 2012-05-07 16:58:13 -0700 Charles Kerr (78c634c) * remove unused function ido_range_grab_notify() 2012-04-26 22:15:10 -0500 Charles Kerr (2a3f56b) * merge lp:~ted/ido/gtest to add the gtest framework and a few tests to make sure our menu items can be created and realized. 2012-04-25 15:24:26 -0500 Ted Gould (4636768) * Bring in xorg-gtest to get an X11 wrapper 2012-04-25 14:41:21 -0500 Ted Gould (62a010a) * Build a scale menu item as well 2012-04-25 14:32:14 -0500 Ted Gould (d02dfec) * Adding in the entry menuitem as well. 2012-04-25 14:31:55 -0500 Ted Gould (e112516) * Putting in the BEGIN_DECLS for the C++ folks 2012-04-25 14:22:27 -0500 Ted Gould (072a5ab) * Now we can realize the menu item to make sure it doesn't mess that up 2012-04-25 14:12:59 -0500 Ted Gould (7db7f0e) * Now we're allocating a calendar 2012-04-25 11:39:52 -0500 Ted Gould (274e477) * Adding in a dummy test and the dependencies to build it 2012-04-25 11:09:47 -0500 Ted Gould (68dedd8) * No gtk-doc.m4 needed 2012-04-25 11:09:24 -0500 Ted Gould (4f9a30d) * We've now got a test directory! 2012-04-25 11:06:56 -0500 Ted Gould (8bba0b8) * Adding in Google test build utilities 2012-04-25 10:58:47 -0500 Ted Gould (d6d8e2e) * Attaching bug 2012-04-12 10:18:01 -0500 Charles Kerr (ceb09d1) * merge lp:~allanlesage/ido/TDD to add targets to autotools build for code-coverage reporting. For more information, see this blog post: http://qualityhour.wordpress.com/2012/01/29/test-coverage-tutorial-for-cc-autotools-projects/ . 2012-03-27 23:50:43 -0500 Allan LeSage (0597fa8) * Added gcov coverage tooling. 2012-03-21 14:33:21 -0500 Ted Gould (a4ad20e) * 0.3.4 (tag: 0.3.4, refs/bzr/origin/tags/0.3.4) 2012-03-16 19:16:04 +0100 Lars Uebernickel (0d4d88d) * ido-range: chain up constructed() to base class 2012-03-16 15:45:42 +0100 Lars Uebernickel (dde8321) * Remove slider mouse button hack 2012-03-14 13:38:42 -0500 Charles Kerr (6a6e63c) * fix regression that broke mousewheel operations on the idoscale 2012-03-14 13:27:55 -0500 Charles Kerr (196217d) * fix regression that broke mousewheel operations on the idoscale 2012-03-13 10:42:05 -0500 Charles Kerr (6db7ec8) * 0.3.3 (tag: 0.3.3, refs/bzr/origin/tags/0.3.3) 2012-03-13 09:44:58 -0500 Charles Kerr (9915201) * merge lp:~charlesk/ido/lp-898611 to fix lp bug #898611 2012-03-12 23:21:26 -0500 Charles Kerr (8722b2b) * alter mouse button 2 clicks to behave like mouse button 2 clicks for lp bug #898611. 2012-03-12 17:52:19 -0500 Charles Kerr (9b02ced) * Merge lp:~charlesk/indicator-sound/lp-921065 into lp:indicator-sound to add "primary-clicked" and "secondary-clicked" events for lp bug #921065 2012-03-12 16:24:21 -0500 Charles Kerr (728b3d1) * Merge lp:~charlesk/ido/lp-906050 into lp:ido to resolve the following LP tickets: 2012-03-10 00:04:36 -0600 Charles Kerr (db0c18c) * add primary-clicked and secondary-clicked signals for lp bug #921065 2012-03-09 22:14:53 -0600 Charles Kerr (dfbd1c2) * tweak: fix some indentation damage in the header file 2012-03-09 19:10:25 -0600 Charles Kerr (8497b8e) * remove idooffscreenproxy 2012-03-09 19:04:41 -0600 Charles Kerr (942c6cc) * small code cleanup in update_packing() 2012-03-09 18:54:52 -0600 Charles Kerr (ab9e35a) * Fix LP Bug #906050 by removing idoscalemenuitem's offscreen proxy. 2012-03-09 18:53:28 -0600 Charles Kerr (c96a9ad) * don't override widget_class.state_changed in idoscalemenuitem ... that was preventing the prelight state from ever showing up there. 2012-03-09 14:50:50 -0600 Ted Gould (5b65ff3) * 0.3.2 (tag: 0.3.2, refs/bzr/origin/tags/0.3.2) 2012-02-09 00:30:16 -0500 Ken VanDine (eec3ce5) * add style class "menubar" to the offscreen proxy, this fixes the white background drawn in the sound menu menu with the current gtk3/light-themes (LP: #925700) 2012-02-08 23:18:09 -0500 Ken VanDine (a6f5ba8) * add style class "menubar" to the offscreen proxy, this fixes the white background drawn in the sound menu with the current gtk3/light-themes (LP: #925700) 2012-01-12 00:49:05 +0100 Ken VanDine (4471ef2) * Patch from ~covox (LP: #867649) 2011-12-14 13:29:26 -0500 Ken VanDine (97ead21) * removed deprecations from gtk3 and fixed sizing issues with idemessagedialog (LP: #888392) 2011-12-14 12:19:26 -0500 Ken VanDine (9b717e5) * removed deprecations from gtk3 and fixed sizing issues with idemessagedialog (LP: #888392) 2011-10-13 10:48:46 -0500 Ted Gould (50b234a) * 0.3.1 (tag: 0.3.1, refs/bzr/origin/tags/0.3.1) 2011-10-12 14:05:06 -0500 Ted Gould (8a442cf) * Fixes for ARM 2011-10-06 09:25:34 -0400 Ken VanDine (28c45e5) * one more fix for armel FTBFS 2011-10-05 13:41:37 -0400 Ken VanDine (fcda383) * Fixed FTBFS on armel (LP: #866039) 2011-10-03 17:01:24 +0200 Michal Hruby (93b180b) * Merge lp:~mhr3/ido/bug-865122 2011-10-03 16:49:54 +0200 Michal Hruby (565816b) * Get rid of unnecessary check 2011-10-03 15:27:13 +0200 Michal Hruby (81e4254) * And we need to include config.h 2011-10-03 14:58:08 +0200 Michal Hruby (ae22267) * Use the grab-notify workaround only when using Gtk3 2011-10-03 14:33:51 +0200 Michal Hruby (4dd0ca9) * Fix bug #865122 2011-09-28 13:48:27 -0500 Ted Gould (8a32a25) * 0.3.0 (tag: 0.3.0, refs/bzr/origin/tags/0.3.0) 2011-09-20 00:25:46 -0500 Ted Gould (49d7db7) * 0.2.93 (tag: 0.2.93, refs/bzr/origin/tags/0.2.93) 2011-09-16 14:34:54 -0500 Ted Gould (db19271) * Ignoring m4 2011-09-16 13:32:21 -0500 Ted Gould (90cb663) * Update Autotools and remove Shave 2011-09-16 13:24:49 -0500 Ted Gould (08a590a) * Fix the calendar item 2011-09-16 13:04:30 -0500 Ted Gould (3abfadd) * Freeing the new event 2011-09-16 12:56:44 -0500 Ted Gould (6e4d5b1) * Attaching bug 2011-09-16 12:54:10 -0500 Ted Gould (d903b29) * Putting the new code as GTK3 only 2011-09-16 12:42:17 -0500 Ted Gould (f5be40f) * Removing a bunch of debug messages 2011-09-16 12:40:28 -0500 Ted Gould (94ce65a) * Use get_origin instead of position and uncomment out our adjustments 2011-09-16 12:40:03 -0500 Ted Gould (8d56d16) * Use the root position in the event instead of finding it 2011-09-16 10:17:36 -0500 Ted Gould (8ca02b8) * Clean up some debug and such 2011-09-15 16:06:37 -0500 Ted Gould (f269963) * Reformating 2011-09-15 16:04:16 -0500 Ted Gould (f4c7db4) * A check point 2011-09-13 11:42:20 -0500 Ted Gould (1415b10) * 0.2.92 (tag: 0.2.92, refs/bzr/origin/tags/0.2.92) 2011-09-13 11:23:09 -0500 Ted Gould (3c96745) * Ignoring some junk! 2011-09-13 11:21:24 -0500 Ted Gould (24f2228) * Putting the offscreen proxy in EXTRA_DIST if we're building GTK2 version 2011-09-13 11:18:40 -0500 Ted Gould (6b7751a) * Making the proxy GTK3 only 2011-09-13 11:32:27 -0400 Robert Carr (074baff) * Only use the offscreen proxy stuff in GTK3 2011-09-13 08:53:22 -0500 Ted Gould (41f3702) * Increasing the number of warnings 2011-09-08 16:20:18 -0500 Ted Gould (9a47c76) * 0.2.91 (tag: 0.2.91, refs/bzr/origin/tags/0.2.91) 2011-09-08 10:01:23 -0400 Robert Carr (af912b9) * Merge lp:~robertcarr/ido/offscreen-scale 2011-09-06 13:52:37 -0400 Robert Carr (a2ddfbb) * Ok I take it back we don't care about border. use custom css to set border-width and radius 2011-09-06 13:00:00 -0400 Robert Carr (01dd00e) * Don't leak style context... 2011-09-06 12:53:47 -0400 Robert Carr (0d4a3db) * Use GtkBorder in drawing background 2011-09-06 10:47:17 -0400 Robert Carr (7bc5c97) * Use gtk_render_background 2011-09-02 14:55:39 -0400 Robert Carr (2f38eb3) * Whoops copyright headers 2011-09-02 14:54:40 -0400 Robert Carr (8de6cb9) * Implement an IdoOffscreenProxy object to work around GtkRange/Scale needing grabs, change IdoScaleMenuItem to make use of this. Fixes lp: #804009 2011-08-03 16:28:38 +0100 Javier Jardón (c9394c7) * configure.ac: Update autotools config a bit 2011-08-03 16:24:01 +0100 Javier Jardón (66af846) * build: Use upstream silent rules instead shave 2011-06-21 11:55:14 -0500 Ted Gould (0b3ce25) * 0.2.90 (tag: 0.2.90, refs/bzr/origin/tags/0.2.90) 2011-06-21 11:55:01 -0500 Ted Gould (5ae054d) * Commenting out boiler plate code that is causing a warning 2011-06-21 11:44:43 -0500 Ted Gould (ea37afc) * Making sure the menu example doesn't use a menu proxy 2011-06-21 11:38:32 -0500 Ted Gould (f3a7a21) * Avoid duplicate events 2011-06-21 11:32:46 -0500 Ted Gould (e1c4792) * Updating to GTK3 2011-06-20 09:34:43 -0400 Michael Terry (d61ddbe) * use const not G_CONST_RETURN 2011-06-01 16:08:47 -0400 Michael Terry (cd59e86) * drop deprecated use of event_window 2011-06-01 15:53:29 -0400 Michael Terry (db8bf6c) * adjustments aren't widgets 2011-06-01 15:49:43 -0400 Michael Terry (da4d22c) * fix build errors with gtk2 2011-06-01 15:36:43 -0400 Michael Terry (ab8fccf) * fix various unused-variable warnings; not directly related to gtk3 work, but helps focus on actual problems 2011-06-01 15:32:49 -0400 Michael Terry (d9ec4cf) * some further automake magic for dual versioning 2011-06-01 15:24:28 -0400 Michael Terry (5ddcf6b) * allow building either gtk2 or gtk3 versions; some deprecation cleanups 2011-05-27 09:06:46 -0400 Ken VanDine (3e67ec3) * porting to gtk3, WIP 2011-05-12 11:00:34 +0100 Karl Lattimer (b80a819) * fixed multiple signal issue which caused calendar jumps bug #768956 2011-03-16 12:20:48 -0500 Ted Gould (33ab93d) * 0.2.2 (tag: 0.2.2, refs/bzr/origin/tags/0.2.2) 2011-03-16 11:19:55 +0100 David Barth (add9d71) * add signals for select/activate and a set date function - merge of karl-qdh branch 2011-03-15 14:02:37 +0000 karl-qdh (d163ba5) * Bug in closure 2011-03-14 21:45:26 -0500 Ted Gould (9b651a1) * Be able to set active date and signal when it changes 2011-03-06 13:28:21 +0000 karl-qdh (3a78f4c) * minor fixes 2011-03-06 13:05:52 +0000 karl-qdh (aac5173) * Merge with trunk 2011-03-06 13:01:20 +0000 karl-qdh (368393b) * Added new API to the calendar menu item so we can change the selected day/date. Also added new signals for selecting days and selecting with double click. In indicator-datetime these signals will be connected to either launching evolution (double), or invoking a re-building of the appointments menu (single) from the selected day forward. 2011-03-02 16:19:32 -0600 Ted Gould (a38ef76) * Adding back lost API 2011-02-28 10:33:01 +0100 David Barth (8264fbe) * integrating Karl & mterry's API for exposing calendar display options 2011-02-25 13:26:35 -0500 Michael Terry (4004883) * compile fix 2011-02-25 15:25:47 +0000 karl-qdh (acbbf01) * Added return if fails to public api 2011-02-25 13:13:55 +0000 karl-qdh (ae4456b) * Gmf. 2011-02-25 13:12:18 +0000 karl-qdh (6b313f1) * Merging with trunk 2011-02-25 09:47:28 +0000 karl-qdh (a7e9eed) * Added missing getter for calendar display options 2011-02-24 16:19:39 -0500 Ken VanDine (acebf0d) * Added ido_calendar_menu_item_get_calendar back to prevent a ABI break 2011-02-24 13:25:04 -0600 Cody Russell (3072fd1) * Fixed missing semicolon. Also the code formatting was all messed up so I fixed that because I'm kind of a code formatting nazi. Sie müssen Antretenbzr diff 2011-02-24 12:55:52 -0600 Cody Russell (0ade486) * Bump version 2011-02-23 11:14:48 -0600 Ted Gould (461b168) * Adding API to the calendar menu item 2011-02-23 15:49:47 +0000 karl-qdh (b6f75c1) * Added get_date, pretty critical function 2011-02-23 15:38:31 +0000 karl-qdh (3acb7aa) * Removed useless marshal include 2011-02-23 15:35:06 +0000 karl-qdh (f18b9b8) * Fixed building of api changes 2011-02-22 15:21:54 +0000 karl-qdh (841bcef) * Removed get_calendar, we don't want it and it's unnecessary to do this 2011-02-21 16:05:48 +0000 karl-qdh (f013899) * Added month change signal too, slight cleanup of tabs 2011-02-21 09:22:31 +0000 karl-qdh (99b479d) * Added additional API for marking days and setting options 2011-01-18 11:12:19 -0600 Cody Russell (5b3b2fe) * Remove IdoGestureManager 2011-01-18 11:08:29 -0600 Cody Russell (603f327) * Fix linker problems in Natty. 2011-01-18 09:54:24 -0600 Cody Russell (9f82279) * Add GTK_LIBS to the example programs' LDADD 2010-10-07 12:19:20 -0500 Cody Russell (ecaf8c7) * Listen to GtkMenuItem's 'toggle-size-allocate' signal to get the toggle size instead of using the GSEAL'd GtkMenuItem::toggle_size value. 2010-09-24 09:46:19 -0500 Cody Russell (193b506) * Cleanup, and update to latest geis API. 2010-09-14 17:26:36 -0500 Cody Russell (9aa08ce) * Merge geis updates. 2010-09-14 17:23:39 -0500 Cody Russell (0a8cdd0) * Remove gtk-doc.make 2010-09-14 16:40:31 -0500 Cody Russell (8b95b13) * Fix properties. 2010-09-14 16:08:04 -0500 Cody Russell (846ae96) * GEIS updates. 2010-09-13 19:31:26 -0500 Cody Russell (f3ca63f) * Merge fix for bug #635370 2010-09-10 16:26:16 -0500 Cody Russell (308c307) * When we grab focus, it seemed to also select all the text. 2010-09-09 12:17:37 -0500 Cody Russell (8a939cf) * Bump version to 0.2.0. 2010-09-09 12:16:54 -0500 Cody Russell (553318d) * Bump version to 0.1.12 2010-09-09 12:14:44 -0500 Cody Russell (37df02c) * Pull in gtk-doc.make from trunk. 2010-09-09 12:15:03 +0200 David Barth (435b582) * replace gtk-doc.make with the packaging version to avoid a merge conflict 2010-09-08 12:01:35 +0200 David Barth (228cbda) * fix distcheck; thanks to seb128 2010-08-19 17:48:45 +0100 David Barth (6e46e3b) * don't export export menus over dbus, that won't work... 2010-08-15 17:47:53 +0100 Cody Russell (e90ec22) * Feel up your widgets. 2010-08-03 14:47:05 -0500 Cody Russell (f3893ee) * Fix for armel build. Patch by David Sugar. 2010-07-29 16:07:05 -0500 Cody Russell (b35ee3e) * bleh 2010-07-29 10:01:34 -0500 Cody Russell (ee58467) * Bump version. 2010-07-27 13:02:13 -0500 Cody Russell (f5a80f5) * Need to update the last progress. 2010-07-22 18:05:12 +0200 Cody Russell (9553644) * Bump version 2010-07-22 14:21:06 +0200 Cody Russell (47fbcc2) * ido_timeline_set_progress() 2010-07-20 10:52:31 +0200 Cody Russell (9197560) * Calendar keyboard navigation. 2010-07-20 10:50:29 +0200 Cody Russell (8ae5a81) * Fix something. 2010-07-20 10:33:34 +0200 Cody Russell (12736cb) * Small cleanups 2010-07-19 05:56:50 -0500 Cody Russell (29475f3) * Calendar 2010-07-15 11:21:39 -0500 Cody Russell (272dafa) * Force IdoRange to style itself by name rather than by class. Otherwise they all have the style used by the last one created. 2010-07-15 10:18:57 -0500 Cody Russell (32093b5) * Fix for distcheck 2010-07-15 09:54:48 -0500 Cody Russell (cea3e8f) * Bump version to 0.1.9 2010-07-15 09:52:20 -0500 Cody Russell (663fb98) * Merge scale-size branch. 2010-07-15 08:44:29 -0500 Cody Russell (b3dc66c) * Different range size styles. 2010-07-14 09:51:58 -0500 Cody Russell (7aed15f) * Fix compile for ARM 2010-07-13 10:00:43 -0500 Cody Russell (dfa5455) * Merge in range branch. 2010-07-13 09:45:22 -0500 Cody Russell (01d2367) * Add IdoRange, and modify IdoScaleMenuItem to use it. 2010-07-08 15:17:27 -0500 Cody Russell (09a6454) * Bump version 2010-07-08 13:49:37 -0500 Cody Russell (03c0ea4) * Fix IdoMessageDialog to compile with deprecated gtk+ for Meerkat. 2010-07-08 11:11:17 -0500 Cody Russell (e937255) * Fix license 2010-07-08 10:47:13 -0500 Cody Russell (6218c6d) * Fixes for dist 2010-07-08 10:31:49 -0500 Cody Russell (23318a5) * Bump version to 0.1.7. 2010-07-08 10:30:50 -0500 Cody Russell (b3f4350) * Merge up with trunk. 2010-07-08 10:28:53 -0500 Cody Russell (5fa7b66) * Start the morph on focus-in-event rather than button-press-event. 2010-07-07 08:48:37 -0500 Cody Russell (4405889) * Send button-press and button-release events to the entry. Also grab focus at the first key-press. 2010-07-02 11:33:56 -0500 Cody Russell (717cf40) * Set focus-on-map to FALSE. 2010-06-08 10:52:45 -0500 Cody Russell (fab639c) * Bump version to 0.1.6 2010-05-12 23:21:36 +0200 Cody Russell (a544da2) * IdoMessageDialog - a morphing message dialog. 2010-05-10 09:14:53 +0200 Cody Russell (ac894c8) * Fake out the grab stuff by setting GTK_HAS_GRAB on the scale widget before forwarding the event. 2010-05-10 02:09:13 +0200 Cody Russell (9f85050) * Try to remove offscreen fu 2010-04-14 09:53:17 -0500 Cody Russell (dd709ad) * reverse-scroll-events property only affects GDK_SCROLL_UP and GDK_SCROLL_DOWN 2010-03-24 11:26:49 +0100 David Barth (172006c) * release 0.1.5 - Don't return TRUE if keyval is GDK_Return. - Bump gtk+ requirement to 2.19.7 - Don't capture up/down keys. Compile fixes for latest gtk+. - Button press event fixes. (tag: 0.1.5, refs/bzr/origin/tags/0.1.5) 2010-03-18 13:24:02 -0500 Cody Russell (9a3de4a) * Don't return TRUE if keyval is GDK_Return. 2010-03-16 11:24:25 -0500 Cody Russell (e27e482) * Bump gtk+ requirement to 2.19.7 2010-03-16 11:10:39 -0500 Cody Russell (e965ac4) * Don't capture up/down keys. Compile fixes for latest gtk+. 2010-03-15 09:07:37 -0500 Cody Russell (d6a2f21) * Don't capture up/down keys. Compile fixes for latest gtk+. 2010-03-11 11:11:51 -0600 Cody Russell (7561ce1) * Button press event fixes. 2010-03-11 11:11:33 +0100 David Barth (cb28301) * release 0.1.4 (tag: 0.1.4, refs/bzr/origin/tags/0.1.4) 2010-03-10 23:30:45 -0600 Cody Russell (0dfd8e6) * Button press event fixes. 2010-03-09 20:42:24 -0600 Cody Russell (3865303) * Don't forward the event to the entry if the user hit the Esc key. 2010-03-09 11:43:40 -0600 Cody Russell (de771b0) * Fix for grab/release signals. If you grab the slider and then release it while the mouse is outside the menu, it was not emitting the released signal. 2010-03-08 12:45:32 -0600 Cody Russell (a46e53c) * Fix keyboard navigation issues in the entry widget, fixes bug #533284. 2010-03-08 12:38:14 -0600 Cody Russell (e2caba6) * Merge trunk 2010-03-08 08:06:25 -0600 Cody Russell (ae62dc7) * Return TRUE after forwarding the event to priv->entry 2010-03-05 16:04:11 +0000 Cody Russell (6c7fcbe) * Add grab/release signals 2010-03-04 16:44:38 -0500 Ken VanDine (af98418) * bump version to 0.1.3 2010-03-04 16:46:32 +0000 Cody Russell (2cffa85) * Make 'ido-offscreen-scale' the name of the GtkOffscreenWindow, not the GtkScale. (tag: 0.1.3, refs/bzr/origin/tags/0.1.3) 2010-03-04 10:32:56 +0000 Cody Russell (08e010a) * Name the offscreen scale 'ido-offscreen-scale' 2010-02-18 12:54:33 +0100 David Barth (3acbbdb) * bump version to 0.1.2 (tag: 0.1.2, refs/bzr/origin/tags/0.1.2) 2010-02-13 00:43:20 -0600 Cody Russell (fc660fc) * Support reversing scroll events 2010-02-11 17:21:14 -0600 Cody Russell (ad50ecd) * merge in secondary_padding branch from ken-vandine 2010-02-11 18:09:46 -0500 Ken VanDine (1841df0) * fixed build failure where secondary_padding wasn't initialized 2010-02-11 15:44:02 -0500 Ken VanDine (cf57f22) * bump version to 0.1.1 (tag: 0.1.1, refs/bzr/origin/tags/0.1.1) 2010-02-09 14:04:22 -0600 Cody Russell (6ac36fe) * Merge initial-slider-value branch 2010-02-09 14:00:51 -0600 Cody Russell (484a47c) * Merge scale-icons branch 2010-02-09 11:59:30 -0600 Cody Russell (a843525) * Add support for initial value to ido_scale_menu_item_new_with_range() 2010-02-09 09:19:48 -0600 Cody Russell (e8c2d56) * Upper/lower clamping on icon click 2010-02-06 12:35:15 -0600 Cody Russell (bd5faca) * Add support for primary/secondary icons. 2010-02-05 14:19:30 -0800 Cody Russell (d03f386) * Fix build for ARM architecture 2010-02-05 12:35:53 -0800 Cody Russell (518846a) * Test ARM fix 2010-02-05 10:02:08 -0800 Cody Russell (e892ebe) * merge scale-spacing-fixes branch 2010-02-04 17:15:35 -0800 Cody Russell (50ae8ef) * Scale spacing fixes 2010-02-04 14:21:10 -0800 Cody Russell (1595f64) * Fix distcheck (tag: 0.1.0, refs/bzr/origin/tags/0.1.0) 2010-02-04 14:14:19 -0800 Cody Russell (c650b69) * Merge license change branch 2010-02-04 14:13:47 -0800 Cody Russell (5d5a08d) * Merge fix-header-install branch 2010-02-04 13:03:56 -0800 Cody Russell (d9fc8cf) * Merge spacing-fixes branch 2010-02-04 13:01:18 -0800 Cody Russell (faf10d1) * Fix headers to install 2010-02-04 12:58:36 -0800 Cody Russell (a5aad4e) * Remove stuff 2010-02-04 12:57:39 -0800 Cody Russell (8b8228c) * Copyright/license fu 2010-02-04 12:32:28 -0800 Cody Russell (9f3461c) * Spacing fixes 2010-02-02 12:51:12 -0800 Cody Russell (6b60795) * Fix header installs 2010-02-02 10:34:30 -0800 Cody Russell (140b985) * Merge entry menuitem 2010-02-01 18:22:16 -0600 Cody Russell (0dc1eba) * Entry menu items 2010-02-01 16:24:00 -0600 Cody Russell (c9b34c9) * Merge offscreen scale branch 2010-02-01 16:22:31 -0600 Cody Russell (0372535) * Unref the pixbuf 2010-01-25 10:02:16 -0600 Cody Russell (c4a23ad) * Merge get-scale branch 2010-01-25 09:49:39 -0600 Cody Russell (0696acf) * Autogen changes 2010-01-25 08:54:55 -0600 Cody Russell (902d58d) * Add ido_scale_menu_item_get_scale() function 2010-01-20 23:43:05 -0600 Cody Russell (51029c2) * Use GtkOffscreenWindow to manage rendering of the scale. 2010-01-19 16:02:50 -0600 Cody Russell (ebb7b05) * IDO initial commit, scale menuitem ayatana-ido-0.4.2/configure.ac0000644000000000000000000001057113211262407013062 0ustar # # shamelessly stolen from clutter-gtk # m4_define([ido_major_version], [0]) m4_define([ido_minor_version], [4]) m4_define([ido_micro_version], [2]) m4_define([ido_api_version], [ido_major_version.ido_minor_version]) m4_define([ido_version], [ido_major_version.ido_minor_version.ido_micro_version]) m4_define([ido_interface_age], [0]) m4_define([ido_binary_age], [m4_eval(100 * ido_minor_version + ido_micro_version)]) AC_PREREQ([2.64]) AC_INIT([ayatana-ido], [ido_version], [https://github.com/ArcticaProject/ayatana-ido/issues], [ayatana-ido], [https://github.com/ArcticaProject/ayatana-ido]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([src/libayatana-ido.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([check-news 1.11 foreign]) AM_SILENT_RULES([yes]) IDO_MAJOR_VERSION=ido_major_version IDO_MINOR_VERSION=ido_minor_version IDO_MICRO_VERSION=ido_micro_version IDO_VERSION=ido_version AC_SUBST(IDO_MAJOR_VERSION) AC_SUBST(IDO_MINOR_VERSION) AC_SUBST(IDO_MICRO_VERSION) AC_SUBST(IDO_VERSION) m4_define([lt_current], [m4_eval(100 * ido_minor_version + ido_micro_version - ido_interface_age)]) m4_define([lt_revision], [ido_interface_age]) m4_define([lt_age], [m4_eval(ido_binary_age - ido_interface_age)]) IDO_LT_CURRENT=lt_current IDO_LT_REV=lt_revision IDO_LT_AGE=lt_age IDO_LT_VERSION="$IDO_LT_CURRENT:$IDO_LT_REV:$IDO_LT_AGE" IDO_LT_LDFLAGS="-version-info $IDO_LT_VERSION" AC_SUBST(IDO_LT_VERSION) AC_SUBST(IDO_LT_LDFLAGS) dnl =========================================================================== # Checks for programs AC_PROG_CC AM_PROG_CC_C_O AC_PROG_CXX # Initialize libtool LT_PREREQ([2.2]) LT_INIT([disable-static]) AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums]) PKG_PROG_PKG_CONFIG # Checks for header files AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h]) # Checks for typedefs, structures and compiler charecteristics AC_C_CONST # Checks for library functions AC_FUNC_MALLOC AC_FUNC_MMAP AC_CHECK_FUNCS([memset munmap strcasecmp strdup]) AC_CHECK_LIBM GIO_REQUIRED_VERSION=2.37.0 GTK_REQUIRED_VERSION=3.8.2 PKG_CHECK_MODULES(GTK,[gtk+-3.0 >= $GTK_REQUIRED_VERSION gio-2.0 >= $GIO_REQUIRED_VERSION]) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) dnl =========================================================================== if test "x$GCC" = "xyes"; then GCC_FLAGS="-g -Wall" fi AC_SUBST(GCC_FLAGS) # use strict compiler flags only on development releases m4_define([maintainer_flags_default], [m4_if(m4_eval(ido_minor_version % 2), [1], [yes], [no])]) AC_ARG_ENABLE([maintainer-flags], [AS_HELP_STRING([--enable-maintainer-flags=@<:@no/yes@:>@], [Use strict compiler flags @<:@default=no@:>@])], [], [enable_maintainer_flags=maintainer_flags_default]) MAINTAINER_CFLAGS="" AS_IF([test "x$enable_maintainer_flags" = "xyes" && test "x$GCC" = "xyes"], [ MAINTAINER_CFLAGS="-Werror -Wall -Wshadow -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self" ] ) AC_SUBST(MAINTAINER_CFLAGS) dnl = gcov Coverage Reporting ================================================= m4_include([m4/gcov.m4]) AC_TDD_GCOV AM_CONDITIONAL([HAVE_GCOV], [test "x$ac_cv_check_gcov" = xyes]) AM_CONDITIONAL([HAVE_LCOV], [test "x$ac_cv_check_lcov" = xyes]) AM_CONDITIONAL([HAVE_GCOVR], [test "x$ac_cv_check_gcovr" = xyes]) AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_CXXFLAGS) AC_SUBST(COVERAGE_LDFLAGS) dnl = GObject Introspection =================================================== GOBJECT_INTROSPECTION_CHECK([0.6.7]) dnl = Vala API Generation ===================================================== AC_PATH_PROG([VALA_API_GEN], [vapigen]) dnl = Google Test Framework =================================================== dnl xorg-gtest also provides gtest. CHECK_XORG_GTEST dnl = GTK Doc Check =========================================================== GTK_DOC_CHECK([1.8]) dnl =========================================================================== AC_CONFIG_FILES([ Makefile src/Makefile example/Makefile tests/Makefile libayatana-ido3.pc ]) AC_OUTPUT echo "" echo " ido $VERSION" echo " ===============================" echo "" echo " Prefix : ${prefix}" echo " gcov : ${use_gcov}" echo " introspection: ${enable_introspection}" echo "" echo " Documentation: ${enable_gtk_doc}" echo "" ayatana-ido-0.4.2/COPYING0000644000000000000000000001672713211262407011640 0ustar GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ayatana-ido-0.4.2/COPYING.LGPL.2.10000644000000000000000000006363713211262407012676 0ustar GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ayatana-ido-0.4.2/example/Makefile.am0000644000000000000000000000134713211262407014264 0ustar VER=3 noinst_PROGRAMS = \ messagedialog \ menus messagedialog_SOURCES = \ messagedialog.c menus_SOURCES = \ menus.c messagedialog_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ $(GCC_FLAGS) \ $(GTK_CFLAGS) \ $(MAINTAINER_CFLAGS) menus_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ $(GCC_FLAGS) \ $(GTK_CFLAGS) \ $(MAINTAINER_CFLAGS) messagedialog_LDADD = $(top_builddir)/src/libayatana-ido$(VER)-0.4.la $(GTK_LIBS) menus_LDADD = $(top_builddir)/src/libayatana-ido$(VER)-0.4.la $(GTK_LIBS) DISTCLEANFILES = Makefile.inayatana-ido-0.4.2/example/menus.c0000644000000000000000000001203713211262407013521 0ustar #include #include "idoscalemenuitem.h" #include "idocalendarmenuitem.h" #include "idoentrymenuitem.h" #include "idolocationmenuitem.h" #include "idoswitchmenuitem.h" #include "idousermenuitem.h" #include "config.h" static void slider_grabbed (GtkWidget *widget, gpointer user_data) { g_print ("grabbed\n"); } static void slider_released (GtkWidget *widget, gpointer user_data) { g_print ("released\n"); } int main (int argc, char *argv[]) { guint i; GtkWidget *window; GtkWidget *vbox; GtkWidget *menu; GtkWidget *menuitem; GtkWidget *root; GtkWidget *menubar; GtkWidget *image; const struct { const char * username; const char * icon_filename; gboolean is_logged_in; gboolean is_active; } users[] = { { "Guest", NULL, FALSE, FALSE }, { "Bobby Fischer", "/usr/share/pixmaps/faces/chess.jpg", FALSE, FALSE }, { "Linus Torvalds", "/usr/share/pixmaps/faces/penguin.jpg", TRUE, FALSE }, { "Mark Shuttleworth", "/usr/share/pixmaps/faces/astronaut.jpg", TRUE, TRUE } }; const struct { const char * name; const char * timezone; const char * format; } locations[] = { { "Oklahoma City", "America/Chicago", "%I:%M %p" }, { "Magdeburg", "Europe/Berlin", "%T" }, { "Kuntzig", "Europe/Paris", "%a %H:%M" } }; g_unsetenv ("UBUNTU_MENUPROXY"); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Menus"); gtk_widget_set_size_request (window, 300, 200); g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (window), vbox); menubar = gtk_menu_bar_new (); gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); menu = gtk_menu_new (); root = gtk_menu_item_new_with_label ("File"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (root), menu); menuitem = gtk_menu_item_new_with_label ("New"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); menuitem = gtk_menu_item_new_with_label ("Open"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); /* Scale */ menuitem = ido_scale_menu_item_new_with_range ("Volume", IDO_RANGE_STYLE_DEFAULT, 65, 0, 100, 1); ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (menuitem), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); image = ido_scale_menu_item_get_primary_image (IDO_SCALE_MENU_ITEM (menuitem)); gtk_image_set_from_stock (GTK_IMAGE (image), GTK_STOCK_NEW, GTK_ICON_SIZE_MENU); image = ido_scale_menu_item_get_secondary_image (IDO_SCALE_MENU_ITEM (menuitem)); gtk_image_set_from_stock (GTK_IMAGE (image), GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (menuitem, "slider-grabbed", G_CALLBACK (slider_grabbed), NULL); g_signal_connect (menuitem, "slider-released", G_CALLBACK (slider_released), NULL); /* Entry */ menuitem = ido_entry_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); /* Switch */ menuitem = ido_switch_menu_item_new (); ido_switch_menu_item_set_label (IDO_SWITCH_MENU_ITEM (menuitem), "This is a switch."); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); /* Calendar */ gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); menuitem = ido_calendar_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); /* Users */ gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); for (i=0; i #include "idomessagedialog.h" #include "config.h" static void response_cb (GtkDialog *dialog, gint response, gpointer user_data) { gtk_widget_destroy (GTK_WIDGET (dialog)); } static void button_clicked_cb (GtkWidget *button, gpointer data) { GtkWidget *window = (GtkWidget *) data; GtkWidget *dialog = ido_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "This is a test of the emergency broadcasting system"); gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "If this had been an actual emergency, you'd be dead already"); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (response_cb), NULL); gtk_widget_show (dialog); } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *vbox; GtkWidget *button; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Message Dialogs"); g_signal_connect (window, "destroy", gtk_main_quit, NULL); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (window), vbox); button = gtk_button_new_with_label ("Confirmation dialog"); g_signal_connect (button, "clicked", G_CALLBACK (button_clicked_cb), window); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_widget_show_all (window); gtk_main (); return 0; } ayatana-ido-0.4.2/INSTALL0000644000000000000000000002243213211262407011624 0ustar Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Here is a another example: /bin/bash ./configure CONFIG_SHELL=/bin/bash Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent configuration-related scripts to be executed by `/bin/bash'. `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. ayatana-ido-0.4.2/libayatana-ido3.pc.in0000644000000000000000000000041613211262407014463 0ustar prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libayatana-ido Description: Ayatana Indicator Display Objects Version: @VERSION@ Libs: -L${libdir} -layatana-ido3-0.4 Cflags: -I${includedir}/libayatana-ido3-0.4 Requires: gtk+-3.0 ayatana-ido-0.4.2/m4/gcov.m40000644000000000000000000000471713211262407012321 0ustar # Checks for existence of coverage tools: # * gcov # * lcov # * genhtml # * gcovr # # Sets ac_cv_check_gcov to yes if tooling is present # and reports the executables to the variables LCOV, GCOVR and GENHTML. AC_DEFUN([AC_TDD_GCOV], [ AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov], [enable coverage testing with gcov]), [use_gcov=$enableval], [use_gcov=no]) if test "x$use_gcov" = "xyes"; then # we need gcc: if test "$GCC" != "yes"; then AC_MSG_ERROR([GCC is required for --enable-gcov]) fi # Check if ccache is being used AC_CHECK_PROG(SHTOOL, shtool, shtool) case `$SHTOOL path $CC` in *ccache*[)] gcc_ccache=yes;; *[)] gcc_ccache=no;; esac if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) fi lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" AC_CHECK_PROG(LCOV, lcov, lcov) AC_CHECK_PROG(GENHTML, genhtml, genhtml) if test "$LCOV"; then AC_CACHE_CHECK([for lcov version], glib_cv_lcov_version, [ glib_cv_lcov_version=invalid lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` for lcov_check_version in $lcov_version_list; do if test "$lcov_version" = "$lcov_check_version"; then glib_cv_lcov_version="$lcov_check_version (ok)" fi done ]) else lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" AC_MSG_ERROR([$lcov_msg]) fi case $glib_cv_lcov_version in ""|invalid[)] lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." AC_MSG_ERROR([$lcov_msg]) LCOV="exit 0;" ;; esac if test -z "$GENHTML"; then AC_MSG_ERROR([Could not find genhtml from the lcov package]) fi ac_cv_check_gcov=yes ac_cv_check_lcov=yes # Remove all optimization flags from CFLAGS changequote({,}) CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` changequote([,]) # Add the special gcc flags COVERAGE_CFLAGS="-O0 -fprofile-arcs -ftest-coverage" COVERAGE_CXXFLAGS="-O0 -fprofile-arcs -ftest-coverage" COVERAGE_LDFLAGS="-lgcov" # Check availability of gcovr AC_CHECK_PROG(GCOVR, gcovr, gcovr) if test -z "$GCOVR"; then ac_cv_check_gcovr=no else ac_cv_check_gcovr=yes fi fi ]) # AC_TDD_GCOV ayatana-ido-0.4.2/Makefile.am0000644000000000000000000000146613211262407012633 0ustar ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} NULL= V = @ Q = $(V:1=) QUIET_GEN = $(Q:@=@echo ' GEN '$@;) SUBDIRS = src example tests %-0.4.pc: %.pc $(QUIET_GEN) cp -f $< $@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libayatana-ido3-0.4.pc CLEANFILES = \ libayatana-ido3-0.4.pc \ $(NULL) DISTCLEANFILES = \ libayatana-ido.pc \ libayatana-ido3.pc \ Makefile.in \ aclocal.m4 \ autom4te.cache/ \ compile \ config.guess \ config.h.in \ config.h.in~ \ config.sub \ configure \ depcomp \ gtk-doc.make \ install-sh \ ltmain.sh \ m4/gtk-doc.m4 \ m4/libtool.m4 \ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ m4/lt~obsolete.m4 \ missing \ omf.make \ test-driver \ xmldocs.make \ $(NULL) EXTRA_DIST = libayatana-ido3.pc.in include $(top_srcdir)/Makefile.am.coverage ayatana-ido-0.4.2/Makefile.am.coverage0000644000000000000000000000250513211262407014420 0ustar # Coverage targets .PHONY: clean-gcno clean-gcda \ coverage-html generate-coverage-html clean-coverage-html \ coverage-gcovr generate-coverage-gcovr clean-coverage-gcovr clean-local: clean-gcno clean-coverage-html clean-coverage-gcovr if HAVE_GCOV clean-gcno: @echo Removing old coverage instrumentation -find -name '*.gcno' -print | xargs -r rm clean-gcda: @echo Removing old coverage results -find -name '*.gcda' -print | xargs -r rm coverage-html: clean-gcda -$(MAKE) $(AM_MAKEFLAGS) -k check $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html generate-coverage-html: @echo Collecting coverage data $(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info clean-coverage-html: clean-gcda -$(LCOV) --directory $(top_builddir) -z -rm -rf coverage.info coveragereport if HAVE_GCOVR coverage-gcovr: clean-gcda -$(MAKE) $(AM_MAKEFLAGS) -k check $(MAKE) $(AM_MAKEFLAGS) generate-coverage-gcovr generate-coverage-gcovr: @echo Generating coverage GCOVR report $(GCOVR) -x -r $(top_builddir) -o $(top_builddir)/coverage.xml clean-coverage-gcovr: clean-gcda -rm -rf $(top_builddir)/coverage.xml endif # HAVE_GCOVR endif # HAVE_GCOV ayatana-ido-0.4.2/NEWS.Canonical0000644000000000000000000000026513211262407013160 0ustar 12.10.2: * fix escape key behavior in calendar menuitem (LP: #953757) 12.10.1: * remove gtk2 support * remove slider hack (lp #953757) 12.10.0: * new widget IdoSwitchMenuItem ayatana-ido-0.4.2/README0000644000000000000000000000000013211262407011436 0ustar ayatana-ido-0.4.2/src/ayatanamenuitemfactory.c0000644000000000000000000000444513211262407016304 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include "ayatanamenuitemfactory.h" G_DEFINE_INTERFACE_WITH_CODE (AyatanaMenuItemFactory, ayatana_menu_item_factory, G_TYPE_OBJECT, GIOExtensionPoint *ep = g_io_extension_point_register (AYATANA_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME); g_io_extension_point_set_required_type (ep, g_define_type_id);) /* * ayatana_menu_item_factory_get_all: * * Returns a static list of all registered factories. */ GList * ayatana_menu_item_factory_get_all (void) { static GList *factories = NULL; if (factories == NULL) { GIOExtensionPoint *ep; GList *it; g_type_ensure (AYATANA_TYPE_MENU_ITEM_FACTORY); ep = g_io_extension_point_lookup (AYATANA_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME); for (it = g_io_extension_point_get_extensions (ep); it != NULL; it = it->next) { GIOExtension *ext = it->data; AyatanaMenuItemFactory *factory; factory = g_object_new (g_io_extension_get_type (ext), NULL); factories = g_list_prepend (factories, factory); } factories = g_list_reverse (factories); } return factories; } static void ayatana_menu_item_factory_default_init (AyatanaMenuItemFactoryInterface *iface) { } GtkMenuItem * ayatana_menu_item_factory_create_menu_item (AyatanaMenuItemFactory *factory, const gchar *type, GMenuItem *menuitem, GActionGroup *actions) { return AYATANA_MENU_ITEM_FACTORY_GET_IFACE (factory)->create_menu_item (factory, type, menuitem, actions); } ayatana-ido-0.4.2/src/ayatanamenuitemfactory.h0000644000000000000000000000501713211262407016305 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #ifndef __AYATANA_MENU_ITEM_FACTORY_H__ #define __AYATANA_MENU_ITEM_FACTORY_H__ #include G_BEGIN_DECLS #define AYATANA_TYPE_MENU_ITEM_FACTORY (ayatana_menu_item_factory_get_type ()) #define AYATANA_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), AYATANA_TYPE_MENU_ITEM_FACTORY, AyatanaMenuItemFactory)) #define AYATANA_IS_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), AYATANA_TYPE_MENU_ITEM_FACTORY)) #define AYATANA_MENU_ITEM_FACTORY_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), AYATANA_TYPE_MENU_ITEM_FACTORY, AyatanaMenuItemFactoryInterface)) #define AYATANA_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME "ayatana-menu-item-factory" typedef struct _AyatanaMenuItemFactoryInterface AyatanaMenuItemFactoryInterface; typedef struct _AyatanaMenuItemFactory AyatanaMenuItemFactory; struct _AyatanaMenuItemFactoryInterface { GTypeInterface iface; GtkMenuItem * (*create_menu_item) (AyatanaMenuItemFactory *factory, const gchar *type, GMenuItem *menuitem, GActionGroup *actions); }; GDK_AVAILABLE_IN_3_10 GList * ayatana_menu_item_factory_get_all (void); GDK_AVAILABLE_IN_3_10 GType ayatana_menu_item_factory_get_type (void); GDK_AVAILABLE_IN_3_10 GtkMenuItem * ayatana_menu_item_factory_create_menu_item (AyatanaMenuItemFactory *factory, const gchar *type, GMenuItem *menuitem, GActionGroup *actions); G_END_DECLS #endif ayatana-ido-0.4.2/src/ayatana-private.h0000644000000000000000000000174613211262407014626 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ /* * Warning: this file is not part of gtk+, but an Ubuntu-specific extension. * The API provided here is meant to be used only from Unity. * * Applications should not use this. */ #ifndef __AYATANA_PRIVATE_H__ #define __AYATANA_PRIVATE_H__ #include "ayatanamenuitemfactory.h" #endif ayatana-ido-0.4.2/src/idoactionhelper.c0000644000000000000000000003374213211262407014705 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include "idoactionhelper.h" typedef GObjectClass IdoActionHelperClass; struct _IdoActionHelper { GObject parent; GtkWidget *widget; GActionGroup *actions; gchar *action_name; GVariant *action_target; guint idle_source_id; }; G_DEFINE_TYPE (IdoActionHelper, ido_action_helper, G_TYPE_OBJECT) enum { PROP_0, PROP_WIDGET, PROP_ACTION_GROUP, PROP_ACTION_NAME, PROP_ACTION_TARGET, NUM_PROPERTIES }; enum { ACTION_STATE_CHANGED, NUM_SIGNALS }; static GParamSpec *properties[NUM_PROPERTIES]; static guint signals[NUM_SIGNALS]; static void ido_action_helper_action_added (GActionGroup *actions, const gchar *action_name, gpointer user_data) { IdoActionHelper *helper = user_data; gboolean enabled; GVariant *state; if (!g_str_equal (action_name, helper->action_name)) return; if (g_action_group_query_action (actions, action_name, &enabled, NULL, NULL, NULL, &state)) { gtk_widget_set_sensitive (helper->widget, enabled); if (state) { g_signal_emit (helper, signals[ACTION_STATE_CHANGED], 0, state); g_variant_unref (state); } } else { gtk_widget_set_sensitive (helper->widget, FALSE); } } static void ido_action_helper_action_removed (GActionGroup *action_group, gchar *action_name, gpointer user_data) { IdoActionHelper *helper = user_data; if (g_str_equal (action_name, helper->action_name)) gtk_widget_set_sensitive (helper->widget, FALSE); } static void ido_action_helper_action_enabled_changed (GActionGroup *action_group, gchar *action_name, gboolean enabled, gpointer user_data) { IdoActionHelper *helper = user_data; if (g_str_equal (action_name, helper->action_name)) gtk_widget_set_sensitive (helper->widget, enabled); } static void ido_action_helper_action_state_changed (GActionGroup *action_group, gchar *action_name, GVariant *value, gpointer user_data) { IdoActionHelper *helper = user_data; if (g_str_equal (action_name, helper->action_name)) g_signal_emit (helper, signals[ACTION_STATE_CHANGED], 0, value); } static gboolean call_action_added (gpointer user_data) { IdoActionHelper *helper = user_data; ido_action_helper_action_added (helper->actions, helper->action_name, helper); helper->idle_source_id = 0; return G_SOURCE_REMOVE; } static void ido_action_helper_constructed (GObject *object) { IdoActionHelper *helper = IDO_ACTION_HELPER (object); g_signal_connect (helper->actions, "action-added", G_CALLBACK (ido_action_helper_action_added), helper); g_signal_connect (helper->actions, "action-removed", G_CALLBACK (ido_action_helper_action_removed), helper); g_signal_connect (helper->actions, "action-enabled-changed", G_CALLBACK (ido_action_helper_action_enabled_changed), helper); g_signal_connect (helper->actions, "action-state-changed", G_CALLBACK (ido_action_helper_action_state_changed), helper); if (g_action_group_has_action (helper->actions, helper->action_name)) { /* call action_added in an idle, so that we don't fire the * state-changed signal during construction (nobody could have * connected by then). */ helper->idle_source_id = g_idle_add (call_action_added, helper); } G_OBJECT_CLASS (ido_action_helper_parent_class)->constructed (object); } static void ido_action_helper_get_property (GObject *object, guint id, GValue *value, GParamSpec *pspec) { IdoActionHelper *helper = IDO_ACTION_HELPER (object); switch (id) { case PROP_WIDGET: g_value_set_object (value, helper->widget); break; case PROP_ACTION_GROUP: g_value_set_object (value, helper->actions); break; case PROP_ACTION_NAME: g_value_set_string (value, helper->action_name); break; case PROP_ACTION_TARGET: g_value_set_variant (value, helper->action_target); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, id, pspec); } } static void ido_action_helper_set_property (GObject *object, guint id, const GValue *value, GParamSpec *pspec) { IdoActionHelper *helper = IDO_ACTION_HELPER (object); switch (id) { case PROP_WIDGET: /* construct-only */ helper->widget = g_value_dup_object (value); break; case PROP_ACTION_GROUP: /* construct-only */ helper->actions = g_value_dup_object (value); break; case PROP_ACTION_NAME: /* construct-only */ helper->action_name = g_value_dup_string (value); break; case PROP_ACTION_TARGET: /* construct-only */ helper->action_target = g_value_dup_variant (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, id, pspec); } } static void ido_action_helper_finalize (GObject *object) { IdoActionHelper *helper = IDO_ACTION_HELPER (object); if (helper->idle_source_id) g_source_remove (helper->idle_source_id); g_object_unref (helper->widget); g_signal_handlers_disconnect_by_data (helper->actions, helper); g_object_unref (helper->actions); g_free (helper->action_name); if (helper->action_target) g_variant_unref (helper->action_target); G_OBJECT_CLASS (ido_action_helper_parent_class)->finalize (object); } static void ido_action_helper_class_init (IdoActionHelperClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->constructed = ido_action_helper_constructed; object_class->get_property = ido_action_helper_get_property; object_class->set_property = ido_action_helper_set_property; object_class->finalize = ido_action_helper_finalize; /** * IdoActionHelper::action-state-changed: * @helper: the #IdoActionHelper watching the action * @state: the new state of the action * * Emitted when the widget must be updated from the action's state, * which happens every time the action appears in the group and when * the action changes its state. */ signals[ACTION_STATE_CHANGED] = g_signal_new ("action-state-changed", IDO_TYPE_ACTION_HELPER, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VARIANT, G_TYPE_NONE, 1, G_TYPE_VARIANT); /** * IdoActionHelper:widget: * * The widget that is associated with this action helper. The action * helper updates the widget's "sensitive" property to reflect whether * the action #IdoActionHelper:action-name exists in * #IdoActionHelper:action-group. */ properties[PROP_WIDGET] = g_param_spec_object ("widget", "", "", GTK_TYPE_WIDGET, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * IdoActionHelper:action-group: * * The action group that eventually contains the action that * #IdoActionHelper:widget should be bound to. */ properties[PROP_ACTION_GROUP] = g_param_spec_object ("action-group", "", "", G_TYPE_ACTION_GROUP, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * IdoActionHelper:action-name: * * The name of the action in #IdoActionHelper:action-group that * should be bound to #IdoActionHelper:widget */ properties[PROP_ACTION_NAME] = g_param_spec_string ("action-name", "", "", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * IdoActionHelper:action-target: * * The target of #IdoActionHelper:widget. ido_action_helper_activate() * passes the target as parameter when activating the action. * * The handler of #IdoActionHelper:action-state-changed is responsible * for comparing this target with the action's state and updating the * #IdoActionHelper:widget appropriately. */ properties[PROP_ACTION_TARGET] = g_param_spec_variant ("action-target", "", "", G_VARIANT_TYPE_ANY, NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } static void ido_action_helper_init (IdoActionHelper *helper) { } /** * ido_action_helper_new: * @widget: a #GtkWidget * @action_group: a #GActionGroup * @action_name: the name of an action in @action_group * @target: the target of the action * * Creates a new #IdoActionHelper. This helper ties @widget to an action * (and a target), and performs some common tasks: * * @widget will be set to insensitive whenever @action_group does not * contain an action with the name @action_name, or the action with that * name is disabled. * * Also, the helper emits the "action-state-changed" signal whenever the * widget must be updated from the action's state. This includes once * when the action was added, and every time the action changes its * state. * * Returns: (transfer full): a new #IdoActionHelper */ IdoActionHelper * ido_action_helper_new (GtkWidget *widget, GActionGroup *action_group, const gchar *action_name, GVariant *target) { g_return_val_if_fail (widget != NULL, NULL); g_return_val_if_fail (action_group != NULL, NULL); g_return_val_if_fail (action_name != NULL, NULL); return g_object_new (IDO_TYPE_ACTION_HELPER, "widget", widget, "action-group", action_group, "action-name", action_name, "action-target", target, NULL); } /** * ido_action_helper_get_widget: * @helper: an #IdoActionHelper * * Returns: (transfer none): the #GtkWidget associated with @helper */ GtkWidget * ido_action_helper_get_widget (IdoActionHelper *helper) { g_return_val_if_fail (IDO_IS_ACTION_HELPER (helper), NULL); return helper->widget; } /** * ido_action_helper_get_action_target: * @helper: an #IdoActionHelper * * Returns: (transfer none): the action target that was set in * ido_action_helper_new() as a #GVariant */ GVariant * ido_action_helper_get_action_target (IdoActionHelper *helper) { g_return_val_if_fail (IDO_IS_ACTION_HELPER (helper), NULL); return helper->action_target; } /** * ido_action_helper_activate: * @helper: an #IdoActionHelper * * Activates the action that is associated with this helper. */ void ido_action_helper_activate (IdoActionHelper *helper) { g_return_if_fail (IDO_IS_ACTION_HELPER (helper)); if (helper->actions && helper->action_name) g_action_group_activate_action (helper->actions, helper->action_name, helper->action_target); } /** * ido_action_helper_activate_with_parameter: * @helper: an #IdoActionHelper * @parameter: a #GVariant containing the parameter * * Activates the action that is associated with this helper passing * @parameter instead the "target" associated with the menu item this * helper is bound to. */ void ido_action_helper_activate_with_parameter (IdoActionHelper *helper, GVariant *parameter) { g_return_if_fail (IDO_IS_ACTION_HELPER (helper)); g_return_if_fail (parameter != NULL); g_variant_ref_sink (parameter); if (helper->actions && helper->action_name) g_action_group_activate_action (helper->actions, helper->action_name, parameter); g_variant_unref (parameter); } /** * ido_action_helper_change_action_state: * @helper: an #IdoActionHelper * @state: the proposed new state of the action * * Requests changing the state of the action that is associated with * @helper to @state. * * If @state is floating, it is consumed. */ void ido_action_helper_change_action_state (IdoActionHelper *helper, GVariant *state) { g_return_if_fail (IDO_IS_ACTION_HELPER (helper)); g_return_if_fail (state != NULL); g_variant_ref_sink (state); if (helper->actions && helper->action_name) g_action_group_change_action_state (helper->actions, helper->action_name, state); g_variant_unref (state); } ayatana-ido-0.4.2/src/idoactionhelper.h0000644000000000000000000000407613211262407014710 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #ifndef __IDO_ACTION_HELPER_H__ #define __IDO_ACTION_HELPER_H__ #include #define IDO_TYPE_ACTION_HELPER (ido_action_helper_get_type ()) #define IDO_ACTION_HELPER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_ACTION_HELPER, IdoActionHelper)) #define IDO_IS_ACTION_HELPER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_ACTION_HELPER)) typedef struct _IdoActionHelper IdoActionHelper; GType ido_menu_item_get_type (void); IdoActionHelper * ido_action_helper_new (GtkWidget *widget, GActionGroup *action_group, const gchar *action_name, GVariant *target); GtkWidget * ido_action_helper_get_widget (IdoActionHelper *helper); GVariant * ido_action_helper_get_action_target (IdoActionHelper *helper); void ido_action_helper_activate (IdoActionHelper *helper); void ido_action_helper_activate_with_parameter (IdoActionHelper *helper, GVariant *parameter); void ido_action_helper_change_action_state (IdoActionHelper *helper, GVariant *state); #endif ayatana-ido-0.4.2/src/idoalarmmenuitem.c0000644000000000000000000000711113211262407015057 0ustar /* * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * Ted Gould * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "idoactionhelper.h" #include "idotimestampmenuitem.h" /** * ido_alarm_menu_item_new_from_model: * @menu_item: the corresponding menuitem * @actions: action group to tell when this GtkMenuItem is activated * * Creates a new IdoTimeStampMenuItem with properties initialized * appropriately for a org.ayatana.indicator.alarm * * If the menuitem's 'action' attribute is set, trigger that action * in @actions when this IdoAppointmentMenuItem is activated. */ GtkMenuItem * ido_alarm_menu_item_new_from_model (GMenuItem * menu_item, GActionGroup * actions) { guint i; guint n; gint64 i64; gchar * str; IdoBasicMenuItem * ido_menu_item; GParameter parameters[8]; /* create the ido_menu_item */ n = 0; if (g_menu_item_get_attribute (menu_item, G_MENU_ATTRIBUTE_LABEL, "s", &str)) { GParameter p = { "text", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if (TRUE) { GParameter p = { "icon", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_OBJECT); g_value_take_object (&p.value, g_themed_icon_new_with_default_fallbacks ("alarm-symbolic")); parameters[n++] = p; } if (g_menu_item_get_attribute (menu_item, "x-canonical-time-format", "s", &str)) { GParameter p = { "format", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if (g_menu_item_get_attribute (menu_item, "x-canonical-time", "x", &i64)) { GParameter p = { "date-time", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_DATE_TIME); g_value_take_boxed (&p.value, g_date_time_new_from_unix_local (i64)); parameters[n++] = p; } g_assert (n <= G_N_ELEMENTS (parameters)); ido_menu_item = g_object_newv (IDO_TYPE_TIME_STAMP_MENU_ITEM, n, parameters); for (i=0; i * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __IDO_ALARM_MENU_ITEM_H__ #define __IDO_ALARM_MENU_ITEM_H__ #include G_BEGIN_DECLS GtkMenuItem * ido_alarm_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions); G_END_DECLS #endif ayatana-ido-0.4.2/src/idoapplicationmenuitem.c0000644000000000000000000001340213211262407016266 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include "idoapplicationmenuitem.h" #include "idoactionhelper.h" typedef GtkMenuItemClass IdoApplicationMenuItemClass; struct _IdoApplicationMenuItem { GtkMenuItem parent; gboolean is_running; GtkWidget *icon; GtkWidget *label; }; G_DEFINE_TYPE (IdoApplicationMenuItem, ido_application_menu_item, GTK_TYPE_MENU_ITEM); static void ido_application_menu_item_constructed (GObject *object) { IdoApplicationMenuItem *item = IDO_APPLICATION_MENU_ITEM (object); GtkWidget *grid; gint icon_height; gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_height); item->icon = g_object_ref (gtk_image_new ()); gtk_image_set_pixel_size (GTK_IMAGE (item->icon), icon_height); gtk_widget_set_margin_right (item->icon, 6); item->label = g_object_ref (gtk_label_new ("")); grid = gtk_grid_new (); gtk_grid_attach (GTK_GRID (grid), item->icon, 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), item->label, 1, 0, 1, 1); gtk_container_add (GTK_CONTAINER (object), grid); gtk_widget_show_all (grid); G_OBJECT_CLASS (ido_application_menu_item_parent_class)->constructed (object); } static void ido_application_menu_item_dispose (GObject *object) { IdoApplicationMenuItem *self = IDO_APPLICATION_MENU_ITEM (object); g_clear_object (&self->icon); g_clear_object (&self->label); G_OBJECT_CLASS (ido_application_menu_item_parent_class)->dispose (object); } static gboolean ido_application_menu_item_draw (GtkWidget *widget, cairo_t *cr) { IdoApplicationMenuItem *item = IDO_APPLICATION_MENU_ITEM (widget); GTK_WIDGET_CLASS (ido_application_menu_item_parent_class)->draw (widget, cr); if (item->is_running) { const int arrow_width = 5; const double half_arrow_height = 4.5; GtkAllocation alloc; GdkRGBA color; double center; gtk_widget_get_allocation (widget, &alloc); gtk_style_context_get_color (gtk_widget_get_style_context (widget), gtk_widget_get_state_flags (widget), &color); gdk_cairo_set_source_rgba (cr, &color); center = alloc.height / 2 + 0.5; cairo_move_to (cr, 0, center - half_arrow_height); cairo_line_to (cr, 0, center + half_arrow_height); cairo_line_to (cr, arrow_width, center); cairo_close_path (cr); cairo_fill (cr); } return FALSE; } void ido_application_menu_item_class_init (IdoApplicationMenuItemClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->constructed = ido_application_menu_item_constructed; object_class->dispose = ido_application_menu_item_dispose; widget_class->draw = ido_application_menu_item_draw; } static void ido_application_menu_item_init (IdoApplicationMenuItem *self) { } static void ido_application_menu_item_set_label (IdoApplicationMenuItem *item, const gchar *label) { gtk_label_set_label (GTK_LABEL (item->label), label); } static void ido_application_menu_item_set_icon (IdoApplicationMenuItem *item, GIcon *icon) { gtk_image_set_from_gicon (GTK_IMAGE (item->icon), icon, GTK_ICON_SIZE_MENU); } static void ido_application_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { IdoApplicationMenuItem *item = user_data; item->is_running = g_variant_get_boolean (state); gtk_widget_queue_draw (GTK_WIDGET (item)); } GtkMenuItem * ido_application_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions) { GtkMenuItem *item; gchar *label; GVariant *serialized_icon; gchar *action; item = g_object_new (IDO_TYPE_APPLICATION_MENU_ITEM, NULL); if (g_menu_item_get_attribute (menuitem, "label", "s", &label)) { ido_application_menu_item_set_label (IDO_APPLICATION_MENU_ITEM (item), label); g_free (label); } serialized_icon = g_menu_item_get_attribute_value (menuitem, "icon", NULL); if (serialized_icon) { GIcon *icon; icon = g_icon_deserialize (serialized_icon); if (icon) { ido_application_menu_item_set_icon (IDO_APPLICATION_MENU_ITEM (item), icon); g_object_unref (icon); } g_variant_unref (serialized_icon); } if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) { IdoActionHelper *helper; helper = ido_action_helper_new (GTK_WIDGET (item), actions, action, NULL); g_signal_connect (helper, "action-state-changed", G_CALLBACK (ido_application_menu_item_state_changed), item); g_signal_connect_object (item, "activate", G_CALLBACK (ido_action_helper_activate), helper, G_CONNECT_SWAPPED); g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper); g_free (action); } return item; } ayatana-ido-0.4.2/src/idoapplicationmenuitem.h0000644000000000000000000000277113211262407016302 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #ifndef __IDO_APPLICATION_MENU_ITEM_H__ #define __IDO_APPLICATION_MENU_ITEM_H__ #include #define IDO_TYPE_APPLICATION_MENU_ITEM (ido_application_menu_item_get_type ()) #define IDO_APPLICATION_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_APPLICATION_MENU_ITEM, IdoApplicationMenuItem)) #define IS_IDO_APPLICATION_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_APPLICATION_MENU_ITEM)) typedef struct _IdoApplicationMenuItem IdoApplicationMenuItem; GType ido_application_menu_item_get_type (void); GtkMenuItem * ido_application_menu_item_new_from_model (GMenuItem *item, GActionGroup *actions); #endif ayatana-ido-0.4.2/src/idoappointmentmenuitem.c0000644000000000000000000001130213211262407016316 0ustar /* * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * Ted Gould * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "idoactionhelper.h" #include "idotimestampmenuitem.h" /* create a menu-sized pixbuf filled with specified color */ static GdkPixbuf * create_color_icon_pixbuf (const char * color_spec) { static int width = -1; static int height = -1; GdkPixbuf * pixbuf = NULL; if (width == -1) { gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); width = CLAMP (width, 10, 30); height = CLAMP (height, 10, 30); } if (color_spec && *color_spec) { cairo_surface_t * surface; cairo_t * cr; GdkRGBA rgba; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); if (gdk_rgba_parse (&rgba, color_spec)) gdk_cairo_set_source_rgba (cr, &rgba); cairo_paint (cr); cairo_set_source_rgba (cr, 0, 0, 0, 0.5); cairo_set_line_width (cr, 1); cairo_rectangle (cr, 0.5, 0.5, width-1, height-1); cairo_stroke (cr); pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height); cairo_destroy (cr); cairo_surface_destroy (surface); } return pixbuf; } /** * ido_appointment_menu_item_new_from_model: * @menu_item: the corresponding menuitem * @actions: action group to tell when this GtkMenuItem is activated * * Creates a new IdoTimeStampMenuItem with properties initialized * appropriately for a org.ayatana.indicator.alarm * * If the menuitem's 'action' attribute is set, trigger that action * in @actions when this IdoAppointmentMenuItem is activated. */ GtkMenuItem * ido_appointment_menu_item_new_from_model (GMenuItem * menu_item, GActionGroup * actions) { guint i; guint n; gint64 i64; gchar * str; IdoBasicMenuItem * ido_menu_item; GParameter parameters[8]; /* create the ido_menu_item */ n = 0; if (g_menu_item_get_attribute (menu_item, G_MENU_ATTRIBUTE_LABEL, "s", &str)) { GParameter p = { "text", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if (g_menu_item_get_attribute (menu_item, "x-canonical-color", "s", &str)) { GParameter p = { "icon", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_OBJECT); g_value_take_object (&p.value, create_color_icon_pixbuf (str)); parameters[n++] = p; g_free (str); } if (g_menu_item_get_attribute (menu_item, "x-canonical-time-format", "s", &str)) { GParameter p = { "format", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if (g_menu_item_get_attribute (menu_item, "x-canonical-time", "x", &i64)) { GParameter p = { "date-time", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_DATE_TIME); g_value_take_boxed (&p.value, g_date_time_new_from_unix_local (i64)); parameters[n++] = p; } g_assert (n <= G_N_ELEMENTS (parameters)); ido_menu_item = g_object_newv (IDO_TYPE_TIME_STAMP_MENU_ITEM, n, parameters); for (i=0; i * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __IDO_APPOINTMENT_MENU_ITEM_H__ #define __IDO_APPOINTMENT_MENU_ITEM_H__ #include G_BEGIN_DECLS GtkMenuItem * ido_appointment_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions); G_END_DECLS #endif ayatana-ido-0.4.2/src/idobasicmenuitem.c0000644000000000000000000002500513211262407015046 0ustar /* * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "idoactionhelper.h" #include "idobasicmenuitem.h" enum { PROP_0, PROP_ICON, PROP_TEXT, PROP_SECONDARY_TEXT, PROP_LAST }; static GParamSpec *properties[PROP_LAST]; struct _IdoBasicMenuItemPrivate { GIcon * icon; char * text; char * secondary_text; GtkWidget * image; GtkWidget * label; GtkWidget * secondary_label; }; typedef IdoBasicMenuItemPrivate priv_t; G_DEFINE_TYPE (IdoBasicMenuItem, ido_basic_menu_item, GTK_TYPE_MENU_ITEM); /*** **** GObject Virtual Functions ***/ static void my_get_property (GObject * o, guint property_id, GValue * value, GParamSpec * pspec) { IdoBasicMenuItem * self = IDO_BASIC_MENU_ITEM (o); priv_t * p = self->priv; switch (property_id) { case PROP_ICON: g_value_set_object (value, p->icon); break; case PROP_TEXT: g_value_set_string (value, p->text); break; case PROP_SECONDARY_TEXT: g_value_set_string (value, p->secondary_text); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_set_property (GObject * o, guint property_id, const GValue * value, GParamSpec * pspec) { IdoBasicMenuItem * self = IDO_BASIC_MENU_ITEM (o); switch (property_id) { case PROP_ICON: ido_basic_menu_item_set_icon (self, g_value_get_object (value)); break; case PROP_TEXT: ido_basic_menu_item_set_text (self, g_value_get_string (value)); break; case PROP_SECONDARY_TEXT: ido_basic_menu_item_set_secondary_text (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_dispose (GObject * object) { IdoBasicMenuItem * self = IDO_BASIC_MENU_ITEM (object); priv_t * p = self->priv; g_clear_object (&p->icon); G_OBJECT_CLASS (ido_basic_menu_item_parent_class)->dispose (object); } static void my_finalize (GObject * object) { IdoBasicMenuItem * self = IDO_BASIC_MENU_ITEM (object); priv_t * p = self->priv; g_free (p->text); g_free (p->secondary_text); G_OBJECT_CLASS (ido_basic_menu_item_parent_class)->finalize (object); } static void ido_basic_menu_item_update_image (IdoBasicMenuItem *self) { IdoBasicMenuItemPrivate * p = self->priv; gtk_image_clear (GTK_IMAGE (p->image)); if (p->icon == NULL) { gtk_widget_set_visible (p->image, FALSE); } else { GtkIconInfo *info; const gchar *filename; info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), p->icon, 16, 0); filename = gtk_icon_info_get_filename (info); if (filename) { GdkPixbuf *pixbuf; pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, -1, 16, TRUE, NULL); gtk_image_set_from_pixbuf (GTK_IMAGE (p->image), pixbuf); g_object_unref (pixbuf); } gtk_widget_set_visible (p->image, filename != NULL); g_object_unref (info); } } static void ido_basic_menu_item_style_updated (GtkWidget *widget) { GTK_WIDGET_CLASS (ido_basic_menu_item_parent_class)->style_updated (widget); ido_basic_menu_item_update_image (IDO_BASIC_MENU_ITEM (widget)); gtk_widget_queue_draw (widget); } /*** **** Instantiation ***/ static void ido_basic_menu_item_class_init (IdoBasicMenuItemClass *klass) { GParamFlags prop_flags; GObjectClass * gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); g_type_class_add_private (klass, sizeof (IdoBasicMenuItemPrivate)); gobject_class->get_property = my_get_property; gobject_class->set_property = my_set_property; gobject_class->dispose = my_dispose; gobject_class->finalize = my_finalize; widget_class->style_updated = ido_basic_menu_item_style_updated; prop_flags = G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS; properties[PROP_ICON] = g_param_spec_object ("icon", "Icon", "The menuitem's GIcon", G_TYPE_OBJECT, prop_flags); properties[PROP_TEXT] = g_param_spec_string ("text", "Text", "The menuitem's text", "", prop_flags); properties[PROP_SECONDARY_TEXT] = g_param_spec_string ("secondary-text", "Secondary Text", "The menuitem's secondary text", "", prop_flags); g_object_class_install_properties (gobject_class, PROP_LAST, properties); } static void ido_basic_menu_item_init (IdoBasicMenuItem *self) { priv_t * p; GtkWidget * w; GtkGrid * grid; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, IDO_TYPE_BASIC_MENU_ITEM, IdoBasicMenuItemPrivate); p = self->priv; p->image = gtk_image_new (); gtk_misc_set_alignment(GTK_MISC(p->image), 0.0, 0.0); p->label = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC(p->label), 0.0, 0.5); p->secondary_label = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC(p->secondary_label), 1.0, 0.5); w = gtk_grid_new (); grid = GTK_GRID (w); gtk_grid_attach (grid, p->image, 0, 0, 1, 1); gtk_grid_attach (grid, p->label, 1, 0, 1, 1); gtk_grid_attach (grid, p->secondary_label, 2, 0, 1, 1); g_object_set (p->image, "halign", GTK_ALIGN_START, "hexpand", FALSE, "valign", GTK_ALIGN_CENTER, "margin-right", 6, NULL); g_object_set (p->label, "halign", GTK_ALIGN_START, "hexpand", TRUE, "margin-right", 6, "valign", GTK_ALIGN_CENTER, NULL); g_object_set (p->secondary_label, "halign", GTK_ALIGN_END, "hexpand", FALSE, "valign", GTK_ALIGN_CENTER, NULL); gtk_widget_show (w); gtk_container_add (GTK_CONTAINER (self), w); } /*** **** Public API ***/ /* create a new IdoBasicMenuItem */ GtkWidget * ido_basic_menu_item_new (void) { return GTK_WIDGET (g_object_new (IDO_TYPE_BASIC_MENU_ITEM, NULL)); } void ido_basic_menu_item_set_icon (IdoBasicMenuItem * self, GIcon * icon) { IdoBasicMenuItemPrivate * p = self->priv; if (p->icon != icon) { if (p->icon) g_object_unref (p->icon); p->icon = icon ? g_object_ref (icon) : NULL; ido_basic_menu_item_update_image (self); } } void ido_basic_menu_item_set_icon_from_file (IdoBasicMenuItem * self, const char * filename) { GFile * file = filename ? g_file_new_for_path (filename) : NULL; GIcon * icon = file ? g_file_icon_new (file) : NULL; ido_basic_menu_item_set_icon (self, icon); g_clear_object (&icon); g_clear_object (&file); } void ido_basic_menu_item_set_text (IdoBasicMenuItem * self, const char * text) { IdoBasicMenuItemPrivate * p = self->priv; if (g_strcmp0 (p->text, text)) { g_free (p->text); p->text = g_strdup (text); g_object_set (G_OBJECT(p->label), "label", p->text, "visible", (gboolean)(p->text && *p->text), NULL); } } void ido_basic_menu_item_set_secondary_text (IdoBasicMenuItem * self, const char * secondary_text) { IdoBasicMenuItemPrivate * p = self->priv; if (g_strcmp0 (p->secondary_text, secondary_text)) { g_free (p->secondary_text); p->secondary_text = g_strdup (secondary_text); g_object_set (G_OBJECT(p->secondary_label), "label", p->secondary_text, "visible", (gboolean)(p->secondary_text && *p->secondary_text), NULL); } } static void ido_basic_menu_item_activate (GtkMenuItem *item, gpointer user_data) { IdoActionHelper *helper = user_data; ido_action_helper_activate (helper); } GtkMenuItem * ido_basic_menu_item_new_from_model (GMenuItem * menu_item, GActionGroup * actions) { GtkWidget *item; gchar *label; gchar *action; GVariant *serialized_icon; item = ido_basic_menu_item_new (); if (g_menu_item_get_attribute (menu_item, "label", "s", &label)) { ido_basic_menu_item_set_text (IDO_BASIC_MENU_ITEM (item), label); g_free (label); } serialized_icon = g_menu_item_get_attribute_value (menu_item, "icon", NULL); if (serialized_icon) { GIcon *icon; icon = g_icon_deserialize (serialized_icon); ido_basic_menu_item_set_icon (IDO_BASIC_MENU_ITEM (item), icon); g_object_unref (icon); g_variant_unref (serialized_icon); } if (g_menu_item_get_attribute (menu_item, "action", "s", &action)) { IdoActionHelper *helper; GVariant *target; target = g_menu_item_get_attribute_value (menu_item, "target", NULL); helper = ido_action_helper_new (item, actions, action, target); g_signal_connect_object (item, "activate", G_CALLBACK (ido_basic_menu_item_activate), helper, 0); g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper); if (target) g_variant_unref (target); g_free (action); } return GTK_MENU_ITEM (item); } ayatana-ido-0.4.2/src/idobasicmenuitem.h0000644000000000000000000000464013211262407015055 0ustar /** * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __IDO_BASIC_MENU_ITEM_H__ #define __IDO_BASIC_MENU_ITEM_H__ #include G_BEGIN_DECLS #define IDO_TYPE_BASIC_MENU_ITEM (ido_basic_menu_item_get_type ()) #define IDO_BASIC_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_BASIC_MENU_ITEM, IdoBasicMenuItem)) #define IDO_IS_BASIC_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_BASIC_MENU_ITEM)) typedef struct _IdoBasicMenuItem IdoBasicMenuItem; typedef struct _IdoBasicMenuItemClass IdoBasicMenuItemClass; typedef struct _IdoBasicMenuItemPrivate IdoBasicMenuItemPrivate; struct _IdoBasicMenuItemClass { GtkMenuItemClass parent_class; }; /** * A simple menuitem that includes a right-justified secondary text. */ struct _IdoBasicMenuItem { /*< private >*/ GtkMenuItem parent; IdoBasicMenuItemPrivate * priv; }; GType ido_basic_menu_item_get_type (void) G_GNUC_CONST; GtkWidget * ido_basic_menu_item_new (void); void ido_basic_menu_item_set_icon (IdoBasicMenuItem * self, GIcon * icon); void ido_basic_menu_item_set_icon_from_file (IdoBasicMenuItem * self, const char * filename); void ido_basic_menu_item_set_text (IdoBasicMenuItem * self, const char * text); void ido_basic_menu_item_set_secondary_text (IdoBasicMenuItem * self, const char * text); GtkMenuItem * ido_basic_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions); G_END_DECLS #endif ayatana-ido-0.4.2/src/idocalendarmenuitem.c0000644000000000000000000005431013211262407015537 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #include #include "idoactionhelper.h" #include "idocalendarmenuitem.h" #include "config.h" static void ido_calendar_menu_item_finalize (GObject *item); static void ido_calendar_menu_item_select (GtkMenuItem *item); static void ido_calendar_menu_item_deselect (GtkMenuItem *item); static gboolean ido_calendar_menu_item_button_release (GtkWidget *widget, GdkEventButton *event); static gboolean ido_calendar_menu_item_button_press (GtkWidget *widget, GdkEventButton *event); static gboolean ido_calendar_menu_item_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data); static void ido_calendar_menu_item_send_focus_change (GtkWidget *widget, gboolean in); static void calendar_realized_cb (GtkWidget *widget, IdoCalendarMenuItem *item); static void calendar_move_focus_cb (GtkWidget *widget, GtkDirectionType direction, IdoCalendarMenuItem *item); static void calendar_month_changed_cb (GtkWidget *widget, gpointer user_data); static void calendar_day_selected_double_click_cb (GtkWidget *widget, gpointer user_data); static void calendar_day_selected_cb (GtkWidget *widget, gpointer user_data); struct _IdoCalendarMenuItemPrivate { GtkWidget *box; GtkWidget *calendar; GtkWidget *parent; gboolean selected; }; G_DEFINE_TYPE (IdoCalendarMenuItem, ido_calendar_menu_item, GTK_TYPE_MENU_ITEM) #define IDO_CALENDAR_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItemPrivate)) static void ido_calendar_menu_item_class_init (IdoCalendarMenuItemClass *klass) { GObjectClass *gobject_class; GtkWidgetClass *widget_class; GtkMenuItemClass *menu_item_class; gobject_class = G_OBJECT_CLASS (klass); widget_class = GTK_WIDGET_CLASS (klass); menu_item_class = GTK_MENU_ITEM_CLASS (klass); gobject_class->finalize = ido_calendar_menu_item_finalize; widget_class->button_release_event = ido_calendar_menu_item_button_release; widget_class->button_press_event = ido_calendar_menu_item_button_press; menu_item_class->select = ido_calendar_menu_item_select; menu_item_class->deselect = ido_calendar_menu_item_deselect; menu_item_class->hide_on_activate = TRUE; g_type_class_add_private (gobject_class, sizeof (IdoCalendarMenuItemPrivate)); g_signal_new("month-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_signal_new("day-selected", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_signal_new("day-selected-double-click", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void ido_calendar_menu_item_init (IdoCalendarMenuItem *item) { IdoCalendarMenuItemPrivate *priv; priv = item->priv = IDO_CALENDAR_MENU_ITEM_GET_PRIVATE (item); /* Will be disposed automatically */ priv->calendar = g_object_new (gtk_calendar_get_type (), NULL); g_object_add_weak_pointer (G_OBJECT (priv->calendar), (gpointer*) &priv->calendar); g_signal_connect (priv->calendar, "realize", G_CALLBACK (calendar_realized_cb), item); g_signal_connect (priv->calendar, "move-focus", G_CALLBACK (calendar_move_focus_cb), item); priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (priv->box), priv->calendar, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (item), priv->box); gtk_widget_show_all (priv->box); } static void ido_calendar_menu_item_finalize (GObject *object) { IdoCalendarMenuItem *item = IDO_CALENDAR_MENU_ITEM (object); IdoCalendarMenuItemPrivate *priv = IDO_CALENDAR_MENU_ITEM_GET_PRIVATE (item); if (G_IS_OBJECT (priv->calendar)) { g_object_remove_weak_pointer (G_OBJECT (priv->calendar), (gpointer*) &priv->calendar); g_signal_handlers_disconnect_by_data (priv->calendar, item); } if (G_IS_OBJECT (priv->parent)) { g_object_remove_weak_pointer (G_OBJECT (priv->parent), (gpointer*) &priv->parent); g_signal_handlers_disconnect_by_data (priv->parent, item); } G_OBJECT_CLASS (ido_calendar_menu_item_parent_class)->finalize (object); } static void ido_calendar_menu_item_send_focus_change (GtkWidget *widget, gboolean in) { GdkEvent *event = gdk_event_new (GDK_FOCUS_CHANGE); g_object_ref (widget); if (in) gtk_widget_grab_focus (widget); event->focus_change.type = GDK_FOCUS_CHANGE; event->focus_change.window = g_object_ref (gtk_widget_get_window (widget)); event->focus_change.in = in; gtk_widget_event (widget, event); g_object_notify (G_OBJECT (widget), "has-focus"); g_object_unref (widget); gdk_event_free (event); } static gboolean ido_calendar_menu_item_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data) { IdoCalendarMenuItem *menuitem = (IdoCalendarMenuItem *)data; g_return_val_if_fail (IDO_IS_CALENDAR_MENU_ITEM (menuitem), FALSE); if (menuitem->priv->selected) { GtkWidget *calendar = menuitem->priv->calendar; gtk_widget_event (calendar, ((GdkEvent *)(void*)(event))); if (gtk_widget_get_window (calendar) != NULL) { gdk_window_raise (gtk_widget_get_window (calendar)); } if (!gtk_widget_has_focus (calendar)) { gtk_widget_grab_focus (calendar); } return (event->keyval != GDK_KEY_Return) && (event->keyval != GDK_KEY_Escape); } return FALSE; } static gboolean ido_calendar_menu_item_button_press (GtkWidget *widget, GdkEventButton *event) { GtkWidget *calendar = IDO_CALENDAR_MENU_ITEM (widget)->priv->calendar; if (event->button == 1) { if (gtk_widget_get_window (calendar) != NULL) { gdk_window_raise (gtk_widget_get_window (calendar)); } if (!gtk_widget_has_focus (calendar)) { gtk_widget_grab_focus (calendar); } GdkEvent * newevent = gdk_event_copy((GdkEvent *)(event)); GList * children = gdk_window_get_children(gtk_widget_get_window(calendar)); GList * child; gint root_x = event->x_root; gint root_y = event->y_root; for (child = children; child != NULL; child = g_list_next(child)) { gint newx, newy; gint winx, winy; GdkWindow * newwindow = (GdkWindow*)child->data; ((GdkEventButton *)newevent)->window = newwindow; gdk_window_get_origin(newwindow, &winx, &winy); newx = root_x - winx; newy = root_y - winy; if (newx >= 0 && newy >= 0 && newx < gdk_window_get_width(newwindow) && newy < gdk_window_get_height(newwindow)) { ((GdkEventButton *)newevent)->x = newx; ((GdkEventButton *)newevent)->y = newy; GTK_WIDGET_GET_CLASS(calendar)->button_press_event(GTK_WIDGET(calendar), (GdkEventButton*)newevent); } } ((GdkEventButton *)newevent)->window = event->window; gdk_event_free(newevent); return TRUE; } return FALSE; } static gboolean ido_calendar_menu_item_button_release (GtkWidget *widget, GdkEventButton *event) { GtkWidget *calendar = IDO_CALENDAR_MENU_ITEM (widget)->priv->calendar; GTK_WIDGET_GET_CLASS(calendar)->button_release_event(GTK_WIDGET(calendar), event); return TRUE; } static void ido_calendar_menu_item_select (GtkMenuItem *item) { IDO_CALENDAR_MENU_ITEM (item)->priv->selected = TRUE; ido_calendar_menu_item_send_focus_change (GTK_WIDGET (IDO_CALENDAR_MENU_ITEM (item)->priv->calendar), TRUE); } static void ido_calendar_menu_item_deselect (GtkMenuItem *item) { IDO_CALENDAR_MENU_ITEM (item)->priv->selected = FALSE; ido_calendar_menu_item_send_focus_change (GTK_WIDGET (IDO_CALENDAR_MENU_ITEM (item)->priv->calendar), FALSE); } static void calendar_realized_cb (GtkWidget *widget, IdoCalendarMenuItem *item) { if (gtk_widget_get_window (widget) != NULL) { gdk_window_raise (gtk_widget_get_window (widget)); } item->priv->parent = gtk_widget_get_parent (GTK_WIDGET (item)); g_object_add_weak_pointer (G_OBJECT (item->priv->parent), (gpointer*) &item->priv->parent); g_signal_connect (item->priv->parent, "key-press-event", G_CALLBACK (ido_calendar_menu_item_key_press), item); g_signal_connect (item->priv->calendar, "month-changed", G_CALLBACK (calendar_month_changed_cb), item); g_signal_connect (item->priv->calendar, "day-selected", G_CALLBACK (calendar_day_selected_cb), item); g_signal_connect (item->priv->calendar, "day-selected-double-click", G_CALLBACK (calendar_day_selected_double_click_cb), item); ido_calendar_menu_item_send_focus_change (widget, TRUE); } static void calendar_move_focus_cb (GtkWidget *widget, GtkDirectionType direction, IdoCalendarMenuItem *item) { ido_calendar_menu_item_send_focus_change (GTK_WIDGET (IDO_CALENDAR_MENU_ITEM (item)->priv->calendar), FALSE); g_signal_emit_by_name (item, "move-focus", GTK_DIR_TAB_FORWARD); } static void calendar_month_changed_cb (GtkWidget *widget, gpointer user_data) { IdoCalendarMenuItem *item = (IdoCalendarMenuItem *)user_data; g_signal_emit_by_name (item, "month-changed", NULL); } static void calendar_day_selected_cb (GtkWidget *widget, gpointer user_data) { IdoCalendarMenuItem *item = (IdoCalendarMenuItem *)user_data; g_signal_emit_by_name (item, "day-selected", NULL); } static void calendar_day_selected_double_click_cb (GtkWidget *widget, gpointer user_data) { IdoCalendarMenuItem *item = (IdoCalendarMenuItem *)user_data; guint day, month, year; gtk_calendar_get_date (GTK_CALENDAR (widget), &year, &month, &day); g_signal_emit_by_name (item, "day-selected-double-click", NULL); } /** * ido_calendar_menu_item_new: * * Creates a new #IdoCalendarMenuItem * * Return Value: a new #IdoCalendarMenuItem. **/ GtkWidget * ido_calendar_menu_item_new (void) { return g_object_new (IDO_TYPE_CALENDAR_MENU_ITEM, NULL); } /** * ido_calendar_menu_item_get_calendar: * @menuitem: A #IdoCalendarMenuItem * * Returns the calendar associated with this menu item. * * Return Value: (transfer none): The #GtkCalendar used in this item. */ GtkWidget * ido_calendar_menu_item_get_calendar (IdoCalendarMenuItem *menuitem) { g_return_val_if_fail (IDO_IS_CALENDAR_MENU_ITEM (menuitem), NULL); return menuitem->priv->calendar; } /** * ido_calendar_menu_item_mark_day: * @menuitem: A #IdoCalendarMenuItem * @day: the day number to unmark between 1 and 31. * * Places a visual marker on a particular day. * * Return Value: #TRUE */ gboolean ido_calendar_menu_item_mark_day (IdoCalendarMenuItem *menuitem, guint day) { g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), FALSE); gtk_calendar_mark_day(GTK_CALENDAR (menuitem->priv->calendar), day); return TRUE; } /** * ido_calendar_menu_item_unmark_day: * @menuitem: A #IdoCalendarMenuItem * @day: the day number to unmark between 1 and 31. * * Removes the visual marker from a particular day. * * Return Value: #TRUE */ gboolean ido_calendar_menu_item_unmark_day (IdoCalendarMenuItem *menuitem, guint day) { g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), FALSE); gtk_calendar_unmark_day(GTK_CALENDAR (menuitem->priv->calendar), day); return TRUE; } /** * ido_calendar_menu_item_clear_marks: * @menuitem: A #IdoCalendarMenuItem * * Remove all visual markers. */ void ido_calendar_menu_item_clear_marks (IdoCalendarMenuItem *menuitem) { g_return_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem)); gtk_calendar_clear_marks(GTK_CALENDAR (menuitem->priv->calendar)); } /** * ido_calendar_menu_item_set_display_options: * @menuitem: A #IdoCalendarMenuItem * @flags: the display options to set * * Set the display options for the calendar. */ void ido_calendar_menu_item_set_display_options (IdoCalendarMenuItem *menuitem, GtkCalendarDisplayOptions flags) { g_return_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem)); gtk_calendar_set_display_options (GTK_CALENDAR (menuitem->priv->calendar), flags); } /** * ido_calendar_menu_item_get_display_options: * @menuitem: A #IdoCalendarMenuItem * * Get the display options for the calendar. * * Return Value: the display options in use */ GtkCalendarDisplayOptions ido_calendar_menu_item_get_display_options (IdoCalendarMenuItem *menuitem) { g_return_val_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem), 0); return gtk_calendar_get_display_options (GTK_CALENDAR (menuitem->priv->calendar)); } /** * ido_calendar_menu_item_get_date: * @menuitem: A #IdoCalendarMenuItem * @year: (out) (allow-none): location to store the year as a decimal number (e.g. 2011), or #NULL. * @month: (out) (allow-none): location to store the month number (between 0 and 11), or #NULL. * @day: (out) (allow-none): location to store the day number (between 1 and 31), or #NULL. * * Gets the selected date. */ void ido_calendar_menu_item_get_date (IdoCalendarMenuItem *menuitem, guint *year, guint *month, guint *day) { g_return_if_fail(IDO_IS_CALENDAR_MENU_ITEM(menuitem)); gtk_calendar_get_date (GTK_CALENDAR (menuitem->priv->calendar), year, month, day); } /** * ido_calendar_menu_item_set_date: * @menuitem: A #IdoCalendarMenuItem * @year: the year to show (e.g. 2011). * @month: a month number (between 0 and 11). * @day: The day number (between 1 and 31). * * Set the date shown on the calendar. * * Return Value: #TRUE */ gboolean ido_calendar_menu_item_set_date (IdoCalendarMenuItem *menuitem, guint year, guint month, guint day) { guint old_y, old_m, old_d; g_return_val_if_fail (IDO_IS_CALENDAR_MENU_ITEM(menuitem), FALSE); ido_calendar_menu_item_get_date (menuitem, &old_y, &old_m, &old_d); if ((old_y != year) || (old_m != month)) gtk_calendar_select_month (GTK_CALENDAR (menuitem->priv->calendar), month, year); if (old_d != day) gtk_calendar_select_day (GTK_CALENDAR (menuitem->priv->calendar), day); return TRUE; } /*** **** **** **** ***/ static void activate_current_day (IdoCalendarMenuItem * ido_calendar, const char * action_name_key) { GObject * o; const char * action_name; GActionGroup * action_group; o = G_OBJECT (ido_calendar); action_name = g_object_get_data (o, action_name_key); action_group = g_object_get_data (o, "ido-action-group"); if (action_group && action_name) { guint y, m, d; GDateTime * date_time; GVariant * target; ido_calendar_menu_item_get_date (ido_calendar, &y, &m, &d); m++; /* adjust month from GtkCalendar (0 based) to GDateTime (1 based) */ date_time = g_date_time_new_local (y, m, d, 9, 0, 0); target = g_variant_new_int64 (g_date_time_to_unix (date_time)); g_action_group_activate_action (action_group, action_name, target); g_date_time_unref (date_time); } } static void on_day_selected (IdoCalendarMenuItem * ido_calendar) { activate_current_day (ido_calendar, "ido-selection-action-name"); } static void on_day_double_clicked (IdoCalendarMenuItem * ido_calendar) { activate_current_day (ido_calendar, "ido-activation-action-name"); } static void on_action_state_changed (IdoActionHelper * helper, GVariant * state, gpointer unused G_GNUC_UNUSED) { GVariant * v; const char * key; IdoCalendarMenuItem * ido_calendar; ido_calendar = IDO_CALENDAR_MENU_ITEM (ido_action_helper_get_widget (helper)); g_return_if_fail (ido_calendar != NULL); g_return_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE_DICTIONARY)); /* an int64 representing a time_t indicating which year and month should be visible in the calendar and which day should be given the cursor. */ key = "calendar-day"; if ((v = g_variant_lookup_value (state, key, G_VARIANT_TYPE_INT64))) { int y, m, d; time_t t; GDateTime * date_time; t = g_variant_get_int64 (v); date_time = g_date_time_new_from_unix_local (t); g_date_time_get_ymd (date_time, &y, &m, &d); m--; /* adjust month from GDateTime (1 based) to GtkCalendar (0 based) */ ido_calendar_menu_item_set_date (ido_calendar, y, m, d); g_date_time_unref (date_time); g_variant_unref (v); } /* a boolean value of whether or not to show the week numbers */ key = "show-week-numbers"; if ((v = g_variant_lookup_value (state, key, G_VARIANT_TYPE_BOOLEAN))) { const GtkCalendarDisplayOptions old_flags = ido_calendar_menu_item_get_display_options (ido_calendar); GtkCalendarDisplayOptions new_flags = old_flags; if (g_variant_get_boolean (v)) new_flags |= GTK_CALENDAR_SHOW_WEEK_NUMBERS; else new_flags &= ~GTK_CALENDAR_SHOW_WEEK_NUMBERS; if (new_flags != old_flags) ido_calendar_menu_item_set_display_options (ido_calendar, new_flags); g_variant_unref (v); } /* an array of int32 day-of-months denoting days that have appointments */ key = "appointment-days"; ido_calendar_menu_item_clear_marks (ido_calendar); if ((v = g_variant_lookup_value (state, key, G_VARIANT_TYPE("ai")))) { gint32 day; GVariantIter iter; g_variant_iter_init (&iter, v); while (g_variant_iter_next (&iter, "i", &day)) ido_calendar_menu_item_mark_day (ido_calendar, day); g_variant_unref (v); } } GtkMenuItem * ido_calendar_menu_item_new_from_model (GMenuItem * menu_item, GActionGroup * actions) { GObject * o; GtkWidget * calendar; IdoCalendarMenuItem * ido_calendar; gchar * selection_action_name = NULL; gchar * activation_action_name = NULL; /* get the select & activate action names */ g_menu_item_get_attribute (menu_item, "action", "s", &selection_action_name); g_menu_item_get_attribute (menu_item, "activation-action", "s", &activation_action_name); /* remember the action group & action names so that we can poke them when user selects and double-clicks */ ido_calendar = IDO_CALENDAR_MENU_ITEM (ido_calendar_menu_item_new ()); o = G_OBJECT (ido_calendar); g_object_set_data_full (o, "ido-action-group", g_object_ref(actions), g_object_unref); g_object_set_data_full (o, "ido-selection-action-name", selection_action_name, g_free); g_object_set_data_full (o, "ido-activation-action-name", activation_action_name, g_free); calendar = ido_calendar_menu_item_get_calendar (ido_calendar); g_signal_connect_swapped (calendar, "day-selected", G_CALLBACK(on_day_selected), ido_calendar); g_signal_connect_swapped (calendar, "day-selected-double-click", G_CALLBACK(on_day_double_clicked), ido_calendar); /* Use an IdoActionHelper for state updates. Since we have two separate actions for selection & activation, we'll do the activation & targets logic here in ido-calendar */ if (selection_action_name != NULL) { IdoActionHelper * helper; helper = ido_action_helper_new (GTK_WIDGET(ido_calendar), actions, selection_action_name, NULL); g_signal_connect (helper, "action-state-changed", G_CALLBACK (on_action_state_changed), NULL); g_signal_connect_swapped (ido_calendar, "destroy", G_CALLBACK (g_object_unref), helper); } return GTK_MENU_ITEM (ido_calendar); } ayatana-ido-0.4.2/src/idocalendarmenuitem.h0000644000000000000000000000716313211262407015550 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #ifndef __IDO_CALENDAR_MENU_ITEM_H__ #define __IDO_CALENDAR_MENU_ITEM_H__ #include G_BEGIN_DECLS #define IDO_TYPE_CALENDAR_MENU_ITEM (ido_calendar_menu_item_get_type ()) #define IDO_CALENDAR_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItem)) #define IDO_CALENDAR_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItemClass)) #define IDO_IS_CALENDAR_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_CALENDAR_MENU_ITEM)) #define IDO_IS_CALENDAR_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_CALENDAR_MENU_ITEM)) #define IDO_CALENDAR_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_CALENDAR_MENU_ITEM, IdoCalendarMenuItemClass)) typedef struct _IdoCalendarMenuItem IdoCalendarMenuItem; typedef struct _IdoCalendarMenuItemClass IdoCalendarMenuItemClass; typedef struct _IdoCalendarMenuItemPrivate IdoCalendarMenuItemPrivate; struct _IdoCalendarMenuItem { GtkMenuItem parent_instance; IdoCalendarMenuItemPrivate *priv; }; struct _IdoCalendarMenuItemClass { GtkMenuItemClass parent_class; }; GType ido_calendar_menu_item_get_type (void) G_GNUC_CONST; GtkWidget *ido_calendar_menu_item_new (void); GtkWidget *ido_calendar_menu_item_get_calendar (IdoCalendarMenuItem *menuitem); gboolean ido_calendar_menu_item_mark_day (IdoCalendarMenuItem *menuitem, guint day); gboolean ido_calendar_menu_item_unmark_day (IdoCalendarMenuItem *menuitem, guint day); void ido_calendar_menu_item_clear_marks (IdoCalendarMenuItem *menuitem); void ido_calendar_menu_item_set_display_options (IdoCalendarMenuItem *menuitem, GtkCalendarDisplayOptions flags); GtkCalendarDisplayOptions ido_calendar_menu_item_get_display_options (IdoCalendarMenuItem *menuitem); void ido_calendar_menu_item_get_date (IdoCalendarMenuItem *menuitem, guint *year, guint *month, guint *day); gboolean ido_calendar_menu_item_set_date (IdoCalendarMenuItem *menuitem, guint year, guint month, guint day); GtkMenuItem * ido_calendar_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions); G_END_DECLS #endif /* __IDO_CALENDAR_MENU_ITEM_H__ */ ayatana-ido-0.4.2/src/idodetaillabel.c0000644000000000000000000002602513211262407014466 0ustar /* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include "idodetaillabel.h" #include G_DEFINE_TYPE (IdoDetailLabel, ido_detail_label, GTK_TYPE_WIDGET) struct _IdoDetailLabelPrivate { gchar *text; PangoLayout *layout; gboolean draw_lozenge; }; enum { PROP_0, PROP_TEXT, NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; static void ido_detail_label_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { IdoDetailLabel *self = IDO_DETAIL_LABEL (object); switch (property_id) { case PROP_TEXT: g_value_set_string (value, self->priv->text); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void ido_detail_label_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { IdoDetailLabel *self = IDO_DETAIL_LABEL (object); switch (property_id) { case PROP_TEXT: ido_detail_label_set_text (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void ido_detail_label_finalize (GObject *object) { IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (object)->priv; g_free (priv->text); G_OBJECT_CLASS (ido_detail_label_parent_class)->finalize (object); } static void ido_detail_label_dispose (GObject *object) { IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (object)->priv; g_clear_object (&priv->layout); G_OBJECT_CLASS (ido_detail_label_parent_class)->dispose (object); } static void ido_detail_label_ensure_layout (IdoDetailLabel *label) { IdoDetailLabelPrivate *priv = label->priv; if (priv->layout == NULL) { priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (label), priv->text); pango_layout_set_alignment (priv->layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (priv->layout, PANGO_ELLIPSIZE_END); pango_layout_set_height (priv->layout, -1); // TODO update layout on "style-updated" and "direction-changed" } } static void cairo_lozenge (cairo_t *cr, double x, double y, double w, double h, double radius) { double x1 = x + w - radius; double x2 = x + radius; double y1 = y + radius; double y2 = y + h - radius; cairo_move_to (cr, x + radius, y); cairo_arc (cr, x1, y1, radius, G_PI * 1.5, G_PI * 2); cairo_arc (cr, x1, y2, radius, 0, G_PI * 0.5); cairo_arc (cr, x2, y2, radius, G_PI * 0.5, G_PI); cairo_arc (cr, x2, y1, radius, G_PI, G_PI * 1.5); } static PangoFontMetrics * gtk_widget_get_font_metrics (GtkWidget *widget, PangoContext *context) { PangoFontDescription *font; PangoFontMetrics *metrics; gtk_style_context_get (gtk_widget_get_style_context (widget), gtk_widget_get_state_flags (widget), "font", &font, NULL); metrics = pango_context_get_metrics (context, font, pango_context_get_language (context)); pango_font_description_free (font); return metrics; } static gint ido_detail_label_get_minimum_text_width (IdoDetailLabel *label) { IdoDetailLabelPrivate *priv = label->priv; PangoContext *context; PangoFontMetrics *metrics; gint char_width; gint w; context = pango_layout_get_context (priv->layout); metrics = gtk_widget_get_font_metrics (GTK_WIDGET (label), context); char_width = pango_font_metrics_get_approximate_digit_width (metrics); w = 2 * char_width / PANGO_SCALE; pango_font_metrics_unref (metrics); return w; } static gboolean ido_detail_label_draw (GtkWidget *widget, cairo_t *cr) { IdoDetailLabel *label = IDO_DETAIL_LABEL (widget); IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (widget)->priv; PangoRectangle extents; GtkAllocation allocation; double x, w, h, radius; GdkRGBA color; if (!priv->text || !*priv->text) return TRUE; gtk_widget_get_allocation (widget, &allocation); ido_detail_label_ensure_layout (IDO_DETAIL_LABEL (widget)); pango_layout_get_extents (priv->layout, NULL, &extents); pango_extents_to_pixels (&extents, NULL); h = MIN (allocation.height, extents.height); radius = floor (h / 2.0); w = MAX (ido_detail_label_get_minimum_text_width (label), extents.width) + 2.0 * radius; x = allocation.width - w; pango_layout_set_width (priv->layout, (allocation.width - 2 * radius) * PANGO_SCALE); pango_layout_get_extents (priv->layout, NULL, &extents); pango_extents_to_pixels (&extents, NULL); gtk_style_context_get_color (gtk_widget_get_style_context (widget), gtk_widget_get_state_flags (widget), &color); gdk_cairo_set_source_rgba (cr, &color); cairo_set_line_width (cr, 1.0); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); if (priv->draw_lozenge) cairo_lozenge (cr, x, 0.0, w, h, radius); cairo_move_to (cr, x + radius, (allocation.height - extents.height) / 2.0); pango_cairo_layout_path (cr, priv->layout); cairo_fill (cr); return TRUE; } static void ido_detail_label_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural) { IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (widget)->priv; PangoRectangle extents; double radius; ido_detail_label_ensure_layout (IDO_DETAIL_LABEL (widget)); pango_layout_get_extents (priv->layout, NULL, &extents); pango_extents_to_pixels (&extents, NULL); radius = floor (extents.height / 2.0); *minimum = ido_detail_label_get_minimum_text_width (IDO_DETAIL_LABEL (widget)) + 2.0 * radius; *natural = MAX (*minimum, extents.width + 2.0 * radius); } static void ido_detail_label_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (widget)->priv; PangoContext *context; PangoFontMetrics *metrics; PangoRectangle extents; ido_detail_label_ensure_layout (IDO_DETAIL_LABEL (widget)); pango_layout_get_extents (priv->layout, NULL, &extents); pango_extents_to_pixels (&extents, NULL); context = pango_layout_get_context (priv->layout); metrics = gtk_widget_get_font_metrics (widget, context); *minimum = *natural = (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE; pango_font_metrics_unref (metrics); } static void ido_detail_label_class_init (IdoDetailLabelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->get_property = ido_detail_label_get_property; object_class->set_property = ido_detail_label_set_property; object_class->finalize = ido_detail_label_finalize; object_class->dispose = ido_detail_label_dispose; widget_class->draw = ido_detail_label_draw; widget_class->get_preferred_width = ido_detail_label_get_preferred_width; widget_class->get_preferred_height = ido_detail_label_get_preferred_height; g_type_class_add_private (klass, sizeof (IdoDetailLabelPrivate)); properties[PROP_TEXT] = g_param_spec_string ("text", "Text", "The text of the label", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } static void ido_detail_label_init (IdoDetailLabel *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, IDO_TYPE_DETAIL_LABEL, IdoDetailLabelPrivate); gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); } GtkWidget * ido_detail_label_new (const gchar *label) { return g_object_new (IDO_TYPE_DETAIL_LABEL, "text", label, NULL); } const gchar * ido_detail_label_get_text (IdoDetailLabel *label) { g_return_val_if_fail (IDO_IS_DETAIL_LABEL (label), NULL); return label->priv->text; } /* collapse_whitespace: * @str: the source string * * Collapses all occurences of consecutive whitespace charactes in @str * into a single space. * * Returns: (transfer full): a newly-allocated string */ static gchar * collapse_whitespace (const gchar *str) { GString *result; gboolean in_space = FALSE; if (str == NULL) return NULL; result = g_string_new (""); while (*str) { gunichar c = g_utf8_get_char_validated (str, -1); if (c == (gunichar) -1) break; if (!g_unichar_isspace (c)) { g_string_append_unichar (result, c); in_space = FALSE; } else if (!in_space) { g_string_append_c (result, ' '); in_space = TRUE; } str = g_utf8_next_char (str); } return g_string_free (result, FALSE); } static void ido_detail_label_set_text_impl (IdoDetailLabel *label, const gchar *text, gboolean draw_lozenge) { IdoDetailLabelPrivate * priv = label->priv; g_clear_object (&priv->layout); g_free (priv->text); priv->text = g_strdup (text); priv->draw_lozenge = draw_lozenge; g_object_notify_by_pspec (G_OBJECT (label), properties[PROP_TEXT]); gtk_widget_queue_resize (GTK_WIDGET (label)); } void ido_detail_label_set_text (IdoDetailLabel *label, const gchar *text) { gchar *str; g_return_if_fail (IDO_IS_DETAIL_LABEL (label)); str = collapse_whitespace (text); ido_detail_label_set_text_impl (label, str, FALSE); g_free (str); } void ido_detail_label_set_count (IdoDetailLabel *label, gint count) { gchar *text; g_return_if_fail (IDO_IS_DETAIL_LABEL (label)); text = g_strdup_printf ("%d", count); ido_detail_label_set_text_impl (label, text, TRUE); g_free (text); } ayatana-ido-0.4.2/src/idodetaillabel.h0000644000000000000000000000425613211262407014475 0ustar /* * Copyright 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #ifndef __IDO_DETAIL_LABEL_H__ #define __IDO_DETAIL_LABEL_H__ #include #define IDO_TYPE_DETAIL_LABEL (ido_detail_label_get_type()) #define IDO_DETAIL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_DETAIL_LABEL, IdoDetailLabel)) #define IDO_DETAIL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IDO_TYPE_DETAIL_LABEL, IdoDetailLabelClass)) #define IDO_IS_DETAIL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_DETAIL_LABEL)) #define IDO_IS_DETAIL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IDO_TYPE_DETAIL_LABEL)) #define IDO_DETAIL_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IDO_TYPE_DETAIL_LABEL, IdoDetailLabelClass)) typedef struct _IdoDetailLabel IdoDetailLabel; typedef struct _IdoDetailLabelClass IdoDetailLabelClass; typedef struct _IdoDetailLabelPrivate IdoDetailLabelPrivate; struct _IdoDetailLabel { GtkWidget parent; IdoDetailLabelPrivate *priv; }; struct _IdoDetailLabelClass { GtkWidgetClass parent_class; }; GType ido_detail_label_get_type (void) G_GNUC_CONST; GtkWidget * ido_detail_label_new (const gchar *str); const gchar * ido_detail_label_get_text (IdoDetailLabel *label); void ido_detail_label_set_text (IdoDetailLabel *label, const gchar *text); void ido_detail_label_set_count (IdoDetailLabel *label, gint count); #endif ayatana-ido-0.4.2/src/idoentrymenuitem.c0000644000000000000000000002067213211262407015133 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #include #include "idoentrymenuitem.h" #include "config.h" static void ido_entry_menu_item_select (GtkMenuItem *item); static void ido_entry_menu_item_deselect (GtkMenuItem *item); static gboolean ido_entry_menu_item_button_release (GtkWidget *widget, GdkEventButton *event); static gboolean ido_entry_menu_item_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data); static gboolean ido_entry_menu_item_button_press (GtkWidget *widget, GdkEventButton *event); static void ido_entry_menu_item_send_focus_change (GtkWidget *widget, gboolean in); static void entry_realized_cb (GtkWidget *widget, IdoEntryMenuItem *item); static void entry_move_focus_cb (GtkWidget *widget, GtkDirectionType direction, IdoEntryMenuItem *item); struct _IdoEntryMenuItemPrivate { GtkWidget *box; GtkWidget *entry; gboolean selected; }; G_DEFINE_TYPE (IdoEntryMenuItem, ido_entry_menu_item, GTK_TYPE_MENU_ITEM) #define IDO_ENTRY_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemPrivate)) static void ido_entry_menu_item_class_init (IdoEntryMenuItemClass *klass) { GObjectClass *gobject_class; GtkWidgetClass *widget_class; GtkMenuItemClass *menu_item_class; gobject_class = G_OBJECT_CLASS (klass); widget_class = GTK_WIDGET_CLASS (klass); menu_item_class = GTK_MENU_ITEM_CLASS (klass); widget_class->button_release_event = ido_entry_menu_item_button_release; widget_class->button_press_event = ido_entry_menu_item_button_press; menu_item_class->select = ido_entry_menu_item_select; menu_item_class->deselect = ido_entry_menu_item_deselect; menu_item_class->hide_on_activate = TRUE; g_type_class_add_private (gobject_class, sizeof (IdoEntryMenuItemPrivate)); } static void ido_entry_menu_item_init (IdoEntryMenuItem *item) { IdoEntryMenuItemPrivate *priv; GtkBorder border; border.left = 4; border.right = 4; border.top = 2; border.bottom = 2; priv = item->priv = IDO_ENTRY_MENU_ITEM_GET_PRIVATE (item); priv->entry = g_object_new (gtk_entry_get_type (), "inner-border", &border, NULL); g_signal_connect (priv->entry, "realize", G_CALLBACK (entry_realized_cb), item); g_signal_connect (priv->entry, "move-focus", G_CALLBACK (entry_move_focus_cb), item); priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (priv->box), priv->entry, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (item), priv->box); gtk_widget_show_all (priv->box); } static gboolean is_key_press_valid (IdoEntryMenuItem *item, gint key) { switch (key) { case GDK_KEY_Escape: case GDK_KEY_Up: case GDK_KEY_Down: case GDK_KEY_KP_Up: case GDK_KEY_KP_Down: return FALSE; default: return TRUE; } } static gboolean ido_entry_menu_item_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data) { IdoEntryMenuItem *menuitem = (IdoEntryMenuItem *)data; if (menuitem->priv->selected && is_key_press_valid (menuitem, event->keyval)) { GtkWidget *entry = menuitem->priv->entry; gtk_widget_event (entry, ((GdkEvent *)(void*)(event))); /* We've handled the event, but if the key was GDK_KEY_Return * we still want to forward the event up to the menu shell * to ensure that the menuitem receives the activate signal. */ return event->keyval != GDK_KEY_Return; } return FALSE; } static void ido_entry_menu_item_send_focus_change (GtkWidget *widget, gboolean in) { GdkEvent *event = gdk_event_new (GDK_FOCUS_CHANGE); g_object_ref (widget); event->focus_change.type = GDK_FOCUS_CHANGE; event->focus_change.window = g_object_ref (gtk_widget_get_window (widget)); event->focus_change.in = in; gtk_widget_event (widget, event); g_object_notify (G_OBJECT (widget), "has-focus"); g_object_unref (widget); gdk_event_free (event); } static gboolean ido_entry_menu_item_button_press (GtkWidget *widget, GdkEventButton *event) { GtkWidget *entry = IDO_ENTRY_MENU_ITEM (widget)->priv->entry; if (event->button == 1) { if (gtk_widget_get_window (entry) != NULL) { gdk_window_raise (gtk_widget_get_window (entry)); } if (!gtk_widget_has_focus (entry)) { gtk_widget_grab_focus (entry); } gtk_widget_event (entry, ((GdkEvent *)(void*)(event))); return TRUE; } return FALSE; } static gboolean ido_entry_menu_item_button_release (GtkWidget *widget, GdkEventButton *event) { GtkWidget *entry = IDO_ENTRY_MENU_ITEM (widget)->priv->entry; gtk_widget_event (entry, ((GdkEvent *)(void*)(event))); return TRUE; } static void ido_entry_menu_item_select (GtkMenuItem *item) { IDO_ENTRY_MENU_ITEM (item)->priv->selected = TRUE; ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), TRUE); } static void ido_entry_menu_item_deselect (GtkMenuItem *item) { IDO_ENTRY_MENU_ITEM (item)->priv->selected = FALSE; ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), FALSE); } static void entry_realized_cb (GtkWidget *widget, IdoEntryMenuItem *item) { if (gtk_widget_get_window (widget) != NULL) { gdk_window_raise (gtk_widget_get_window (widget)); } g_signal_connect (gtk_widget_get_parent (GTK_WIDGET (item)), "key-press-event", G_CALLBACK (ido_entry_menu_item_key_press), item); ido_entry_menu_item_send_focus_change (widget, TRUE); } static void entry_move_focus_cb (GtkWidget *widget, GtkDirectionType direction, IdoEntryMenuItem *item) { ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), FALSE); g_signal_emit_by_name (item, "move-focus", GTK_DIR_TAB_FORWARD); } /** * ido_entry_menu_item_new: * * Creates a new #IdoEntryMenuItem. * * Return Value: the newly created #IdoEntryMenuItem. */ GtkWidget * ido_entry_menu_item_new (void) { return g_object_new (IDO_TYPE_ENTRY_MENU_ITEM, NULL); } /** * ido_entry_menu_item_get_entry: * @menuitem: The #IdoEntryMenuItem. * * Get the #GtkEntry used in this menu item. * * Return Value: (transfer none): The #GtkEntry inside this menu item. */ GtkWidget * ido_entry_menu_item_get_entry (IdoEntryMenuItem *menuitem) { g_return_val_if_fail (IDO_IS_ENTRY_MENU_ITEM (menuitem), NULL); return menuitem->priv->entry; } ayatana-ido-0.4.2/src/idoentrymenuitem.h0000644000000000000000000000440213211262407015131 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #ifndef __IDO_ENTRY_MENU_ITEM_H__ #define __IDO_ENTRY_MENU_ITEM_H__ #include G_BEGIN_DECLS #define IDO_TYPE_ENTRY_MENU_ITEM (ido_entry_menu_item_get_type ()) #define IDO_ENTRY_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItem)) #define IDO_ENTRY_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemClass)) #define IDO_IS_ENTRY_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_ENTRY_MENU_ITEM)) #define IDO_IS_ENTRY_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_ENTRY_MENU_ITEM)) #define IDO_ENTRY_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemClass)) typedef struct _IdoEntryMenuItem IdoEntryMenuItem; typedef struct _IdoEntryMenuItemClass IdoEntryMenuItemClass; typedef struct _IdoEntryMenuItemPrivate IdoEntryMenuItemPrivate; struct _IdoEntryMenuItem { GtkMenuItem parent_instance; IdoEntryMenuItemPrivate *priv; }; struct _IdoEntryMenuItemClass { GtkMenuItemClass parent_class; }; GType ido_entry_menu_item_get_type (void) G_GNUC_CONST; GtkWidget *ido_entry_menu_item_new (void); GtkWidget *ido_entry_menu_item_get_entry (IdoEntryMenuItem *menuitem); G_END_DECLS #endif /* __IDO_ENTRY_MENU_ITEM_H__ */ ayatana-ido-0.4.2/src/ido.list0000644000000000000000000000002213211262407013021 0ustar VOID:POINTER,UINT ayatana-ido-0.4.2/src/idolocationmenuitem.c0000644000000000000000000002301413211262407015573 0ustar /* * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* strstr() */ #include #include "idoactionhelper.h" #include "idolocationmenuitem.h" enum { PROP_0, PROP_TIMEZONE, PROP_LAST }; static GParamSpec *properties[PROP_LAST]; struct _IdoLocationMenuItemPrivate { char * timezone; guint timestamp_timer; }; typedef IdoLocationMenuItemPrivate priv_t; G_DEFINE_TYPE (IdoLocationMenuItem, ido_location_menu_item, IDO_TYPE_TIME_STAMP_MENU_ITEM); /*** **** Timestamp Label ***/ static void update_timestamp (IdoLocationMenuItem * self) { GTimeZone * tz; GDateTime * date_time; tz = g_time_zone_new (self->priv->timezone); if (tz == NULL) tz = g_time_zone_new_local (); date_time = g_date_time_new_now (tz); ido_time_stamp_menu_item_set_date_time (IDO_TIME_STAMP_MENU_ITEM(self), date_time); g_date_time_unref (date_time); g_time_zone_unref (tz); } static void stop_timestamp_timer (IdoLocationMenuItem * self) { priv_t * p = self->priv; if (p->timestamp_timer != 0) { g_source_remove (p->timestamp_timer); p->timestamp_timer = 0; } } static void restart_timestamp_timer (IdoLocationMenuItem * self); static gboolean on_timestamp_timer (gpointer gself) { IdoLocationMenuItem * self = IDO_LOCATION_MENU_ITEM (gself); update_timestamp (self); restart_timestamp_timer (self); return G_SOURCE_REMOVE; } static guint calculate_seconds_until_next_minute (void) { guint seconds; GTimeSpan diff; GDateTime * now; GDateTime * next; GDateTime * start_of_next; now = g_date_time_new_now_local (); next = g_date_time_add_minutes (now, 1); start_of_next = g_date_time_new_local (g_date_time_get_year (next), g_date_time_get_month (next), g_date_time_get_day_of_month (next), g_date_time_get_hour (next), g_date_time_get_minute (next), 1); diff = g_date_time_difference (start_of_next, now); seconds = (diff + (G_TIME_SPAN_SECOND - 1)) / G_TIME_SPAN_SECOND; /* cleanup */ g_date_time_unref (start_of_next); g_date_time_unref (next); g_date_time_unref (now); return seconds; } static void restart_timestamp_timer (IdoLocationMenuItem * self) { const char * fmt = ido_time_stamp_menu_item_get_format (IDO_TIME_STAMP_MENU_ITEM (self)); gboolean timestamp_shows_seconds; int interval_sec; stop_timestamp_timer (self); timestamp_shows_seconds = fmt && (strstr(fmt,"%s") || strstr(fmt,"%S") || strstr(fmt,"%T") || strstr(fmt,"%X") || strstr(fmt,"%c")); if (timestamp_shows_seconds) interval_sec = 1; else interval_sec = calculate_seconds_until_next_minute(); self->priv->timestamp_timer = g_timeout_add_seconds (interval_sec, on_timestamp_timer, self); } /*** **** GObject Virtual Functions ***/ static void my_get_property (GObject * o, guint property_id, GValue * value, GParamSpec * pspec) { IdoLocationMenuItem * self = IDO_LOCATION_MENU_ITEM (o); priv_t * p = self->priv; switch (property_id) { case PROP_TIMEZONE: g_value_set_string (value, p->timezone); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_set_property (GObject * o, guint property_id, const GValue * value, GParamSpec * pspec) { IdoLocationMenuItem * self = IDO_LOCATION_MENU_ITEM (o); switch (property_id) { case PROP_TIMEZONE: ido_location_menu_item_set_timezone (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_dispose (GObject * object) { stop_timestamp_timer (IDO_LOCATION_MENU_ITEM (object)); G_OBJECT_CLASS (ido_location_menu_item_parent_class)->dispose (object); } static void my_finalize (GObject * object) { IdoLocationMenuItem * self = IDO_LOCATION_MENU_ITEM (object); g_free (self->priv->timezone); G_OBJECT_CLASS (ido_location_menu_item_parent_class)->finalize (object); } /*** **** Instantiation ***/ static void ido_location_menu_item_class_init (IdoLocationMenuItemClass *klass) { GObjectClass * gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (IdoLocationMenuItemPrivate)); gobject_class->get_property = my_get_property; gobject_class->set_property = my_set_property; gobject_class->dispose = my_dispose; gobject_class->finalize = my_finalize; properties[PROP_TIMEZONE] = g_param_spec_string ( "timezone", "timezone identifier", "string used to identify a timezone; eg, 'America/Chicago'", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, PROP_LAST, properties); } static void ido_location_menu_item_init (IdoLocationMenuItem *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, IDO_LOCATION_MENU_ITEM_TYPE, IdoLocationMenuItemPrivate); /* Update the timer whenever the format string changes because it determines whether we update once per second or per minute */ g_signal_connect (self, "notify::format", G_CALLBACK(restart_timestamp_timer), NULL); } /*** **** Public API ***/ /* create a new IdoLocationMenuItemType */ GtkWidget * ido_location_menu_item_new (void) { return GTK_WIDGET (g_object_new (IDO_LOCATION_MENU_ITEM_TYPE, NULL)); } /** * ido_location_menu_item_set_timezone: * @timezone: timezone identifier (eg: "America/Chicago") * * Set this location's timezone. This will be used to show the location's * current time in menuitem's right-justified secondary label. */ void ido_location_menu_item_set_timezone (IdoLocationMenuItem * self, const char * timezone) { priv_t * p; g_return_if_fail (IDO_IS_LOCATION_MENU_ITEM (self)); p = self->priv; g_free (p->timezone); p->timezone = g_strdup (timezone); update_timestamp (self); } /** * ido_location_menu_item_new_from_model: * @menu_item: the corresponding menuitem * @actions: action group to tell when this GtkMenuItem is activated * * Creates a new IdoLocationMenuItem with properties initialized from * the menuitem's attributes. * * If the menuitem's 'action' attribute is set, trigger that action * in @actions when this IdoLocationMenuItem is activated. */ GtkMenuItem * ido_location_menu_item_new_from_model (GMenuItem * menu_item, GActionGroup * actions) { guint i; guint n; gchar * str; IdoLocationMenuItem * ido_location; GParameter parameters[4]; /* create the ido_location */ n = 0; if (g_menu_item_get_attribute (menu_item, "label", "s", &str)) { GParameter p = { "text", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if (g_menu_item_get_attribute (menu_item, "x-canonical-timezone", "s", &str)) { GParameter p = { "timezone", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if (g_menu_item_get_attribute (menu_item, "x-canonical-time-format", "s", &str)) { GParameter p = { "format", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } g_assert (n <= G_N_ELEMENTS (parameters)); ido_location = g_object_newv (IDO_LOCATION_MENU_ITEM_TYPE, n, parameters); for (i=0; i * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __IDO_LOCATION_MENU_ITEM_H__ #define __IDO_LOCATION_MENU_ITEM_H__ #include #include "idotimestampmenuitem.h" G_BEGIN_DECLS #define IDO_LOCATION_MENU_ITEM_TYPE (ido_location_menu_item_get_type ()) #define IDO_LOCATION_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_LOCATION_MENU_ITEM_TYPE, IdoLocationMenuItem)) #define IDO_IS_LOCATION_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_LOCATION_MENU_ITEM_TYPE)) typedef struct _IdoLocationMenuItem IdoLocationMenuItem; typedef struct _IdoLocationMenuItemClass IdoLocationMenuItemClass; typedef struct _IdoLocationMenuItemPrivate IdoLocationMenuItemPrivate; struct _IdoLocationMenuItemClass { IdoTimeStampMenuItemClass parent_class; }; /** * A menuitem that indicates a location. * * It contains a primary label giving the location's name and a * right-aligned secondary label showing the location's current time */ struct _IdoLocationMenuItem { /*< private >*/ IdoTimeStampMenuItem parent; IdoLocationMenuItemPrivate * priv; }; GType ido_location_menu_item_get_type (void) G_GNUC_CONST; GtkWidget * ido_location_menu_item_new (void); GtkMenuItem * ido_location_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions); void ido_location_menu_item_set_timezone (IdoLocationMenuItem * menuitem, const char * timezone); void ido_location_menu_item_set_format (IdoLocationMenuItem * menuitem, const char * strftime_fmt); G_END_DECLS #endif ayatana-ido-0.4.2/src/idomediaplayermenuitem.c0000644000000000000000000003006613211262407016264 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Conor Curran * Mirco Müller * Lars Uebernickel */ #include "config.h" #include "idomediaplayermenuitem.h" #include "idoactionhelper.h" #define ALBUM_ART_SIZE 60 typedef GtkMenuItemClass IdoMediaPlayerMenuItemClass; struct _IdoMediaPlayerMenuItem { GtkMenuItem parent; GCancellable *cancellable; GtkWidget* player_label; GtkWidget* player_icon; GtkWidget* metadata_widget; GtkWidget* album_art; GtkWidget* artist_label; GtkWidget* piece_label; GtkWidget* container_label; gboolean running; }; G_DEFINE_TYPE (IdoMediaPlayerMenuItem, ido_media_player_menu_item, GTK_TYPE_MENU_ITEM); static void ido_media_player_menu_item_dispose (GObject *object) { IdoMediaPlayerMenuItem *self = IDO_MEDIA_PLAYER_MENU_ITEM (object); if (self->cancellable) { g_cancellable_cancel (self->cancellable); g_clear_object (&self->cancellable); } G_OBJECT_CLASS (ido_media_player_menu_item_parent_class)->dispose (object); } static gboolean ido_media_player_menu_item_draw (GtkWidget *widget, cairo_t *cr) { IdoMediaPlayerMenuItem *self = IDO_MEDIA_PLAYER_MENU_ITEM (widget); GTK_WIDGET_CLASS (ido_media_player_menu_item_parent_class)->draw (widget, cr); /* draw a triangle next to the application name if the app is running */ if (self->running) { const int arrow_width = 5; const int half_arrow_height = 4; GdkRGBA color; GtkAllocation allocation; GtkAllocation label_allocation; int x; int y; gtk_style_context_get_color (gtk_widget_get_style_context (widget), gtk_widget_get_state (widget), &color); gtk_widget_get_allocation (widget, &allocation); gtk_widget_get_allocation (self->player_label, &label_allocation); x = allocation.x; y = label_allocation.y - allocation.y + label_allocation.height / 2; cairo_move_to (cr, x, y - half_arrow_height); cairo_line_to (cr, x, y + half_arrow_height); cairo_line_to (cr, x + arrow_width, y); cairo_close_path (cr); gdk_cairo_set_source_rgba (cr, &color); cairo_fill (cr); } return FALSE; } static void ido_media_player_menu_item_class_init (IdoMediaPlayerMenuItemClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->dispose = ido_media_player_menu_item_dispose; widget_class->draw = ido_media_player_menu_item_draw; } static GtkWidget * track_info_label_new () { GtkWidget *label; label = gtk_label_new (NULL); gtk_label_set_width_chars (GTK_LABEL (label), 25); gtk_label_set_max_width_chars (GTK_LABEL (label), 25); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_widget_set_halign (label, GTK_ALIGN_START); gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE); return label; } static void ido_media_player_menu_item_init (IdoMediaPlayerMenuItem *self) { GtkWidget *grid; self->cancellable = g_cancellable_new (); self->player_icon = gtk_image_new(); gtk_widget_set_margin_right (self->player_icon, 6); gtk_widget_set_halign (self->player_icon, GTK_ALIGN_START); self->player_label = gtk_label_new (NULL); gtk_widget_set_halign (self->player_label, GTK_ALIGN_START); gtk_widget_set_hexpand (self->player_label, TRUE); self->album_art = gtk_image_new(); gtk_widget_set_size_request (self->album_art, ALBUM_ART_SIZE, ALBUM_ART_SIZE); gtk_widget_set_margin_right (self->album_art, 8); self->artist_label = track_info_label_new (); self->piece_label = track_info_label_new (); self->container_label = track_info_label_new (); gtk_widget_set_vexpand (self->container_label, TRUE); gtk_widget_set_valign (self->container_label, GTK_ALIGN_START); self->metadata_widget = gtk_grid_new (); gtk_grid_attach (GTK_GRID (self->metadata_widget), self->album_art, 0, 0, 1, 4); gtk_grid_attach (GTK_GRID (self->metadata_widget), self->piece_label, 1, 0, 1, 1); gtk_grid_attach (GTK_GRID (self->metadata_widget), self->artist_label, 1, 1, 1, 1); gtk_grid_attach (GTK_GRID (self->metadata_widget), self->container_label, 1, 2, 1, 1); grid = gtk_grid_new (); gtk_grid_set_row_spacing (GTK_GRID (grid), 8); gtk_grid_attach (GTK_GRID (grid), self->player_icon, 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), self->player_label, 1, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), self->metadata_widget, 0, 1, 2, 1); gtk_container_add (GTK_CONTAINER (self), grid); gtk_widget_show_all (grid); /* hide metadata by defalut (player is not running) */ gtk_widget_hide (self->metadata_widget); } static void ido_media_player_menu_item_set_player_name (IdoMediaPlayerMenuItem *self, const gchar *name) { g_return_if_fail (IDO_IS_MEDIA_PLAYER_MENU_ITEM (self)); gtk_label_set_label (GTK_LABEL (self->player_label), name); } static void ido_media_player_menu_item_set_player_icon (IdoMediaPlayerMenuItem *self, GIcon *icon) { g_return_if_fail (IDO_IS_MEDIA_PLAYER_MENU_ITEM (self)); gtk_image_set_from_gicon (GTK_IMAGE (self->player_icon), icon, GTK_ICON_SIZE_MENU); } static void ido_media_player_menu_item_set_is_running (IdoMediaPlayerMenuItem *self, gboolean running) { g_return_if_fail (IDO_IS_MEDIA_PLAYER_MENU_ITEM (self)); if (self->running != running) { self->running = running; gtk_widget_queue_draw (GTK_WIDGET (self)); } } static void album_art_received (GObject *object, GAsyncResult *result, gpointer user_data) { IdoMediaPlayerMenuItem *self = user_data; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = gdk_pixbuf_new_from_stream_finish (result, &error); if (pixbuf == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("unable to fetch album art: %s", error->message); g_error_free (error); return; } gtk_image_set_from_pixbuf (GTK_IMAGE (self->album_art), pixbuf); g_object_unref (pixbuf); } static void album_art_file_opened (GObject *object, GAsyncResult *result, gpointer user_data) { IdoMediaPlayerMenuItem *self = user_data; GFileInputStream *input; GError *error = NULL; input = g_file_read_finish (G_FILE (object), result, &error); if (input == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("unable to fetch album art: %s", error->message); g_error_free (error); return; } gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (input), ALBUM_ART_SIZE, ALBUM_ART_SIZE, TRUE, self->cancellable, album_art_received, self); g_object_unref (input); } static void ido_media_player_menu_item_set_album_art (IdoMediaPlayerMenuItem *self, const gchar *url) { GFile *file; g_return_if_fail (IDO_IS_MEDIA_PLAYER_MENU_ITEM (self)); gtk_image_clear (GTK_IMAGE (self->album_art)); if (url == NULL) return; file = g_file_new_for_uri (url); g_file_read_async (file, G_PRIORITY_DEFAULT, self->cancellable, album_art_file_opened, self); g_object_unref (file); } static void gtk_label_set_markup_printf_escaped (GtkLabel *label, const gchar *format, ...) { va_list args; gchar *str; va_start (args, format); str = g_markup_vprintf_escaped (format, args); gtk_label_set_markup (label, str); va_end (args); g_free (str); } static void ido_media_player_menu_item_set_metadata (IdoMediaPlayerMenuItem *self, const gchar *title, const gchar *artist, const gchar *album, const gchar *art_url) { g_return_if_fail (IDO_IS_MEDIA_PLAYER_MENU_ITEM (self)); /* hide if there's no metadata */ if (title == NULL || *title == '\0') { gtk_label_set_label (GTK_LABEL (self->piece_label), NULL); gtk_label_set_label (GTK_LABEL (self->artist_label), NULL); gtk_label_set_label (GTK_LABEL (self->container_label), NULL); ido_media_player_menu_item_set_album_art (self, NULL); gtk_widget_hide (self->metadata_widget); } else { gtk_label_set_markup_printf_escaped (GTK_LABEL (self->piece_label), "%s", title); gtk_label_set_markup_printf_escaped (GTK_LABEL (self->artist_label), "%s", artist); gtk_label_set_markup_printf_escaped (GTK_LABEL (self->container_label), "%s", album); ido_media_player_menu_item_set_album_art (self, art_url); gtk_widget_show (self->metadata_widget); } } static void ido_media_player_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { IdoMediaPlayerMenuItem *widget; gboolean running = FALSE; const gchar *title = NULL; const gchar *artist = NULL; const gchar *album = NULL; const gchar *art_url = NULL; g_variant_lookup (state, "running", "b", &running); g_variant_lookup (state, "title", "&s", &title); g_variant_lookup (state, "artist", "&s", &artist); g_variant_lookup (state, "album", "&s", &album); g_variant_lookup (state, "art-url", "&s", &art_url); widget = IDO_MEDIA_PLAYER_MENU_ITEM (ido_action_helper_get_widget (helper)); ido_media_player_menu_item_set_is_running (widget, running); ido_media_player_menu_item_set_metadata (widget, title, artist, album, art_url); } GtkMenuItem * ido_media_player_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions) { GtkMenuItem *widget; gchar *label; gchar *action; GVariant *v; widget = g_object_new (IDO_TYPE_MEDIA_PLAYER_MENU_ITEM, NULL); if (g_menu_item_get_attribute (menuitem, "label", "s", &label)) { ido_media_player_menu_item_set_player_name (IDO_MEDIA_PLAYER_MENU_ITEM (widget), label); g_free (label); } if ((v = g_menu_item_get_attribute_value (menuitem, "icon", NULL))) { GIcon *icon; icon = g_icon_deserialize (v); if (icon) { ido_media_player_menu_item_set_player_icon (IDO_MEDIA_PLAYER_MENU_ITEM (widget), icon); g_object_unref (icon); } g_variant_unref (v); } if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) { IdoActionHelper *helper; helper = ido_action_helper_new (GTK_WIDGET (widget), actions, action, NULL); g_signal_connect (helper, "action-state-changed", G_CALLBACK (ido_media_player_menu_item_state_changed), NULL); g_signal_connect_object (widget, "activate", G_CALLBACK (ido_action_helper_activate), helper, G_CONNECT_SWAPPED); g_signal_connect_swapped (widget, "destroy", G_CALLBACK (g_object_unref), helper); g_free (action); } return widget; } ayatana-ido-0.4.2/src/idomediaplayermenuitem.h0000644000000000000000000000313413211262407016265 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Conor Curran * Mirco Müller * Lars Uebernickel */ #ifndef __IDO_MEDIA_PLAYER_MENU_ITEM_H__ #define __IDO_MEDIA_PLAYER_MENU_ITEM_H__ #include G_BEGIN_DECLS #define IDO_TYPE_MEDIA_PLAYER_MENU_ITEM (ido_media_player_menu_item_get_type ()) #define IDO_MEDIA_PLAYER_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_MEDIA_PLAYER_MENU_ITEM, IdoMediaPlayerMenuItem)) #define IDO_IS_MEDIA_PLAYER_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_MEDIA_PLAYER_MENU_ITEM)) typedef struct _IdoMediaPlayerMenuItem IdoMediaPlayerMenuItem; GType ido_media_player_menu_item_get_type (void); GtkMenuItem * ido_media_player_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions); G_END_DECLS #endif ayatana-ido-0.4.2/src/idomenuitemfactory.c0000644000000000000000000001100513211262407015427 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include #include "ayatana-private.h" #include "idoalarmmenuitem.h" #include "idoappointmentmenuitem.h" #include "idobasicmenuitem.h" #include "idocalendarmenuitem.h" #include "idolocationmenuitem.h" #include "idoscalemenuitem.h" #include "idousermenuitem.h" #include "idomediaplayermenuitem.h" #include "idoplaybackmenuitem.h" #include "idoapplicationmenuitem.h" #include "idosourcemenuitem.h" #include "idoswitchmenuitem.h" #include "idoprogressmenuitem.h" #define IDO_TYPE_MENU_ITEM_FACTORY (ido_menu_item_factory_get_type ()) #define IDO_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_MENU_ITEM_FACTORY, IdoMenuItemFactory)) #define IDO_IS_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_MENU_ITEM_FACTORY)) typedef GObject IdoMenuItemFactory; typedef GObjectClass IdoMenuItemFactoryClass; GType ido_menu_item_factory_get_type (void); static void ido_menu_item_factory_interface_init (AyatanaMenuItemFactoryInterface *iface); G_DEFINE_TYPE_WITH_CODE (IdoMenuItemFactory, ido_menu_item_factory, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (AYATANA_TYPE_MENU_ITEM_FACTORY, ido_menu_item_factory_interface_init) g_io_extension_point_implement (AYATANA_MENU_ITEM_FACTORY_EXTENSION_POINT_NAME, g_define_type_id, "ido", 0);) static GtkMenuItem * ido_menu_item_factory_create_menu_item (AyatanaMenuItemFactory *factory, const gchar *type, GMenuItem *menuitem, GActionGroup *actions) { GtkMenuItem *item = NULL; if (g_str_equal (type, "indicator.user-menu-item")) item = ido_user_menu_item_new_from_model (menuitem, actions); if (g_str_equal (type, "indicator.guest-menu-item")) item = ido_guest_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.calendar")) item = ido_calendar_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.location")) item = ido_location_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.appointment")) item = ido_appointment_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.alarm")) item = ido_alarm_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.basic")) item = ido_basic_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.progress")) item = ido_progress_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.unity.slider")) item = ido_scale_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.unity.media-player")) item = ido_media_player_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.unity.playback-item")) item = ido_playback_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.application")) item = ido_application_menu_item_new_from_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.messages.source")) item = ido_source_menu_item_new_from_menu_model (menuitem, actions); else if (g_str_equal (type, "org.ayatana.indicator.switch")) item = ido_switch_menu_item_new_from_menu_model (menuitem, actions); return item; } static void ido_menu_item_factory_class_init (IdoMenuItemFactoryClass *class) { } static void ido_menu_item_factory_interface_init (AyatanaMenuItemFactoryInterface *iface) { iface->create_menu_item = ido_menu_item_factory_create_menu_item; } static void ido_menu_item_factory_init (IdoMenuItemFactory *factory) { } ayatana-ido-0.4.2/src/idomessagedialog.c0000644000000000000000000003262613211262407015034 0ustar /* * Copyright (C) 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell * * Design and specification: * Matthew Paul Thomas */ #include #include #include "idomessagedialog.h" #include "idotimeline.h" #include "config.h" #define IDO_MESSAGE_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialogPrivate)) static GtkWidget *ido_message_dialog_get_secondary_label (IdoMessageDialog *dialog); static GtkWidget *ido_message_dialog_get_primary_label (IdoMessageDialog *dialog); typedef struct _IdoMessageDialogPrivate IdoMessageDialogPrivate; typedef struct _IdoMessageDialogMorphContext IdoMessageDialogMorphContext; struct _IdoMessageDialogPrivate { GtkWidget *action_area; GtkWidget *primary_label; GtkWidget *secondary_label; gboolean expanded; }; struct _IdoMessageDialogMorphContext { GtkWidget *widget; IdoTimeline *timeline; GtkRequisition start; GtkRequisition end; }; G_DEFINE_TYPE (IdoMessageDialog, ido_message_dialog, GTK_TYPE_MESSAGE_DIALOG) static void ido_message_dialog_map (GtkWidget *widget) { IdoMessageDialog *dialog = IDO_MESSAGE_DIALOG (widget); IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (dialog); GTK_WIDGET_CLASS (ido_message_dialog_parent_class)->map (widget); priv->primary_label = ido_message_dialog_get_primary_label (dialog); priv->secondary_label = ido_message_dialog_get_secondary_label (dialog); gtk_widget_hide (priv->secondary_label); gtk_label_set_selectable (GTK_LABEL (priv->primary_label), FALSE); gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), FALSE); /* XXX: We really want to use gtk_window_set_deletable (GTK_WINDOW (widget), FALSE) * here, but due to a bug in compiz this is more compatible. * * See: https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/240794 */ gdk_window_set_functions (gtk_widget_get_window (widget), GDK_FUNC_RESIZE | GDK_FUNC_MOVE); ido_message_dialog_get_secondary_label (IDO_MESSAGE_DIALOG (widget)); } static IdoMessageDialogMorphContext * ido_message_dialog_morph_context_new (GtkWidget *widget, IdoTimeline *timeline, gpointer identifier, GtkRequisition *start, GtkRequisition *end) { IdoMessageDialogMorphContext *context; context = g_slice_new (IdoMessageDialogMorphContext); context->widget = widget; context->timeline = timeline; context->start = *start; context->end = *end; return context; } static void ido_message_dialog_morph_context_free (IdoMessageDialogMorphContext *context) { g_object_unref (context->timeline); g_slice_free (IdoMessageDialogMorphContext, context); } static void timeline_frame_cb (IdoTimeline *timeline, gdouble progress, gpointer user_data) { IdoMessageDialogMorphContext *context = user_data; GtkRequisition start = context->start; GtkRequisition end = context->end; gint width_diff; gint height_diff; gint width, height; width_diff = (MAX(start.width, end.width) - MIN(start.width, end.width)) * progress; height_diff = (MAX(start.height, end.height) - MIN(start.height, end.height)) * progress; gtk_window_get_size (GTK_WINDOW (context->widget), &width, &height); gtk_widget_set_size_request (context->widget, width_diff ? start.width + width_diff : -1, height_diff ? start.height + height_diff : -1); } static void timeline_finished_cb (IdoTimeline *timeline, gpointer user_data) { IdoMessageDialogMorphContext *context = user_data; IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (context->widget); gtk_widget_show (priv->action_area); gtk_widget_show (priv->secondary_label); ido_message_dialog_morph_context_free (context); } static gboolean ido_message_dialog_focus_in_event (GtkWidget *widget, GdkEventFocus *event) { IdoMessageDialog *dialog = IDO_MESSAGE_DIALOG (widget); IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (dialog); if (!priv->expanded) { GtkRequisition start; GtkRequisition end; IdoTimeline *timeline; IdoMessageDialogMorphContext *context; gtk_widget_get_preferred_size (GTK_WIDGET (dialog), NULL, &start); priv->expanded = TRUE; gtk_widget_show (priv->action_area); gtk_widget_show (priv->secondary_label); gtk_widget_get_preferred_size (GTK_WIDGET (dialog), NULL, &end); gtk_widget_hide (priv->action_area); gtk_widget_hide (priv->secondary_label); timeline = ido_timeline_new (500); context = ido_message_dialog_morph_context_new (GTK_WIDGET (dialog), timeline, "foo", &start, &end); g_signal_connect (timeline, "frame", G_CALLBACK (timeline_frame_cb), context); g_signal_connect (timeline, "finished", G_CALLBACK (timeline_finished_cb), context); ido_timeline_start (timeline); } return FALSE; } static void ido_message_dialog_constructed (GObject *object) { IdoMessageDialogPrivate *priv = IDO_MESSAGE_DIALOG_GET_PRIVATE (object); GtkWidget *vbox; GtkWidget *event_box; event_box = gtk_event_box_new (); gtk_widget_show (event_box); vbox = gtk_dialog_get_content_area (GTK_DIALOG (object)); priv->action_area = gtk_dialog_get_action_area (GTK_DIALOG (object)); g_object_ref (G_OBJECT (vbox)); gtk_container_remove (GTK_CONTAINER (object), vbox); gtk_container_add (GTK_CONTAINER (event_box), vbox); gtk_container_add (GTK_CONTAINER (object), event_box); gtk_widget_hide (priv->action_area); } static void ido_message_dialog_class_init (IdoMessageDialogClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); object_class->constructed = ido_message_dialog_constructed; widget_class->map = ido_message_dialog_map; widget_class->focus_in_event = ido_message_dialog_focus_in_event; g_type_class_add_private (object_class, sizeof (IdoMessageDialogPrivate)); } static void ido_message_dialog_init (IdoMessageDialog *dialog) { gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE); } /** * ido_message_dialog_new: * @parent: transient parent, or %NULL for none * @flags: flags * @type: type of message * @buttons: a set of buttons to use * @message_format: printf()-style format string, or %NULL * @...: arguments for @message_format * * Creates a new message dialog, which is based upon * GtkMessageDialog so it shares API and functionality * with it. IdoMessageDialog differs in that it has two * states. The initial state hides the action buttons * and the secondary message. When a user clicks on the * dialog it will expand to provide the secondary message * and the action buttons. * * Return Value: a new #IdoMessageDialog **/ GtkWidget* ido_message_dialog_new (GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const gchar *message_format, ...) { GtkWidget *widget; GtkDialog *dialog; gchar* msg = NULL; va_list args; g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL); widget = g_object_new (IDO_TYPE_MESSAGE_DIALOG, "message-type", type, "buttons", buttons, NULL); dialog = GTK_DIALOG (widget); if (message_format) { va_start (args, message_format); msg = g_strdup_vprintf (message_format, args); va_end (args); g_object_set (G_OBJECT (widget), "text", msg, NULL); g_free (msg); } if (parent != NULL) gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (parent)); if (flags & GTK_DIALOG_MODAL) gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); if (flags & GTK_DIALOG_DESTROY_WITH_PARENT) gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); return widget; } /** * ido_message_dialog_new_with_markup: * @parent: transient parent, or %NULL for none * @flags: flags * @type: type of message * @buttons: a set of buttons to use * @message_format: printf()-style format string, or %NULL * @...: arguments for @message_format. They will be escaped to allow valid XML. * * Creates a new message dialog, which is based upon * GtkMessageDialog so it shares API and functionality * with it. IdoMessageDialog differs in that it has two * states. The initial state hides the action buttons * and the secondary message. When a user clicks on the * dialog it will expand to provide the secondary message * and the action buttons. * * Return Value: a new #IdoMessageDialog **/ GtkWidget* ido_message_dialog_new_with_markup (GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const gchar *message_format, ...) { GtkWidget *widget; va_list args; gchar *msg = NULL; g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL); widget = ido_message_dialog_new (parent, flags, type, buttons, NULL); if (message_format) { va_start (args, message_format); msg = g_markup_vprintf_escaped (message_format, args); va_end (args); gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (widget), msg); g_free (msg); } return widget; } /* * This is almost humorously stupid. We jump through some hoops and kill * a few kittens here because we want to preserve API compatibility with * GtkMessageDialog and extend it instead of duplicating its functionality. * If only GtkMessageDialog were easier to extend then maybe all those * kittens wouldn't have had to die... */ static GtkWidget * ido_message_dialog_get_label (IdoMessageDialog *dialog, gboolean primary) { GList *list; gchar *text; gchar *secondary_text; GtkWidget *content; GList *children; g_object_get (G_OBJECT (dialog), "text", &text, "secondary-text", &secondary_text, NULL); g_return_val_if_fail (IDO_IS_MESSAGE_DIALOG (dialog), NULL); content = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); children = gtk_container_get_children (GTK_CONTAINER (content)); for (list = children; list != NULL; list = list->next) { if (G_TYPE_FROM_INSTANCE (list->data) == GTK_TYPE_BOX && gtk_orientable_get_orientation (list->data) == GTK_ORIENTATION_HORIZONTAL) { GList *hchildren; GList *hlist; GtkWidget *hbox = GTK_WIDGET (list->data); hchildren = gtk_container_get_children (GTK_CONTAINER (hbox)); for (hlist = hchildren; hlist != NULL; hlist = hlist->next) { if (G_TYPE_FROM_INSTANCE (hlist->data) == GTK_TYPE_BOX && gtk_orientable_get_orientation (hlist->data) == GTK_ORIENTATION_VERTICAL) { GList *vlist; GtkWidget *vbox = GTK_WIDGET (hlist->data); GList *vchildren; vchildren = gtk_container_get_children (GTK_CONTAINER (vbox)); for (vlist = vchildren; vlist != NULL; vlist = vlist->next) { GtkLabel *label; label = GTK_LABEL (vlist->data); if (strcmp ((primary ? text : secondary_text), gtk_label_get_label (label)) == 0) { return GTK_WIDGET (label); } } } } } } return NULL; } static GtkWidget * ido_message_dialog_get_secondary_label (IdoMessageDialog *dialog) { return ido_message_dialog_get_label (dialog, FALSE); } static GtkWidget * ido_message_dialog_get_primary_label (IdoMessageDialog *dialog) { return ido_message_dialog_get_label (dialog, TRUE); } ayatana-ido-0.4.2/src/idomessagedialog.h0000644000000000000000000000611213211262407015030 0ustar /* * Copyright (C) 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell * * Design and specification: * Matthew Paul Thomas */ #ifndef __IDO_MESSAGE_DIALOG_H__ #define __IDO_MESSAGE_DIALOG_H__ #include #define IDO_TYPE_MESSAGE_DIALOG (ido_message_dialog_get_type ()) #define IDO_MESSAGE_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialog)) #define IDO_MESSAGE_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialogClass)) #define IDO_IS_MESSAGE_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_MESSAGE_DIALOG)) #define IDO_IS_MESSAGE_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IDO_TYPE_MESSAGE_DIALOG)) #define IDO_MESSAGE_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_MESSAGE_DIALOG, IdoMessageDialogClass)) typedef struct _IdoMessageDialog IdoMessageDialog; typedef struct _IdoMessageDialogClass IdoMessageDialogClass; struct _IdoMessageDialog { GtkMessageDialog parent_instance; }; struct _IdoMessageDialogClass { GtkMessageDialogClass parent_class; /* Padding for future expansion */ void (*_ido_reserved1) (void); void (*_ido_reserved2) (void); void (*_ido_reserved3) (void); void (*_ido_reserved4) (void); }; GType ido_message_dialog_get_type (void) G_GNUC_CONST; GtkWidget* ido_message_dialog_new (GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const gchar *message_format, ...) G_GNUC_PRINTF (5, 6); GtkWidget* ido_message_dialog_new_with_markup (GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const gchar *message_format, ...) G_GNUC_PRINTF (5, 6); G_END_DECLS #endif /* __IDO_MESSAGE_DIALOG_H__ */ ayatana-ido-0.4.2/src/idoplaybackmenuitem.c0000644000000000000000000013753413211262407015566 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Conor Curran * Mirco Müller * Andrea Cimitan * Lars Uebernickel */ #include "config.h" #include "idoplaybackmenuitem.h" #include #include #define RECT_WIDTH 130.0f #define Y 7.0f #define INNER_RADIUS 12.5 #define MIDDLE_RADIUS 13.0f #define OUTER_RADIUS 14.5f #define CIRCLE_RADIUS 21.0f #define PREV_WIDTH 25.0f #define PREV_HEIGHT 17.0f #define NEXT_WIDTH 25.0f //PREV_WIDTH #define NEXT_HEIGHT 17.0f //PREV_HEIGHT #define TRI_WIDTH 11.0f #define TRI_HEIGHT 13.0f #define TRI_OFFSET 6.0f #define PREV_X -2.0f #define PREV_Y 13.0f #define NEXT_X 76.0f //prev_y #define NEXT_Y 13.0f //prev_y #define PAUSE_WIDTH 21.0f #define PAUSE_HEIGHT 27.0f #define BAR_WIDTH 4.5f #define BAR_HEIGHT 24.0f #define BAR_OFFSET 10.0f #define PAUSE_X 41.0f #define PAUSE_Y 7.0f #define PLAY_WIDTH 28.0f #define PLAY_HEIGHT 29.0f #define PLAY_PADDING 5.0f #define INNER_START_SHADE 0.98 #define INNER_END_SHADE 0.98 #define MIDDLE_START_SHADE 1.0 #define MIDDLE_END_SHADE 1.0 #define OUTER_START_SHADE 0.75 #define OUTER_END_SHADE 1.3 #define SHADOW_BUTTON_SHADE 0.8 #define OUTER_PLAY_START_SHADE 0.7 #define OUTER_PLAY_END_SHADE 1.38 #define BUTTON_START_SHADE 1.1 #define BUTTON_END_SHADE 0.9 #define BUTTON_SHADOW_SHADE 0.8 #define INNER_COMPRESSED_START_SHADE 1.0 #define INNER_COMPRESSED_END_SHADE 1.0 typedef enum { STATE_PAUSED, STATE_PLAYING, STATE_LAUNCHING } State; typedef enum { BUTTON_NONE, BUTTON_PREVIOUS, BUTTON_PLAYPAUSE, BUTTON_NEXT, N_BUTTONS } Button; typedef GtkMenuItemClass IdoPlaybackMenuItemClass; struct _IdoPlaybackMenuItem { GtkMenuItem parent; State current_state; Button cur_pushed_button; Button cur_hover_button; gboolean has_focus; gboolean keyboard_activated; /* TRUE if the current button was activated with a key */ GActionGroup *action_group; gchar *button_actions[N_BUTTONS]; }; G_DEFINE_TYPE (IdoPlaybackMenuItem, ido_playback_menu_item, GTK_TYPE_MENU_ITEM); static gboolean ido_playback_menu_item_draw (GtkWidget* button, cairo_t *cr); static void ido_playback_menu_item_dispose (GObject *object) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (object); if (item->action_group) { g_signal_handlers_disconnect_by_data (item->action_group, item); g_clear_object (&item->action_group); } G_OBJECT_CLASS (ido_playback_menu_item_parent_class)->dispose (object); } static void ido_playback_menu_item_finalize (GObject *object) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (object); gint i; for (i = 0; i < N_BUTTONS; i++) g_free (item->button_actions[i]); G_OBJECT_CLASS (ido_playback_menu_item_parent_class)->finalize (object); } static Button ido_playback_menu_item_get_button_at_pos (GtkWidget *item, gint x, gint y) { GtkAllocation alloc; gint left; /* 0 44 86 130 * 5 +------+ * 12 +-----+ +-----+ * |prev play next| * 40 +-----+ +-----+ * 47 +------+ */ gtk_widget_get_allocation (item, &alloc); left = alloc.x + (alloc.width - RECT_WIDTH) / 2; if (x > left && x < left + 44 && y > 12 && y < 40) return BUTTON_PREVIOUS; if (x > left + 44 && x < left + 86 && y > 5 && y < 47) return BUTTON_PLAYPAUSE; if (x > left + 86 && x < left + 130 && y > 12 && y < 40) return BUTTON_NEXT; return BUTTON_NONE; } static gboolean ido_playback_menu_item_parent_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { IdoPlaybackMenuItem *self = user_data; /* only listen to events when the playback menu item is selected */ if (!self->has_focus) return FALSE; switch (event->keyval) { case GDK_KEY_Left: self->cur_pushed_button = BUTTON_PREVIOUS; break; case GDK_KEY_Right: self->cur_pushed_button = BUTTON_NEXT; break; case GDK_KEY_space: if (self->cur_hover_button != BUTTON_NONE) self->cur_pushed_button = self->cur_hover_button; else self->cur_pushed_button = BUTTON_PLAYPAUSE; break; default: self->cur_pushed_button = BUTTON_NONE; } if (self->cur_pushed_button != BUTTON_NONE) { const gchar *action = self->button_actions[self->cur_pushed_button]; if (self->action_group && action) g_action_group_activate_action (self->action_group, action, NULL); self->keyboard_activated = TRUE; gtk_widget_queue_draw (widget); return TRUE; } return FALSE; } static gboolean ido_playback_menu_item_parent_key_release_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { IdoPlaybackMenuItem *self = user_data; switch (event->keyval) { case GDK_KEY_Left: case GDK_KEY_Right: case GDK_KEY_space: self->cur_pushed_button = BUTTON_NONE; self->keyboard_activated = FALSE; gtk_widget_queue_draw (widget); break; } return FALSE; } static void ido_playback_menu_item_parent_set (GtkWidget *widget, GtkWidget *old_parent) { GtkWidget *parent; /* Menus don't pass key events to their children. This works around * that by listening to key events on the parent widget. */ if (old_parent) { g_signal_handlers_disconnect_by_func (old_parent, ido_playback_menu_item_parent_key_press_event, widget); g_signal_handlers_disconnect_by_func (old_parent, ido_playback_menu_item_parent_key_release_event, widget); } parent = gtk_widget_get_parent (widget); if (parent) { g_signal_connect (parent, "key-press-event", G_CALLBACK (ido_playback_menu_item_parent_key_press_event), widget); g_signal_connect (parent, "key-release-event", G_CALLBACK (ido_playback_menu_item_parent_key_release_event), widget); } } static void ido_playback_menu_item_select (GtkMenuItem *item) { IdoPlaybackMenuItem *self = IDO_PLAYBACK_MENU_ITEM (item); self->has_focus = TRUE; GTK_MENU_ITEM_CLASS (ido_playback_menu_item_parent_class)->select (item); } static void ido_playback_menu_item_deselect (GtkMenuItem *item) { IdoPlaybackMenuItem *self = IDO_PLAYBACK_MENU_ITEM (item); self->has_focus = FALSE; GTK_MENU_ITEM_CLASS (ido_playback_menu_item_parent_class)->deselect (item); } static gboolean ido_playback_menu_item_button_press_event (GtkWidget *menuitem, GdkEventButton *event) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (menuitem); item->cur_pushed_button = ido_playback_menu_item_get_button_at_pos (menuitem, event->x, event->y); gtk_widget_queue_draw (menuitem); return TRUE; } static gboolean ido_playback_menu_item_button_release_event (GtkWidget *menuitem, GdkEventButton *event) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (menuitem); Button button; const gchar *action = action; button = ido_playback_menu_item_get_button_at_pos (menuitem, event->x, event->y); if (button != item->cur_pushed_button) button = BUTTON_NONE; action = item->button_actions[item->cur_pushed_button]; if (item->action_group && action) g_action_group_activate_action (item->action_group, action, NULL); item->cur_pushed_button = BUTTON_NONE; gtk_widget_queue_draw (menuitem); return TRUE; } static gboolean ido_playback_menu_item_motion_notify_event (GtkWidget *menuitem, GdkEventMotion *event) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (menuitem); item->cur_hover_button = ido_playback_menu_item_get_button_at_pos (menuitem, event->x, event->y); gtk_widget_queue_draw (menuitem); return TRUE; } static gboolean ido_playback_menu_item_leave_notify_event (GtkWidget *menuitem, GdkEventCrossing *event) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (menuitem); item->cur_pushed_button = BUTTON_NONE; item->cur_hover_button = BUTTON_NONE; gtk_widget_queue_draw (GTK_WIDGET(menuitem)); return TRUE; } static void ido_playback_menu_item_class_init (IdoPlaybackMenuItemClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkMenuItemClass *menuitem_class = GTK_MENU_ITEM_CLASS (klass); gobject_class->dispose = ido_playback_menu_item_dispose; gobject_class->finalize = ido_playback_menu_item_finalize; widget_class->button_press_event = ido_playback_menu_item_button_press_event; widget_class->button_release_event = ido_playback_menu_item_button_release_event; widget_class->motion_notify_event = ido_playback_menu_item_motion_notify_event; widget_class->leave_notify_event = ido_playback_menu_item_leave_notify_event; widget_class->parent_set = ido_playback_menu_item_parent_set; widget_class->draw = ido_playback_menu_item_draw; menuitem_class->select = ido_playback_menu_item_select; menuitem_class->deselect = ido_playback_menu_item_deselect; } static void ido_playback_menu_item_init (IdoPlaybackMenuItem *self) { gtk_widget_set_size_request (GTK_WIDGET (self), 200, 43); } static void ido_playback_menu_item_set_state (IdoPlaybackMenuItem *self, State state) { self->current_state = state; if (self->current_state == STATE_LAUNCHING) gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_ACTIVE, FALSE); else gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_ACTIVE); gtk_widget_queue_draw (GTK_WIDGET (self)); } static void ido_playback_menu_item_set_state_from_string (IdoPlaybackMenuItem *self, const gchar *state) { g_return_if_fail (state != NULL); if (g_str_equal (state, "Playing")) ido_playback_menu_item_set_state (self, STATE_PLAYING); else if (g_str_equal (state, "Launching")) ido_playback_menu_item_set_state (self, STATE_LAUNCHING); else /* "Paused" and fallback */ ido_playback_menu_item_set_state (self, STATE_PAUSED); } static void ido_playback_menu_item_action_added (GActionGroup *action_group, const gchar *action_name, gpointer user_data) { IdoPlaybackMenuItem *self = user_data; const gchar *action; action = self->button_actions[BUTTON_PLAYPAUSE]; if (action && g_str_equal (action_name, action)) { GVariant *state; state = g_action_group_get_action_state (action_group, action); if (g_variant_is_of_type (state, G_VARIANT_TYPE_STRING)) ido_playback_menu_item_set_state_from_string (self, g_variant_get_string (state, NULL)); g_variant_unref (state); } } static void ido_playback_menu_item_action_removed (GActionGroup *action_group, const gchar *action_name, gpointer user_data) { IdoPlaybackMenuItem *self = user_data; const gchar *action; action = self->button_actions[BUTTON_PLAYPAUSE]; if (action && g_str_equal (action_name, action)) ido_playback_menu_item_set_state (self, STATE_PAUSED); } static void ido_playback_menu_item_action_state_changed (GActionGroup *action_group, const gchar *action_name, GVariant *value, gpointer user_data) { IdoPlaybackMenuItem *self = user_data; const gchar *action; g_return_if_fail (action_name != NULL); action = self->button_actions[BUTTON_PLAYPAUSE]; if (action && g_str_equal (action_name, action)) { if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) ido_playback_menu_item_set_state_from_string (self, g_variant_get_string (value, NULL)); } } GtkMenuItem * ido_playback_menu_item_new_from_model (GMenuItem *item, GActionGroup *actions) { IdoPlaybackMenuItem *widget; gchar *play_action; widget = g_object_new (IDO_TYPE_PLAYBACK_MENU_ITEM, NULL); widget->action_group = g_object_ref (actions); g_signal_connect (actions, "action-state-changed", G_CALLBACK (ido_playback_menu_item_action_state_changed), widget); g_signal_connect (actions, "action-added", G_CALLBACK (ido_playback_menu_item_action_added), widget); g_signal_connect (actions, "action-removed", G_CALLBACK (ido_playback_menu_item_action_removed), widget); g_menu_item_get_attribute (item, "x-canonical-play-action", "s", &widget->button_actions[BUTTON_PLAYPAUSE]); g_menu_item_get_attribute (item, "x-canonical-next-action", "s", &widget->button_actions[BUTTON_NEXT]); g_menu_item_get_attribute (item, "x-canonical-previous-action", "s", &widget->button_actions[BUTTON_PREVIOUS]); play_action = widget->button_actions[BUTTON_PLAYPAUSE]; if (play_action && g_action_group_has_action (actions, play_action)) ido_playback_menu_item_action_added (actions, play_action, widget); return GTK_MENU_ITEM (widget); } /* * Drawing */ typedef struct { double r; double g; double b; } CairoColorRGB; static void draw_gradient (cairo_t* cr, double x, double y, double w, double r, double* rgba_start, double* rgba_end) { cairo_pattern_t* pattern = NULL; cairo_move_to (cr, x, y); cairo_line_to (cr, x + w - 2.0f * r, y); cairo_arc (cr, x + w - 2.0f * r, y + r, r, -90.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); cairo_line_to (cr, x, y + 2.0f * r); cairo_arc (cr, x, y + r, r, 90.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); cairo_close_path (cr); pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); cairo_pattern_add_color_stop_rgba (pattern, 0.0f, rgba_start[0], rgba_start[1], rgba_start[2], rgba_start[3]); cairo_pattern_add_color_stop_rgba (pattern, 1.0f, rgba_end[0], rgba_end[1], rgba_end[2], rgba_end[3]); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } static void draw_circle (cairo_t* cr, double x, double y, double r, double* rgba_start, double* rgba_end) { cairo_pattern_t* pattern = NULL; cairo_move_to (cr, x, y); cairo_arc (cr, x + r, y + r, r, 0.0f * G_PI / 180.0f, 360.0f * G_PI / 180.0f); pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); cairo_pattern_add_color_stop_rgba (pattern, 0.0f, rgba_start[0], rgba_start[1], rgba_start[2], rgba_start[3]); cairo_pattern_add_color_stop_rgba (pattern, 1.0f, rgba_end[0], rgba_end[1], rgba_end[2], rgba_end[3]); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } static void _setup (cairo_t** cr, cairo_surface_t** surf, gint width, gint height) { if (!cr || !surf) return; *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); *cr = cairo_create (*surf); cairo_scale (*cr, 1.0f, 1.0f); cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR); cairo_paint (*cr); cairo_set_operator (*cr, CAIRO_OPERATOR_OVER); } static void _mask_prev (cairo_t* cr, double x, double y, double tri_width, double tri_height, double tri_offset) { if (!cr) return; cairo_move_to (cr, x, y + tri_height / 2.0f); cairo_line_to (cr, x + tri_width, y); cairo_line_to (cr, x + tri_width, y + tri_height); x += tri_offset; cairo_move_to (cr, x, y + tri_height / 2.0f); cairo_line_to (cr, x + tri_width, y); cairo_line_to (cr, x + tri_width, y + tri_height); x -= tri_offset; cairo_rectangle (cr, x, y, 2.5f, tri_height); cairo_close_path (cr); } static void _mask_next (cairo_t* cr, double x, double y, double tri_width, double tri_height, double tri_offset) { if (!cr) return; cairo_move_to (cr, x, y); cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); cairo_line_to (cr, x, y + tri_height); x += tri_offset; cairo_move_to (cr, x, y); cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); cairo_line_to (cr, x, y + tri_height); x -= tri_offset; x += 2.0f * tri_width - tri_offset - 1.0f; cairo_rectangle (cr, x, y, 2.5f, tri_height); cairo_close_path (cr); } static void _mask_pause (cairo_t* cr, double x, double y, double bar_width, double bar_height, double bar_offset) { if (!cr) return; cairo_set_line_width (cr, bar_width); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); x += bar_width; y += bar_width; cairo_move_to (cr, x, y); cairo_line_to (cr, x, y + bar_height); cairo_move_to (cr, x + bar_offset, y); cairo_line_to (cr, x + bar_offset, y + bar_height); } static void _mask_play (cairo_t* cr, double x, double y, double tri_width, double tri_height) { if (!cr) return; cairo_move_to (cr, x, y); cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); cairo_line_to (cr, x, y + tri_height); cairo_close_path (cr); } static void _fill (cairo_t* cr, double x_start, double y_start, double x_end, double y_end, double* rgba_start, double* rgba_end, gboolean stroke) { cairo_pattern_t* pattern = NULL; if (!cr || !rgba_start || !rgba_end) return; pattern = cairo_pattern_create_linear (x_start, y_start, x_end, y_end); cairo_pattern_add_color_stop_rgba (pattern, 0.0f, rgba_start[0], rgba_start[1], rgba_start[2], rgba_start[3]); cairo_pattern_add_color_stop_rgba (pattern, 1.0f, rgba_end[0], rgba_end[1], rgba_end[2], rgba_end[3]); cairo_set_source (cr, pattern); if (stroke) cairo_stroke (cr); else cairo_fill (cr); cairo_pattern_destroy (pattern); } static void _finalize (cairo_t* cr, cairo_t** cr_surf, cairo_surface_t** surf, double x, double y) { if (!cr || !cr_surf || !surf) return; cairo_set_source_surface (cr, *surf, x, y); cairo_paint (cr); cairo_surface_destroy (*surf); cairo_destroy (*cr_surf); } static void _finalize_repaint (cairo_t* cr, cairo_t** cr_surf, cairo_surface_t** surf, double x, double y, int repaints) { if (!cr || !cr_surf || !surf) return; while (repaints > 0) { cairo_set_source_surface (cr, *surf, x, y); cairo_paint (cr); repaints--; } cairo_surface_destroy (*surf); cairo_destroy (*cr_surf); } static void _color_rgb_to_hls (gdouble *r, gdouble *g, gdouble *b) { gdouble min; gdouble max; gdouble red; gdouble green; gdouble blue; gdouble h = 0; gdouble l; gdouble s; gdouble delta; red = *r; green = *g; blue = *b; if (red > green) { if (red > blue) max = red; else max = blue; if (green < blue) min = green; else min = blue; } else { if (green > blue) max = green; else max = blue; if (red < blue) min = red; else min = blue; } l = (max+min)/2; if (fabs (max-min) < 0.0001) { h = 0; s = 0; } else { if (l <= 0.5) s = (max-min)/(max+min); else s = (max-min)/(2-max-min); delta = (max -min) != 0 ? (max -min) : 1; if(delta == 0) delta = 1; if (red == max) h = (green-blue)/delta; else if (green == max) h = 2+(blue-red)/delta; else if (blue == max) h = 4+(red-green)/delta; h *= 60; if (h < 0.0) h += 360; } *r = h; *g = l; *b = s; } static void _color_hls_to_rgb (gdouble *h, gdouble *l, gdouble *s) { gdouble hue; gdouble lightness; gdouble saturation; gdouble m1, m2; gdouble r, g, b; lightness = *l; saturation = *s; if (lightness <= 0.5) m2 = lightness*(1+saturation); else m2 = lightness+saturation-lightness*saturation; m1 = 2*lightness-m2; if (saturation == 0) { *h = lightness; *l = lightness; *s = lightness; } else { hue = *h+120; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) r = m1+(m2-m1)*hue/60; else if (hue < 180) r = m2; else if (hue < 240) r = m1+(m2-m1)*(240-hue)/60; else r = m1; hue = *h; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) g = m1+(m2-m1)*hue/60; else if (hue < 180) g = m2; else if (hue < 240) g = m1+(m2-m1)*(240-hue)/60; else g = m1; hue = *h-120; while (hue > 360) hue -= 360; while (hue < 0) hue += 360; if (hue < 60) b = m1+(m2-m1)*hue/60; else if (hue < 180) b = m2; else if (hue < 240) b = m1+(m2-m1)*(240-hue)/60; else b = m1; *h = r; *l = g; *s = b; } } static void _color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b) { double red; double green; double blue; red = a->r; green = a->g; blue = a->b; if (k == 1.0) { b->r = red; b->g = green; b->b = blue; return; } _color_rgb_to_hls (&red, &green, &blue); green *= k; if (green > 1.0) green = 1.0; else if (green < 0.0) green = 0.0; blue *= k; if (blue > 1.0) blue = 1.0; else if (blue < 0.0) blue = 0.0; _color_hls_to_rgb (&red, &green, &blue); b->r = red; b->g = green; b->b = blue; } static inline void _blurinner (guchar* pixel, gint* zR, gint* zG, gint* zB, gint* zA, gint alpha, gint aprec, gint zprec) { gint R; gint G; gint B; guchar A; R = *pixel; G = *(pixel + 1); B = *(pixel + 2); A = *(pixel + 3); *zR += (alpha * ((R << zprec) - *zR)) >> aprec; *zG += (alpha * ((G << zprec) - *zG)) >> aprec; *zB += (alpha * ((B << zprec) - *zB)) >> aprec; *zA += (alpha * ((A << zprec) - *zA)) >> aprec; *pixel = *zR >> zprec; *(pixel + 1) = *zG >> zprec; *(pixel + 2) = *zB >> zprec; *(pixel + 3) = *zA >> zprec; } static inline void _blurrow (guchar* pixels, gint width, gint height, gint channels, gint line, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* scanline; scanline = &(pixels[line * width * channels]); zR = *scanline << zprec; zG = *(scanline + 1) << zprec; zB = *(scanline + 2) << zprec; zA = *(scanline + 3) << zprec; for (index = 0; index < width; index ++) _blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = width - 2; index >= 0; index--) _blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } static inline void _blurcol (guchar* pixels, gint width, gint height, gint channels, gint x, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* ptr; ptr = pixels; ptr += x * channels; zR = *((guchar*) ptr ) << zprec; zG = *((guchar*) ptr + 1) << zprec; zB = *((guchar*) ptr + 2) << zprec; zA = *((guchar*) ptr + 3) << zprec; for (index = width; index < (height - 1) * width; index += width) _blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = (height - 2) * width; index >= 0; index -= width) _blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } static void _expblur (guchar* pixels, gint width, gint height, gint channels, gint radius, gint aprec, gint zprec) { gint alpha; gint row = 0; gint col = 0; if (radius < 1) return; // calculate the alpha such that 90% of // the kernel is within the radius. // (Kernel extends to infinity) alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f)))); for (; row < height; row++) _blurrow (pixels, width, height, channels, row, alpha, aprec, zprec); for(; col < width; col++) _blurcol (pixels, width, height, channels, col, alpha, aprec, zprec); return; } static void _surface_blur (cairo_surface_t* surface, guint radius) { guchar* pixels; guint width; guint height; cairo_format_t format; // before we mess with the surface execute any pending drawing cairo_surface_flush (surface); pixels = cairo_image_surface_get_data (surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); format = cairo_image_surface_get_format (surface); switch (format) { case CAIRO_FORMAT_ARGB32: _expblur (pixels, width, height, 4, radius, 16, 7); break; case CAIRO_FORMAT_RGB24: _expblur (pixels, width, height, 3, radius, 16, 7); break; case CAIRO_FORMAT_A8: _expblur (pixels, width, height, 1, radius, 16, 7); break; default : // do nothing break; } // inform cairo we altered the surfaces contents cairo_surface_mark_dirty (surface); } static gboolean ido_playback_menu_item_draw (GtkWidget* button, cairo_t *cr) { IdoPlaybackMenuItem *item = IDO_PLAYBACK_MENU_ITEM (button); GtkAllocation alloc; gint X; gint abs_pause_x; gint abs_prev_x; gint abs_next_x; g_return_val_if_fail(IDO_IS_PLAYBACK_MENU_ITEM (button), FALSE); g_return_val_if_fail(cr != NULL, FALSE); cairo_surface_t* surf = NULL; cairo_t* cr_surf = NULL; GtkStyle *style; CairoColorRGB bg_color, fg_color, bg_selected, bg_prelight; CairoColorRGB color_middle[2], color_middle_prelight[2], color_outer[2], color_outer_prelight[2], color_play_outer[2], color_play_outer_prelight[2], color_button[4], color_button_shadow, color_inner[2], color_inner_compressed[2]; /* Use the menu's style instead of that of the menuitem ('button' is a * menuitem that is packed in a menu directly). The menuitem's style * can't be used due to a change in light-themes (lp #1130183). * Menuitems now have a transparent background, which confuses * GtkStyle. * * This is a workaround until this code gets refactored to use * GtkStyleContext. */ style = gtk_widget_get_style (gtk_widget_get_parent (button)); bg_color.r = style->bg[0].red/65535.0; bg_color.g = style->bg[0].green/65535.0; bg_color.b = style->bg[0].blue/65535.0; bg_prelight.r = style->bg[GTK_STATE_PRELIGHT].red/65535.0; bg_prelight.g = style->bg[GTK_STATE_PRELIGHT].green/65535.0; bg_prelight.b = style->bg[GTK_STATE_PRELIGHT].blue/65535.0; bg_selected.r = style->bg[GTK_STATE_SELECTED].red/65535.0; bg_selected.g = style->bg[GTK_STATE_SELECTED].green/65535.0; bg_selected.b = style->bg[GTK_STATE_SELECTED].blue/65535.0; fg_color.r = style->fg[0].red/65535.0; fg_color.g = style->fg[0].green/65535.0; fg_color.b = style->fg[0].blue/65535.0; _color_shade (&bg_color, MIDDLE_START_SHADE, &color_middle[0]); _color_shade (&bg_color, MIDDLE_END_SHADE, &color_middle[1]); _color_shade (&bg_prelight, MIDDLE_START_SHADE, &color_middle_prelight[0]); _color_shade (&bg_prelight, MIDDLE_END_SHADE, &color_middle_prelight[1]); _color_shade (&bg_color, OUTER_START_SHADE, &color_outer[0]); _color_shade (&bg_color, OUTER_END_SHADE, &color_outer[1]); _color_shade (&bg_prelight, OUTER_START_SHADE, &color_outer_prelight[0]); _color_shade (&bg_prelight, OUTER_END_SHADE, &color_outer_prelight[1]); _color_shade (&bg_color, OUTER_PLAY_START_SHADE, &color_play_outer[0]); _color_shade (&bg_color, OUTER_PLAY_END_SHADE, &color_play_outer[1]); _color_shade (&bg_prelight, OUTER_PLAY_START_SHADE, &color_play_outer_prelight[0]); _color_shade (&bg_prelight, OUTER_PLAY_END_SHADE, &color_play_outer_prelight[1]); _color_shade (&bg_color, INNER_START_SHADE, &color_inner[0]); _color_shade (&bg_color, INNER_END_SHADE, &color_inner[1]); _color_shade (&fg_color, BUTTON_START_SHADE, &color_button[0]); _color_shade (&fg_color, BUTTON_END_SHADE, &color_button[1]); _color_shade (&bg_color, BUTTON_SHADOW_SHADE, &color_button[2]); _color_shade (&bg_color, SHADOW_BUTTON_SHADE, &color_button_shadow); _color_shade (&bg_selected, 1.0, &color_button[3]); _color_shade (&bg_color, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]); _color_shade (&bg_color, INNER_COMPRESSED_END_SHADE, &color_inner_compressed[1]); double MIDDLE_END[] = {color_middle[0].r, color_middle[0].g, color_middle[0].b, 1.0f}; double MIDDLE_START[] = {color_middle[1].r, color_middle[1].g, color_middle[1].b, 1.0f}; double MIDDLE_END_PRELIGHT[] = {color_middle_prelight[0].r, color_middle_prelight[0].g, color_middle_prelight[0].b, 1.0f}; double MIDDLE_START_PRELIGHT[] = {color_middle_prelight[1].r, color_middle_prelight[1].g, color_middle_prelight[1].b, 1.0f}; double OUTER_END[] = {color_outer[0].r, color_outer[0].g, color_outer[0].b, 1.0f}; double OUTER_START[] = {color_outer[1].r, color_outer[1].g, color_outer[1].b, 1.0f}; double OUTER_END_PRELIGHT[] = {color_outer_prelight[0].r, color_outer_prelight[0].g, color_outer_prelight[0].b, 1.0f}; double OUTER_START_PRELIGHT[] = {color_outer_prelight[1].r, color_outer_prelight[1].g, color_outer_prelight[1].b, 1.0f}; double SHADOW_BUTTON[] = {color_button_shadow.r, color_button_shadow.g, color_button_shadow.b, 0.3f}; double OUTER_PLAY_END[] = {color_play_outer[0].r, color_play_outer[0].g, color_play_outer[0].b, 1.0f}; double OUTER_PLAY_START[] = {color_play_outer[1].r, color_play_outer[1].g, color_play_outer[1].b, 1.0f}; double OUTER_PLAY_END_PRELIGHT[] = {color_play_outer_prelight[0].r, color_play_outer_prelight[0].g, color_play_outer_prelight[0].b, 1.0f}; double OUTER_PLAY_START_PRELIGHT[] = {color_play_outer_prelight[1].r, color_play_outer_prelight[1].g, color_play_outer_prelight[1].b, 1.0f}; double BUTTON_END[] = {color_button[0].r, color_button[0].g, color_button[0].b, 1.0f}; double BUTTON_START[] = {color_button[1].r, color_button[1].g, color_button[1].b, 1.0f}; double BUTTON_SHADOW[] = {color_button[2].r, color_button[2].g, color_button[2].b, 0.75f}; double BUTTON_SHADOW_FOCUS[] = {color_button[3].r, color_button[3].g, color_button[3].b, 1.0f}; double INNER_COMPRESSED_END[] = {color_inner_compressed[1].r, color_inner_compressed[1].g, color_inner_compressed[1].b, 1.0f}; double INNER_COMPRESSED_START[] = {color_inner_compressed[0].r, color_inner_compressed[0].g, color_inner_compressed[0].b, 1.0f}; gtk_widget_get_allocation (button, &alloc); X = alloc.x + (alloc.width - RECT_WIDTH) / 2 + OUTER_RADIUS; abs_pause_x = X + PAUSE_X; abs_prev_x = X + PREV_X; abs_next_x = X + NEXT_X; draw_gradient (cr, X, Y, RECT_WIDTH, OUTER_RADIUS, OUTER_START, OUTER_END); draw_gradient (cr, X, Y + 1, RECT_WIDTH - 2, MIDDLE_RADIUS, MIDDLE_START, MIDDLE_END); draw_gradient (cr, X, Y + 2, RECT_WIDTH - 4, MIDDLE_RADIUS, MIDDLE_START, MIDDLE_END); if(item->cur_pushed_button == BUTTON_PREVIOUS) { draw_gradient (cr, X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_END, OUTER_START); draw_gradient (cr, X, Y + 1, RECT_WIDTH/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); draw_gradient (cr, X, Y + 2, RECT_WIDTH/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); } else if(item->cur_pushed_button == BUTTON_NEXT) { draw_gradient (cr, RECT_WIDTH / 2 + X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_END, OUTER_START); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 1, (RECT_WIDTH - 4.5)/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 2, (RECT_WIDTH - 7)/2, MIDDLE_RADIUS, INNER_COMPRESSED_START, INNER_COMPRESSED_END); } else if (item->cur_hover_button == BUTTON_PREVIOUS) { draw_gradient (cr, X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_START_PRELIGHT, OUTER_END_PRELIGHT); draw_gradient (cr, X, Y + 1, RECT_WIDTH/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); draw_gradient (cr, X, Y + 2, RECT_WIDTH/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); } else if (item->cur_hover_button == BUTTON_NEXT) { draw_gradient (cr, RECT_WIDTH / 2 + X, Y, RECT_WIDTH/2, OUTER_RADIUS, OUTER_START_PRELIGHT, OUTER_END_PRELIGHT); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 1, (RECT_WIDTH - 4.5)/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); draw_gradient (cr, RECT_WIDTH / 2 + X, Y + 2, (RECT_WIDTH - 7)/2, MIDDLE_RADIUS, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); } // play/pause shadow if(item->cur_pushed_button != BUTTON_PLAYPAUSE) { cairo_save (cr); cairo_rectangle (cr, X, Y, RECT_WIDTH, MIDDLE_RADIUS*2); cairo_clip (cr); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f - 1.0f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) - 1.0f, CIRCLE_RADIUS + 1.0f, SHADOW_BUTTON, SHADOW_BUTTON); cairo_restore (cr); } // play/pause button if(item->cur_pushed_button == BUTTON_PLAYPAUSE) { draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) , CIRCLE_RADIUS, OUTER_PLAY_END, OUTER_PLAY_START); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, CIRCLE_RADIUS - 1.25, INNER_COMPRESSED_START, INNER_COMPRESSED_END); } else if (item->cur_hover_button == BUTTON_PLAYPAUSE) { /* this subtle offset is to fix alpha borders, should be removed once this draw routine will be refactored */ draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.1, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.1, CIRCLE_RADIUS - 0.1, OUTER_PLAY_START_PRELIGHT, OUTER_PLAY_END_PRELIGHT); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, CIRCLE_RADIUS - 1.25, MIDDLE_START_PRELIGHT, MIDDLE_END_PRELIGHT); } else { draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), CIRCLE_RADIUS, OUTER_PLAY_START, OUTER_PLAY_END); draw_circle (cr, X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, CIRCLE_RADIUS - 1.25, MIDDLE_START, MIDDLE_END); } // draw previous-button drop-shadow if ((item->cur_pushed_button == BUTTON_PREVIOUS && item->keyboard_activated) || item->cur_hover_button == BUTTON_PREVIOUS) { _setup (&cr_surf, &surf, PREV_WIDTH+6, PREV_HEIGHT+6); _mask_prev (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, FALSE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, abs_prev_x, PREV_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); _mask_prev (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW, BUTTON_SHADOW, FALSE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, abs_prev_x, PREV_Y + 1.0f); } // draw previous-button _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); _mask_prev (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_START, BUTTON_END, FALSE); _finalize (cr, &cr_surf, &surf, abs_prev_x, PREV_Y); // draw next-button drop-shadow if ((item->cur_pushed_button == BUTTON_NEXT && item->keyboard_activated) || item->cur_hover_button == BUTTON_NEXT) { _setup (&cr_surf, &surf, NEXT_WIDTH+6, NEXT_HEIGHT+6); _mask_next (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, FALSE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, abs_next_x, NEXT_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); _mask_next (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_SHADOW, BUTTON_SHADOW, FALSE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, abs_next_x, NEXT_Y + 1.0f); } // draw next-button _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); _mask_next (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, TRI_WIDTH, TRI_HEIGHT, TRI_OFFSET); _fill (cr_surf, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, (double) TRI_HEIGHT, BUTTON_START, BUTTON_END, FALSE); _finalize (cr, &cr_surf, &surf, abs_next_x, NEXT_Y); // draw pause-button drop-shadow if (item->current_state == STATE_PLAYING) { if (item->has_focus && (item->cur_hover_button == BUTTON_NONE || item->cur_hover_button == BUTTON_PLAYPAUSE) && (item->cur_pushed_button == BUTTON_NONE || item->cur_pushed_button == BUTTON_PLAYPAUSE)) { _setup (&cr_surf, &surf, PAUSE_WIDTH+6, PAUSE_HEIGHT+6); _mask_pause (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, BAR_WIDTH, BAR_HEIGHT - 2.0f * BAR_WIDTH, BAR_OFFSET); _fill (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (double) BAR_HEIGHT, BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, TRUE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, abs_pause_x, PAUSE_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); _mask_pause (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, BAR_WIDTH, BAR_HEIGHT - 2.0f * BAR_WIDTH, BAR_OFFSET); _fill (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (double) BAR_HEIGHT, BUTTON_SHADOW, BUTTON_SHADOW, TRUE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, abs_pause_x, PAUSE_Y + 1.0f); } // draw pause-button _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); _mask_pause (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, BAR_WIDTH, BAR_HEIGHT - 2.0f * BAR_WIDTH, BAR_OFFSET); _fill (cr_surf, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, (double) BAR_HEIGHT, BUTTON_START, BUTTON_END, TRUE); _finalize (cr, &cr_surf, &surf, abs_pause_x, PAUSE_Y); } else if (item->current_state == STATE_PAUSED) { if (item->has_focus && (item->cur_hover_button == BUTTON_NONE || item->cur_hover_button == BUTTON_PLAYPAUSE) && (item->cur_pushed_button == BUTTON_NONE || item->cur_pushed_button == BUTTON_PLAYPAUSE)) { _setup (&cr_surf, &surf, PLAY_WIDTH+6, PLAY_HEIGHT+6); _mask_play (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING)); _fill (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING), BUTTON_SHADOW_FOCUS, BUTTON_SHADOW_FOCUS, FALSE); _surface_blur (surf, 3); _finalize_repaint (cr, &cr_surf, &surf, abs_pause_x-0.5f, PAUSE_Y + 0.5f, 3); } else { _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); _mask_play (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING)); _fill (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING), BUTTON_SHADOW, BUTTON_SHADOW, FALSE); _surface_blur (surf, 1); _finalize (cr, &cr_surf, &surf, abs_pause_x-0.75f, PAUSE_Y + 1.0f); } // draw play-button _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); cairo_set_line_width (cr, 10.5); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); _mask_play (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING)); _fill (cr_surf, PLAY_PADDING, PLAY_PADDING, PLAY_WIDTH - (2*PLAY_PADDING), PLAY_HEIGHT - (2*PLAY_PADDING), BUTTON_START, BUTTON_END, FALSE); _finalize (cr, &cr_surf, &surf, abs_pause_x-0.5f, PAUSE_Y); } else if (item->current_state == STATE_LAUNCHING) { // the spinner is not aligned, why? because the play button has odd width/height numbers gtk_render_activity (gtk_widget_get_style_context (button), cr, 106, 6, 30, 30); } return FALSE; } ayatana-ido-0.4.2/src/idoplaybackmenuitem.h0000644000000000000000000000275713211262407015571 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Conor Curran * Lars Uebernickel */ #ifndef __IDO_PLAYBACK_MENU_ITEM_H__ #define __IDO_PLAYBACK_MENU_ITEM_H__ #include #define IDO_TYPE_PLAYBACK_MENU_ITEM (ido_playback_menu_item_get_type ()) #define IDO_PLAYBACK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_PLAYBACK_MENU_ITEM, IdoPlaybackMenuItem)) #define IDO_IS_PLAYBACK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_PLAYBACK_MENU_ITEM)) typedef struct _IdoPlaybackMenuItem IdoPlaybackMenuItem; GType ido_playback_menu_item_get_type (void); GtkMenuItem * ido_playback_menu_item_new_from_model (GMenuItem *item, GActionGroup *actions); #endif ayatana-ido-0.4.2/src/idoprogressmenuitem.c0000644000000000000000000000621113211262407015627 0ustar /* * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "idoprogressmenuitem.h" #include "idobasicmenuitem.h" #include "idoactionhelper.h" static void on_progress_action_state_changed (IdoActionHelper * helper, GVariant * state, gpointer unused G_GNUC_UNUSED) { IdoBasicMenuItem * ido_menu_item; char * str; ido_menu_item = IDO_BASIC_MENU_ITEM (ido_action_helper_get_widget (helper)); g_return_if_fail (ido_menu_item != NULL); g_return_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE_UINT32)); str = g_strdup_printf ("%"G_GUINT32_FORMAT"%%", g_variant_get_uint32 (state)); ido_basic_menu_item_set_secondary_text (ido_menu_item, str); g_free (str); } /** * ido_progress_menu_item_new_from_model: * @menu_item: the corresponding menuitem * @actions: action group to tell when this GtkMenuItem is activated * * Creates a new progress menuitem with properties initialized from * the menuitem's attributes. * * If the menuitem's 'action' attribute is set, trigger that action * in @actions when this IdoBasicMenuItem is activated. */ GtkMenuItem * ido_progress_menu_item_new_from_model (GMenuItem * menu_item, GActionGroup * actions) { guint i; guint n; gchar * str; IdoBasicMenuItem * ido_menu_item; GParameter parameters[4]; /* create the ido menuitem */; n = 0; if (g_menu_item_get_attribute (menu_item, "label", "s", &str)) { GParameter p = { "text", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } g_assert (n <= G_N_ELEMENTS (parameters)); ido_menu_item = g_object_newv (IDO_TYPE_BASIC_MENU_ITEM, n, parameters); for (i=0; i * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __IDO_PROGRESS_MENU_ITEM_H__ #define __IDO_PROGRESS_MENU_ITEM_H__ #include GtkMenuItem * ido_progress_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions); #endif ayatana-ido-0.4.2/src/idorange.c0000644000000000000000000001416313211262407013320 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #include "idorange.h" #include "idotypebuiltins.h" #include "config.h" struct _IdoRangePrivate { IdoRangeStyle style; }; static void ido_range_constructed (GObject *object); static void ido_range_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void ido_range_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); #define IDO_RANGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_RANGE, IdoRangePrivate)) G_DEFINE_TYPE (IdoRange, ido_range, GTK_TYPE_SCALE) enum { PROP_0, PROP_STYLE }; static void ido_range_class_init (IdoRangeClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); gobject_class->constructed = ido_range_constructed; gobject_class->set_property = ido_range_set_property; gobject_class->get_property = ido_range_get_property; g_object_class_install_property (gobject_class, PROP_STYLE, g_param_spec_enum ("range-style", "Range style", "The style of the range", IDO_TYPE_RANGE_STYLE, IDO_RANGE_STYLE_SMALL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); gtk_widget_class_install_style_property (widget_class, g_param_spec_int ("knob-width", "The knob width", "The knob width", G_MININT, G_MAXINT, 8, G_PARAM_READABLE)); gtk_widget_class_install_style_property (widget_class, g_param_spec_int ("knob-height", "The knob height", "The knob height", G_MININT, G_MAXINT, 8, G_PARAM_READABLE)); g_type_class_add_private (class, sizeof (IdoRangePrivate)); } static void ido_range_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { IdoRangePrivate *priv = IDO_RANGE (object)->priv; switch (prop_id) { case PROP_STYLE: g_value_set_enum (value, priv->style); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void ido_range_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { IdoRangePrivate *priv = IDO_RANGE (object)->priv; switch (prop_id) { case PROP_STYLE: priv->style = g_value_get_enum (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void ido_range_constructed (GObject *object) { IdoRange *range = IDO_RANGE (object); IdoRangeStyle style; char buf[1024]; g_object_get (range, "range-style", &style, NULL); g_snprintf (buf, sizeof (buf), "idorange-%p", range); gtk_widget_set_name (GTK_WIDGET (range), buf); if (style == IDO_RANGE_STYLE_SMALL) { gint width, height; gtk_widget_style_get (GTK_WIDGET (range), "knob-width", &width, "knob-height", &height, NULL); } gtk_range_set_slider_size_fixed (GTK_RANGE (range), TRUE); G_OBJECT_CLASS (ido_range_parent_class)->constructed (object); } static void ido_range_init (IdoRange *range) { range->priv = IDO_RANGE_GET_PRIVATE (range); } /** * ido_range_new: * @adj: A #GtkAdjustment providing the range values * @style: The range style * * Creates a new #IdoRange widget. * * Return Value: A new #IdoRange **/ GtkWidget * ido_range_new (GObject *adj, IdoRangeStyle style) { g_return_val_if_fail (GTK_IS_ADJUSTMENT (adj), NULL); return g_object_new (IDO_TYPE_RANGE, "orientation", GTK_ORIENTATION_HORIZONTAL, "adjustment", adj, "range-style", style, NULL); } ayatana-ido-0.4.2/src/idorange.h0000644000000000000000000000433513211262407013325 0ustar /* * Copyright (C) 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #ifndef __IDO_RANGE_H__ #define __IDO_RANGE_H__ #include G_BEGIN_DECLS #define IDO_TYPE_RANGE (ido_range_get_type ()) #define IDO_RANGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_RANGE, IdoRange)) #define IDO_RANGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), IDO_TYPE_RANGE, IdoRangeClass)) #define IDO_IS_RANGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_RANGE)) #define IDO_IS_RANGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IDO_TYPE_RANGE)) #define IDO_RANGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_RANGE, IdoRangeClass)) typedef enum { IDO_RANGE_STYLE_DEFAULT, IDO_RANGE_STYLE_SMALL } IdoRangeStyle; typedef struct _IdoRange IdoRange; typedef struct _IdoRangePrivate IdoRangePrivate; typedef struct _IdoRangeClass IdoRangeClass; struct _IdoRange { GtkScale parent_instance; IdoRangePrivate *priv; }; struct _IdoRangeClass { GtkScaleClass parent_class; /* Padding for future expansion */ void (*_ido_reserved1) (void); void (*_ido_reserved2) (void); void (*_ido_reserved3) (void); void (*_ido_reserved4) (void); }; GType ido_range_get_type (void) G_GNUC_CONST; GtkWidget* ido_range_new (GObject *adj, IdoRangeStyle style); G_END_DECLS #endif /* __IDO_RANGE_H__ */ ayatana-ido-0.4.2/src/idoscalemenuitem.c0000644000000000000000000010724113211262407015057 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #include "config.h" #include #include "idorange.h" #include "idoscalemenuitem.h" #include "idotypebuiltins.h" #include "idoactionhelper.h" static void ido_scale_menu_item_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void ido_scale_menu_item_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static gboolean ido_scale_menu_item_parent_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data); static void ido_scale_menu_item_select (GtkMenuItem *item); static void ido_scale_menu_item_deselect (GtkMenuItem *item); static gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem, GdkEventButton *event); static gboolean ido_scale_menu_item_button_release_event (GtkWidget *menuitem, GdkEventButton *event); static gboolean ido_scale_menu_item_motion_notify_event (GtkWidget *menuitem, GdkEventMotion *event); static void ido_scale_menu_item_primary_image_notify (GtkImage *image, GParamSpec *pspec, IdoScaleMenuItem *item); static void ido_scale_menu_item_secondary_image_notify (GtkImage *image, GParamSpec *pspec, IdoScaleMenuItem *item); static void ido_scale_menu_item_parent_set (GtkWidget *item, GtkWidget *previous_parent); static void update_packing (IdoScaleMenuItem *self, IdoScaleMenuItemStyle style); static void default_primary_clicked_handler (IdoScaleMenuItem *self); static void default_secondary_clicked_handler (IdoScaleMenuItem *self); struct _IdoScaleMenuItemPrivate { GtkWidget *scale; GtkAdjustment *adjustment; GtkWidget *primary_image; GtkWidget *secondary_image; GtkWidget *primary_label; GtkWidget *secondary_label; GtkWidget *hbox; gboolean reverse_scroll; gboolean grabbed; IdoScaleMenuItemStyle style; IdoRangeStyle range_style; gboolean ignore_value_changed; gboolean has_focus; }; enum { SLIDER_GRABBED, SLIDER_RELEASED, PRIMARY_CLICKED, SECONDARY_CLICKED, VALUE_CHANGED, LAST_SIGNAL }; enum { PROP_0, PROP_ADJUSTMENT, PROP_REVERSE_SCROLL_EVENTS, PROP_STYLE, PROP_RANGE_STYLE }; static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (IdoScaleMenuItem, ido_scale_menu_item, GTK_TYPE_MENU_ITEM) #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemPrivate)) static gboolean ido_scale_menu_item_scroll_event (GtkWidget *menuitem, GdkEventScroll *event) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem); GtkWidget *scale = priv->scale; if (priv->reverse_scroll) { switch (event->direction) { case GDK_SCROLL_UP: event->direction = GDK_SCROLL_DOWN; break; case GDK_SCROLL_DOWN: event->direction = GDK_SCROLL_UP; break; default: break; } } gtk_widget_event (scale, ((GdkEvent *)(void*)(event))); return TRUE; } static void ido_scale_menu_item_scale_value_changed (GtkRange *range, gpointer user_data) { IdoScaleMenuItem *self = user_data; IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self); /* The signal is not sent when it was set through * ido_scale_menu_item_set_value(). */ if (!priv->ignore_value_changed) g_signal_emit (self, signals[VALUE_CHANGED], 0, gtk_range_get_value (range)); } static void ido_scale_menu_item_constructed (GObject *object) { IdoScaleMenuItem *self = IDO_SCALE_MENU_ITEM (object); IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self); GObject *adj = G_OBJECT (gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 10.0, 0.0)); IdoRangeStyle range_style; GtkWidget *hbox; priv->adjustment = NULL; g_object_get (self, "range-style", &range_style, NULL); priv->scale = ido_range_new (adj, range_style); g_signal_connect (priv->scale, "value-changed", G_CALLBACK (ido_scale_menu_item_scale_value_changed), self); g_object_ref (priv->scale); gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); priv->primary_image = gtk_image_new (); g_signal_connect (priv->primary_image, "notify", G_CALLBACK (ido_scale_menu_item_primary_image_notify), self); priv->secondary_image = gtk_image_new (); g_signal_connect (priv->secondary_image, "notify", G_CALLBACK (ido_scale_menu_item_secondary_image_notify), self); priv->primary_label = gtk_label_new (""); priv->secondary_label = gtk_label_new (""); priv->hbox = hbox; update_packing (self, priv->style); gtk_container_add (GTK_CONTAINER (self), hbox); gtk_widget_add_events (GTK_WIDGET(self), GDK_SCROLL_MASK); } static void ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class) { GObjectClass *gobject_class = G_OBJECT_CLASS (item_class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (item_class); GtkMenuItemClass *menuitem_class = GTK_MENU_ITEM_CLASS (item_class); item_class->primary_clicked = default_primary_clicked_handler; item_class->secondary_clicked = default_secondary_clicked_handler; menuitem_class->select = ido_scale_menu_item_select; menuitem_class->deselect = ido_scale_menu_item_deselect; widget_class->button_press_event = ido_scale_menu_item_button_press_event; widget_class->button_release_event = ido_scale_menu_item_button_release_event; widget_class->motion_notify_event = ido_scale_menu_item_motion_notify_event; widget_class->scroll_event = ido_scale_menu_item_scroll_event; widget_class->parent_set = ido_scale_menu_item_parent_set; gobject_class->constructed = ido_scale_menu_item_constructed; gobject_class->set_property = ido_scale_menu_item_set_property; gobject_class->get_property = ido_scale_menu_item_get_property; g_object_class_install_property (gobject_class, PROP_STYLE, g_param_spec_enum ("accessory-style", "Style of primary/secondary widgets", "The style of the primary/secondary widgets", IDO_TYPE_SCALE_MENU_ITEM_STYLE, IDO_SCALE_MENU_ITEM_STYLE_NONE, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_RANGE_STYLE, g_param_spec_enum ("range-style", "Range style", "Style of the range", IDO_TYPE_RANGE_STYLE, IDO_RANGE_STYLE_DEFAULT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_ADJUSTMENT, g_param_spec_object ("adjustment", "Adjustment", "The adjustment containing the scale value", GTK_TYPE_ADJUSTMENT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_REVERSE_SCROLL_EVENTS, g_param_spec_boolean ("reverse-scroll-events", "Reverse scroll events", "Reverses how up/down scroll events are interpreted", TRUE, G_PARAM_READWRITE)); /** * IdoScaleMenuItem::slider-grabbed: * @menuitem: The #IdoScaleMenuItem emitting the signal. * * The ::slider-grabbed signal is emitted when the pointer selects the slider. */ signals[SLIDER_GRABBED] = g_signal_new ("slider-grabbed", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * IdoScaleMenuItem::slider-released: * @menuitem: The #IdoScaleMenuItem emitting the signal. * * The ::slider-released signal is emitted when the pointer releases the slider. */ signals[SLIDER_RELEASED] = g_signal_new ("slider-released", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * IdoScaleMenuItem::primary-clicked: * @menuitem: The #IdoScaleMenuItem emitting the signal. * * The ::primary-clicked signal is emitted when the pointer clicks the primary label. */ signals[PRIMARY_CLICKED] = g_signal_new ("primary-clicked", G_TYPE_FROM_CLASS (item_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (IdoScaleMenuItemClass, primary_clicked), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, /* return type */ 0 /* n_params */); /** * IdoScaleMenuItem::secondary-clicked: * @menuitem: The #IdoScaleMenuItem emitting the signal. * * The ::secondary-clicked signal is emitted when the pointer clicks the secondary label. */ signals[SECONDARY_CLICKED] = g_signal_new ("secondary-clicked", G_TYPE_FROM_CLASS (item_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (IdoScaleMenuItemClass, secondary_clicked), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, /* return type */ 0 /* n_params */); /** * IdoScaleMenuItem::value-changed: * @menuitem: the #IdoScaleMenuItem for which the value changed * @value: the new value * * Emitted whenever the value of the contained scale changes because * of user input. */ signals[VALUE_CHANGED] = g_signal_new ("value-changed", IDO_TYPE_SCALE_MENU_ITEM, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE); g_type_class_add_private (item_class, sizeof (IdoScaleMenuItemPrivate)); } static void update_packing (IdoScaleMenuItem *self, IdoScaleMenuItemStyle style) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self); GtkBox * box = GTK_BOX (priv->hbox); GtkContainer *container = GTK_CONTAINER (priv->hbox); /* remove the old layout */ GList * children = gtk_container_get_children (container); GList * l; for (l=children; l!=NULL; l=l->next) gtk_container_remove (container, l->data); g_list_free (children); /* add the new layout */ switch (style) { case IDO_SCALE_MENU_ITEM_STYLE_IMAGE: gtk_box_pack_start (box, priv->primary_image, FALSE, FALSE, 0); gtk_box_pack_start (box, priv->scale, TRUE, TRUE, 0); gtk_box_pack_start (box, priv->secondary_image, FALSE, FALSE, 0); break; case IDO_SCALE_MENU_ITEM_STYLE_LABEL: gtk_box_pack_start (box, priv->primary_label, FALSE, FALSE, 0); gtk_box_pack_start (box, priv->scale, TRUE, TRUE, 0); gtk_box_pack_start (box, priv->secondary_label, FALSE, FALSE, 0); break; default: gtk_box_pack_start (box, priv->scale, TRUE, TRUE, 0); break; } gtk_widget_show_all (priv->hbox); } static void ido_scale_menu_item_init (IdoScaleMenuItem *self) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self); priv->reverse_scroll = TRUE; gtk_widget_set_size_request (GTK_WIDGET (self), 200, -1); } static void ido_scale_menu_item_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { IdoScaleMenuItem *menu_item = IDO_SCALE_MENU_ITEM (object); IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menu_item); switch (prop_id) { case PROP_ADJUSTMENT: gtk_range_set_adjustment (GTK_RANGE (priv->scale), g_value_get_object (value)); break; case PROP_REVERSE_SCROLL_EVENTS: priv->reverse_scroll = g_value_get_boolean (value); break; case PROP_STYLE: ido_scale_menu_item_set_style (menu_item, g_value_get_enum (value)); break; case PROP_RANGE_STYLE: priv->range_style = g_value_get_enum (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void ido_scale_menu_item_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { IdoScaleMenuItem *menu_item = IDO_SCALE_MENU_ITEM (object); IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menu_item); GtkAdjustment *adjustment; switch (prop_id) { case PROP_ADJUSTMENT: adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->scale)); g_value_set_object (value, adjustment); break; case PROP_REVERSE_SCROLL_EVENTS: g_value_set_boolean (value, priv->reverse_scroll); break; case PROP_RANGE_STYLE: g_value_set_enum (value, priv->range_style); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static gboolean ido_scale_menu_item_parent_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (user_data); /* only listen to events when the playback menu item is selected */ if (!priv->has_focus) return FALSE; switch (event->keyval) { case GDK_KEY_Left: case GDK_KEY_minus: case GDK_KEY_KP_Subtract: GTK_RANGE_GET_CLASS (priv->scale)->move_slider (GTK_RANGE (priv->scale), GTK_SCROLL_STEP_LEFT); return TRUE; case GDK_KEY_Right: case GDK_KEY_plus: case GDK_KEY_KP_Add: GTK_RANGE_GET_CLASS (priv->scale)->move_slider (GTK_RANGE (priv->scale), GTK_SCROLL_STEP_RIGHT); return TRUE; } return FALSE; } static void ido_scale_menu_item_select (GtkMenuItem *item) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item); priv->has_focus = TRUE; gtk_widget_set_state_flags (priv->scale, GTK_STATE_FLAG_FOCUSED, FALSE); GTK_MENU_ITEM_CLASS (ido_scale_menu_item_parent_class)->select (item); } static void ido_scale_menu_item_deselect (GtkMenuItem *item) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item); priv->has_focus = FALSE; gtk_widget_unset_state_flags (priv->scale, GTK_STATE_FLAG_FOCUSED); GTK_MENU_ITEM_CLASS (ido_scale_menu_item_parent_class)->deselect (item); } static gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem, GdkEventButton *event) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem); GtkAllocation alloc; gint x, y; gtk_widget_get_allocation (priv->scale, &alloc); gtk_widget_translate_coordinates (menuitem, priv->scale, event->x, event->y, &x, &y); if (x > 0 && x < alloc.width && y > 0 && y < alloc.height) gtk_widget_event (priv->scale, (GdkEvent *) event); if (!priv->grabbed) { priv->grabbed = TRUE; g_signal_emit (menuitem, signals[SLIDER_GRABBED], 0); } return TRUE; } static gboolean ido_scale_menu_item_button_release_event (GtkWidget *menuitem, GdkEventButton *event) { IdoScaleMenuItem *item = IDO_SCALE_MENU_ITEM (menuitem); IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem); GtkWidget *scale = priv->scale; GtkAllocation alloc; gint x, y; gtk_widget_get_allocation (priv->scale, &alloc); gtk_widget_translate_coordinates (menuitem, priv->scale, event->x, event->y, &x, &y); /* if user clicked to the left of the scale... */ if (x < 0) { if (gtk_widget_get_direction (menuitem) == GTK_TEXT_DIR_LTR) { ido_scale_menu_item_primary_clicked (item); } else { ido_scale_menu_item_secondary_clicked (item); } } /* if user clicked to the right of the scale... */ else if (x > alloc.width) { if (gtk_widget_get_direction (menuitem) == GTK_TEXT_DIR_LTR) { ido_scale_menu_item_secondary_clicked (item); } else { ido_scale_menu_item_primary_clicked (item); } } /* user clicked on the scale... */ else if (x > 0 && x < alloc.width && y > 0 && y < alloc.height) { gtk_widget_event (scale, (GdkEvent*) event); } if (priv->grabbed) { priv->grabbed = FALSE; g_signal_emit (menuitem, signals[SLIDER_RELEASED], 0); } return TRUE; } static gboolean ido_scale_menu_item_motion_notify_event (GtkWidget *menuitem, GdkEventMotion *event) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem); GtkAllocation alloc; gint x, y; gtk_widget_get_allocation (priv->scale, &alloc); gtk_widget_translate_coordinates (menuitem, priv->scale, event->x, event->y, &x, &y); /* don't translate coordinates when the scale has the "grab" - * GtkRange expects coords relative to its event window in that case */ if (!priv->grabbed) { event->x = x; event->y = y; } if (priv->grabbed || (x > 0 && x < alloc.width && y > 0 && y < alloc.height)) gtk_widget_event (priv->scale, (GdkEvent *) event); return TRUE; } static void menu_hidden (GtkWidget *menu, IdoScaleMenuItem *scale) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (scale); if (priv->grabbed) { priv->grabbed = FALSE; g_signal_emit (scale, signals[SLIDER_RELEASED], 0); } } static void ido_scale_menu_item_parent_set (GtkWidget *item, GtkWidget *previous_parent) { GtkWidget *parent; if (previous_parent) { g_signal_handlers_disconnect_by_func (previous_parent, menu_hidden, item); g_signal_handlers_disconnect_by_func (previous_parent, ido_scale_menu_item_parent_key_press_event, item); } parent = gtk_widget_get_parent (item); if (parent) { g_signal_connect (parent, "hide", G_CALLBACK (menu_hidden), item); /* Menus don't pass key events to their children. This works around * that by listening to key events on the parent widget. */ g_signal_connect (parent, "key-press-event", G_CALLBACK (ido_scale_menu_item_parent_key_press_event), item); } } static void ido_scale_menu_item_primary_image_notify (GtkImage *image, GParamSpec *pspec, IdoScaleMenuItem *item) { if (gtk_image_get_storage_type (image) == GTK_IMAGE_EMPTY) gtk_widget_hide (GTK_WIDGET (image)); else gtk_widget_show (GTK_WIDGET (image)); } static void ido_scale_menu_item_secondary_image_notify (GtkImage *image, GParamSpec *pspec, IdoScaleMenuItem *item) { if (gtk_image_get_storage_type (image) == GTK_IMAGE_EMPTY) gtk_widget_hide (GTK_WIDGET (image)); else gtk_widget_show (GTK_WIDGET (image)); } /** * ido_scale_menu_item_new: * @label: the text of the new menu item. * @size: The size style of the range. * @adjustment: A #GtkAdjustment describing the slider value. * * Creates a new #IdoScaleMenuItem with an empty label. * * Return Value: a new #IdoScaleMenuItem. **/ GtkWidget* ido_scale_menu_item_new (const gchar *label, IdoRangeStyle range_style, GtkAdjustment *adjustment) { return g_object_new (IDO_TYPE_SCALE_MENU_ITEM, "adjustment", adjustment, "range-style", range_style, NULL); } /** * ido_scale_menu_item_new_with_label: * @label: the text of the menu item. * @size: The size style of the range. * @min: The minimum value of the slider. * @max: The maximum value of the slider. * @step: The step increment of the slider. * * Creates a new #IdoScaleMenuItem containing a label. * * Return Value: a new #IdoScaleMenuItem. **/ GtkWidget* ido_scale_menu_item_new_with_range (const gchar *label, IdoRangeStyle range_style, gdouble value, gdouble min, gdouble max, gdouble step) { GObject *adjustment = G_OBJECT (gtk_adjustment_new (value, min, max, step, 10 * step, 0)); return GTK_WIDGET (g_object_new (IDO_TYPE_SCALE_MENU_ITEM, "label", label, "range-style", range_style, "adjustment", adjustment, NULL)); } /** * ido_scale_menu_item_get_scale: * @menuitem: The #IdoScaleMenuItem * * Retrieves the scale widget. * * Return Value: (transfer none): The #IdoRange in this item **/ GtkWidget* ido_scale_menu_item_get_scale (IdoScaleMenuItem *menuitem) { IdoScaleMenuItemPrivate *priv; g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL); priv = GET_PRIVATE (menuitem); return priv->scale; } /** * ido_scale_menu_item_get_style: * @menuitem: The #IdoScaleMenuItem * * Retrieves the type of widgets being used for the primary and * secondary widget slots. This could be images, labels, or nothing. * * Return Value: A #IdoScaleMenuItemStyle enum describing the style. **/ IdoScaleMenuItemStyle ido_scale_menu_item_get_style (IdoScaleMenuItem *menuitem) { IdoScaleMenuItemPrivate *priv; g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), IDO_SCALE_MENU_ITEM_STYLE_NONE); priv = GET_PRIVATE (menuitem); return priv->style; } /** * ido_scale_menu_item_set_style: * @menuitem: The #IdoScaleMenuItem * @style: Set the style use for the primary and secondary widget slots. * * Sets the type of widgets being used for the primary and * secondary widget slots. This could be images, labels, or nothing. **/ void ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem, IdoScaleMenuItemStyle style) { IdoScaleMenuItemPrivate *priv; g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem)); priv = GET_PRIVATE (menuitem); priv->style = style; update_packing (menuitem, style); } /** * ido_scale_menu_item_get_primary_image: * @menuitem: The #IdoScaleMenuItem * * Retrieves a pointer to the image widget used in the primary slot. * Whether this is visible depends upon the return value from * ido_scale_menu_item_get_style(). * * Return Value: (transfer none): A #GtkWidget pointer for the primary image. **/ GtkWidget * ido_scale_menu_item_get_primary_image (IdoScaleMenuItem *menuitem) { IdoScaleMenuItemPrivate *priv; g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL); priv = GET_PRIVATE (menuitem); return priv->primary_image; } /** * ido_scale_menu_item_get_secondary_image: * @menuitem: The #IdoScaleMenuItem * * Retrieves a pointer to the image widget used in the secondary slot. * Whether this is visible depends upon the return value from * ido_scale_menu_item_get_style(). * * Return Value: (transfer none): A #GtkWidget pointer for the secondary image. **/ GtkWidget * ido_scale_menu_item_get_secondary_image (IdoScaleMenuItem *menuitem) { IdoScaleMenuItemPrivate *priv; g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL); priv = GET_PRIVATE (menuitem); return priv->secondary_image; } /** * ido_scale_menu_item_set_icons: * @item: a #IdoScaleMenuItem * @primary-icon: (allow-none): the primary icon, or %NULL * @secondary-icon: (allow-none): the secondary icon, %NULL * * Sets the icons of @item to @primary_icon and @secondary_icon. * Pass %NULL for either of them to unset the icon. */ static void ido_scale_menu_item_set_icons (IdoScaleMenuItem *item, GIcon *primary_icon, GIcon *secondary_icon) { GtkWidget *primary; GtkWidget *secondary; primary = ido_scale_menu_item_get_primary_image (item); secondary = ido_scale_menu_item_get_secondary_image (item); if (primary_icon) gtk_image_set_from_gicon (GTK_IMAGE (primary), primary_icon, GTK_ICON_SIZE_MENU); else gtk_image_clear (GTK_IMAGE (primary)); if (secondary_icon) gtk_image_set_from_gicon (GTK_IMAGE (secondary), secondary_icon, GTK_ICON_SIZE_MENU); else gtk_image_clear (GTK_IMAGE (secondary)); } /** * ido_scale_menu_item_get_primary_label: * @menuitem: The #IdoScaleMenuItem * * Retrieves a string of the text for the primary label widget. * Whether this is visible depends upon the return value from * ido_scale_menu_item_get_style(). * * Return Value: The label text. **/ const gchar* ido_scale_menu_item_get_primary_label (IdoScaleMenuItem *menuitem) { IdoScaleMenuItemPrivate *priv; g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL); priv = GET_PRIVATE (menuitem); return gtk_label_get_text (GTK_LABEL (priv->primary_label)); } /** * ido_scale_menu_item_get_secondary_label: * @menuitem: The #IdoScaleMenuItem * * Retrieves a string of the text for the secondary label widget. * Whether this is visible depends upon the return value from * ido_scale_menu_item_get_style(). * * Return Value: The label text. **/ const gchar* ido_scale_menu_item_get_secondary_label (IdoScaleMenuItem *menuitem) { IdoScaleMenuItemPrivate *priv; g_return_val_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem), NULL); priv = GET_PRIVATE (menuitem); return gtk_label_get_text (GTK_LABEL (priv->secondary_label)); } /** * ido_scale_menu_item_set_primary_label: * @menuitem: The #IdoScaleMenuItem * @label: The label text * * Sets the text for the label widget in the primary slot. This * widget will only be visibile if the return value of * ido_scale_menu_item_get_style() is set to %IDO_SCALE_MENU_ITEM_STYLE_LABEL. **/ void ido_scale_menu_item_set_primary_label (IdoScaleMenuItem *menuitem, const gchar *label) { IdoScaleMenuItemPrivate *priv; g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem)); priv = GET_PRIVATE (menuitem); if (priv->primary_label) { gtk_label_set_text (GTK_LABEL (priv->primary_label), label); } } /** * ido_scale_menu_item_set_secondary_label: * @menuitem: The #IdoScaleMenuItem * @label: The label text * * Sets the text for the label widget in the secondary slot. This * widget will only be visibile if the return value of * ido_scale_menu_item_get_style() is set to %IDO_SCALE_MENU_ITEM_STYLE_LABEL. **/ void ido_scale_menu_item_set_secondary_label (IdoScaleMenuItem *menuitem, const gchar *label) { IdoScaleMenuItemPrivate *priv; g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem)); priv = GET_PRIVATE (menuitem); if (priv->secondary_label) { gtk_label_set_text (GTK_LABEL (priv->secondary_label), label); } } /** * ido_scale_menu_item_primary_clicked: * @menuitem: the #IdoScaleMenuItem * * Emits the "primary-clicked" signal. * * The default handler for this signal lowers the scale's * adjustment to its lower bound. */ void ido_scale_menu_item_primary_clicked (IdoScaleMenuItem * menuitem) { g_signal_emit (menuitem, signals[PRIMARY_CLICKED], 0); } static void default_primary_clicked_handler (IdoScaleMenuItem * item) { g_debug ("%s: setting scale to lower bound", G_STRFUNC); IdoScaleMenuItemPrivate * priv = GET_PRIVATE (item); GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale)); gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj)); } /** * ido_scale_menu_item_secondary_clicked: * @menuitem: the #IdoScaleMenuItem * * Emits the "secondary-clicked" signal. * * The default handler for this signal raises the scale's * adjustment to its upper bound. */ void ido_scale_menu_item_secondary_clicked (IdoScaleMenuItem * menuitem) { g_signal_emit (menuitem, signals[SECONDARY_CLICKED], 0); } static void default_secondary_clicked_handler (IdoScaleMenuItem * item) { g_debug ("%s: setting scale to upper bound", G_STRFUNC); IdoScaleMenuItemPrivate * priv = GET_PRIVATE (item); GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale)); gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj)); } /* ido_scale_menu_item_set_value: * * Sets the value of the scale inside @item to @value, without emitting * "value-changed". */ static void ido_scale_menu_item_set_value (IdoScaleMenuItem *item, gdouble value) { IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item); /* set ignore_value_changed to signify to the scale menu item that it * should not emit its own value-changed signal, as that should only * be emitted when the value is changed by the user. */ priv->ignore_value_changed = TRUE; gtk_range_set_value (GTK_RANGE (priv->scale), value); priv->ignore_value_changed = FALSE; } /** * ido_scale_menu_item_state_changed: * * Updates a IdoScaleMenuItem from @state. State must be a double which * contains the current value of the slider. */ static void ido_scale_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { GtkWidget *menuitem; menuitem = ido_action_helper_get_widget (helper); ido_scale_menu_item_set_value (IDO_SCALE_MENU_ITEM (menuitem), g_variant_get_double (state)); } static void ido_scale_menu_item_value_changed (GtkScale *scale, gdouble value, gpointer user_data) { IdoActionHelper *helper = user_data; ido_action_helper_change_action_state (helper, g_variant_new_double (value)); } static GIcon * menu_item_get_icon (GMenuItem *menuitem, const gchar *attribute) { GVariant *value; value = g_menu_item_get_attribute_value (menuitem, attribute, NULL); return value ? g_icon_deserialize (value) : NULL; } /** * ido_scale_menu_item_new_from_model: * * Creates a new #IdoScaleMenuItem. If @menuitem contains an action, it * will be bound to that action in @actions. * * Returns: (transfer full): a new #IdoScaleMenuItem */ GtkMenuItem * ido_scale_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions) { GtkWidget *item; gchar *action; gdouble min = 0.0; gdouble max = 100.0; gdouble step = 1.0; GIcon *min_icon; GIcon *max_icon; g_menu_item_get_attribute (menuitem, "min-value", "d", &min); g_menu_item_get_attribute (menuitem, "max-value", "d", &max); g_menu_item_get_attribute (menuitem, "step", "d", &step); item = ido_scale_menu_item_new_with_range ("Volume", IDO_RANGE_STYLE_DEFAULT, 0.0, min, max, step); ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (item), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) { IdoActionHelper *helper; helper = ido_action_helper_new (item, actions, action, NULL); g_signal_connect (helper, "action-state-changed", G_CALLBACK (ido_scale_menu_item_state_changed), NULL); g_signal_connect (item, "value-changed", G_CALLBACK (ido_scale_menu_item_value_changed), helper); g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper); g_free (action); } min_icon = menu_item_get_icon (menuitem, "min-icon"); max_icon = menu_item_get_icon (menuitem, "max-icon"); ido_scale_menu_item_set_icons (IDO_SCALE_MENU_ITEM (item), min_icon, max_icon); if (min_icon) g_object_unref (min_icon); if (max_icon) g_object_unref (max_icon); return GTK_MENU_ITEM (item); } #define __IDO_SCALE_MENU_ITEM_C__ ayatana-ido-0.4.2/src/idoscalemenuitem.h0000644000000000000000000001116713211262407015065 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #ifndef __IDO_SCALE_MENU_ITEM_H__ #define __IDO_SCALE_MENU_ITEM_H__ #include #include "idorange.h" G_BEGIN_DECLS #define IDO_TYPE_SCALE_MENU_ITEM (ido_scale_menu_item_get_type ()) #define IDO_SCALE_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItem)) #define IDO_SCALE_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemClass)) #define IDO_IS_SCALE_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_SCALE_MENU_ITEM)) #define IDO_IS_SCALE_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_SCALE_MENU_ITEM)) #define IDO_SCALE_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemClass)) typedef enum { IDO_SCALE_MENU_ITEM_STYLE_NONE, IDO_SCALE_MENU_ITEM_STYLE_IMAGE, IDO_SCALE_MENU_ITEM_STYLE_LABEL } IdoScaleMenuItemStyle; typedef struct _IdoScaleMenuItem IdoScaleMenuItem; typedef struct _IdoScaleMenuItemClass IdoScaleMenuItemClass; typedef struct _IdoScaleMenuItemPrivate IdoScaleMenuItemPrivate; struct _IdoScaleMenuItem { GtkMenuItem parent_instance; IdoScaleMenuItemPrivate *priv; }; struct _IdoScaleMenuItemClass { GtkMenuItemClass parent_class; /* signal default handlers */ void (*primary_clicked)(IdoScaleMenuItem * menuitem); void (*secondary_clicked)(IdoScaleMenuItem * menuitem); }; GType ido_scale_menu_item_get_type (void) G_GNUC_CONST; GtkWidget *ido_scale_menu_item_new (const gchar *label, IdoRangeStyle size, GtkAdjustment *adjustment); GtkWidget *ido_scale_menu_item_new_with_range (const gchar *label, IdoRangeStyle size, gdouble value, gdouble min, gdouble max, gdouble step); GtkWidget *ido_scale_menu_item_get_scale (IdoScaleMenuItem *menuitem); IdoScaleMenuItemStyle ido_scale_menu_item_get_style (IdoScaleMenuItem *menuitem); void ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem, IdoScaleMenuItemStyle style); GtkWidget *ido_scale_menu_item_get_primary_image (IdoScaleMenuItem *menuitem); GtkWidget *ido_scale_menu_item_get_secondary_image (IdoScaleMenuItem *menuitem); const gchar *ido_scale_menu_item_get_primary_label (IdoScaleMenuItem *menuitem); void ido_scale_menu_item_set_primary_label (IdoScaleMenuItem *menuitem, const gchar *label); const gchar *ido_scale_menu_item_get_secondary_label (IdoScaleMenuItem *menuitem); void ido_scale_menu_item_set_secondary_label (IdoScaleMenuItem *menuitem, const gchar *label); void ido_scale_menu_item_primary_clicked (IdoScaleMenuItem *menuitem); void ido_scale_menu_item_secondary_clicked (IdoScaleMenuItem *menuitem); GtkMenuItem * ido_scale_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions); G_END_DECLS #endif /* __IDO_SCALE_MENU_ITEM_H__ */ ayatana-ido-0.4.2/src/idosourcemenuitem.c0000644000000000000000000001642313211262407015271 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include "idosourcemenuitem.h" #include #include "idodetaillabel.h" #include "idoactionhelper.h" typedef GtkMenuItemClass IdoSourceMenuItemClass; struct _IdoSourceMenuItem { GtkMenuItem parent; GtkWidget *icon; GtkWidget *label; GtkWidget *detail; gint64 time; guint timer_id; }; G_DEFINE_TYPE (IdoSourceMenuItem, ido_source_menu_item, GTK_TYPE_MENU_ITEM); static void ido_source_menu_item_constructed (GObject *object) { IdoSourceMenuItem *item = IDO_SOURCE_MENU_ITEM (object); GtkWidget *grid; gint icon_width; gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL); item->icon = g_object_ref (gtk_image_new ()); gtk_widget_set_margin_left (item->icon, icon_width); gtk_widget_set_margin_right (item->icon, 6); item->label = g_object_ref (gtk_label_new ("")); gtk_label_set_max_width_chars (GTK_LABEL (item->label), 40); gtk_label_set_ellipsize (GTK_LABEL (item->label), PANGO_ELLIPSIZE_END); gtk_misc_set_alignment (GTK_MISC (item->label), 0.0, 0.5); item->detail = g_object_ref (ido_detail_label_new ("")); gtk_widget_set_halign (item->detail, GTK_ALIGN_END); gtk_widget_set_hexpand (item->detail, TRUE); gtk_style_context_add_class (gtk_widget_get_style_context (item->detail), "accelerator"); grid = gtk_grid_new (); gtk_grid_attach (GTK_GRID (grid), item->icon, 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), item->label, 1, 0, 1, 1); gtk_grid_attach (GTK_GRID (grid), item->detail, 2, 0, 1, 1); gtk_container_add (GTK_CONTAINER (object), grid); gtk_widget_show_all (grid); G_OBJECT_CLASS (ido_source_menu_item_parent_class)->constructed (object); } static gchar * ido_source_menu_item_time_span_string (gint64 timestamp) { gchar *str; gint64 span; gint hours; gint minutes; span = MAX (g_get_real_time () - timestamp, 0) / G_USEC_PER_SEC; hours = span / 3600; minutes = (span / 60) % 60; if (hours == 0) { /* TRANSLATORS: number of minutes that have passed */ str = g_strdup_printf (ngettext ("%d min", "%d min", minutes), minutes); } else { /* TRANSLATORS: number of hours that have passed */ str = g_strdup_printf (ngettext ("%d h", "%d h", hours), hours); } return str; } static void ido_source_menu_item_set_detail_time (IdoSourceMenuItem *self, gint64 time) { gchar *str; self->time = time; str = ido_source_menu_item_time_span_string (self->time); ido_detail_label_set_text (IDO_DETAIL_LABEL (self->detail), str); g_free (str); } static gboolean ido_source_menu_item_update_time (gpointer data) { IdoSourceMenuItem *self = data; ido_source_menu_item_set_detail_time (self, self->time); return TRUE; } static void ido_source_menu_item_dispose (GObject *object) { IdoSourceMenuItem *self = IDO_SOURCE_MENU_ITEM (object); if (self->timer_id != 0) { g_source_remove (self->timer_id); self->timer_id = 0; } g_clear_object (&self->icon); g_clear_object (&self->label); g_clear_object (&self->detail); G_OBJECT_CLASS (ido_source_menu_item_parent_class)->dispose (object); } static void ido_source_menu_item_class_init (IdoSourceMenuItemClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = ido_source_menu_item_constructed; object_class->dispose = ido_source_menu_item_dispose; } static void ido_source_menu_item_init (IdoSourceMenuItem *self) { } static void ido_source_menu_item_set_label (IdoSourceMenuItem *item, const gchar *label) { gtk_label_set_label (GTK_LABEL (item->label), label ? label : ""); } static void ido_source_menu_item_set_icon (IdoSourceMenuItem *item, GIcon *icon) { if (icon) gtk_image_set_from_gicon (GTK_IMAGE (item->icon), icon, GTK_ICON_SIZE_MENU); else gtk_image_clear (GTK_IMAGE (item->icon)); } static void ido_source_menu_item_activate (GtkMenuItem *item, gpointer user_data) { IdoActionHelper *helper = user_data; /* The parameter signifies whether this source was activated (TRUE) or * dismissed (FALSE). Since there's no UI to dismiss a gtkmenuitem, * this always passes TRUE. */ ido_action_helper_activate_with_parameter (helper, g_variant_new_boolean (TRUE)); } static void ido_source_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { IdoSourceMenuItem *item = user_data; guint32 count; gint64 time; const gchar *str; if (item->timer_id != 0) { g_source_remove (item->timer_id); item->timer_id = 0; } g_return_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)"))); g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); if (count != 0) ido_detail_label_set_count (IDO_DETAIL_LABEL (item->detail), count); else if (time != 0) { ido_source_menu_item_set_detail_time (item, time); item->timer_id = g_timeout_add_seconds (59, ido_source_menu_item_update_time, item); } else if (str != NULL && *str) ido_detail_label_set_text (IDO_DETAIL_LABEL (item->detail), str); } GtkMenuItem * ido_source_menu_item_new_from_menu_model (GMenuItem *menuitem, GActionGroup *actions) { GtkMenuItem *item; GVariant *serialized_icon; GIcon *icon = NULL; gchar *label; gchar *action = NULL; item = g_object_new (IDO_TYPE_SOURCE_MENU_ITEM, NULL); if (g_menu_item_get_attribute (menuitem, "label", "s", &label)) { ido_source_menu_item_set_label (IDO_SOURCE_MENU_ITEM (item), label); g_free (label); } serialized_icon = g_menu_item_get_attribute_value (menuitem, "icon", NULL); if (serialized_icon) { icon = g_icon_deserialize (serialized_icon); g_variant_unref (serialized_icon); } ido_source_menu_item_set_icon (IDO_SOURCE_MENU_ITEM (item), icon); if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) { IdoActionHelper *helper; helper = ido_action_helper_new (GTK_WIDGET (item), actions, action, NULL); g_signal_connect (helper, "action-state-changed", G_CALLBACK (ido_source_menu_item_state_changed), item); g_signal_connect_object (item, "activate", G_CALLBACK (ido_source_menu_item_activate), helper, 0); g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper); g_free (action); } if (icon) g_object_unref (icon); return item; } ayatana-ido-0.4.2/src/idosourcemenuitem.h0000644000000000000000000000265013211262407015273 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #ifndef __IDO_SOURCE_MENU_ITEM_H__ #define __IDO_SOURCE_MENU_ITEM_H__ #include #define IDO_TYPE_SOURCE_MENU_ITEM (ido_source_menu_item_get_type ()) #define IDO_SOURCE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_SOURCE_MENU_ITEM, IdoSourceMenuItem)) #define IDO_IS_SOURCE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_SOURCE_MENU_ITEM)) typedef struct _IdoSourceMenuItem IdoSourceMenuItem; GType ido_source_menu_item_get_type (void); GtkMenuItem * ido_source_menu_item_new_from_menu_model (GMenuItem *menuitem, GActionGroup *actions); #endif ayatana-ido-0.4.2/src/idoswitchmenuitem.c0000644000000000000000000001707513211262407015276 0ustar /* * A GtkCheckMenuItem that uses a GtkSwitch to show its 'active' property * * Copyright © 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Author: Charles Kerr */ #include "config.h" #include "idoswitchmenuitem.h" #include "idoactionhelper.h" static gboolean ido_switch_menu_button_release_event (GtkWidget * widget, GdkEventButton * event); struct _IdoSwitchMenuItemPrivate { GtkWidget * box; GtkWidget * content_area; GtkWidget * label; GtkWidget * image; GtkWidget * switch_w; }; /*** **** Life Cycle ***/ G_DEFINE_TYPE (IdoSwitchMenuItem, ido_switch_menu_item, GTK_TYPE_CHECK_MENU_ITEM) static void ido_switch_menu_item_class_init (IdoSwitchMenuItemClass *klass) { GObjectClass * gobject_class; GtkWidgetClass * widget_class; GtkCheckMenuItemClass * check_class; gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (gobject_class, sizeof (IdoSwitchMenuItemPrivate)); widget_class = GTK_WIDGET_CLASS (klass); widget_class->button_release_event = ido_switch_menu_button_release_event; check_class = GTK_CHECK_MENU_ITEM_CLASS (klass); check_class->draw_indicator = NULL; } static void ido_switch_menu_item_init (IdoSwitchMenuItem *item) { IdoSwitchMenuItemPrivate *priv; priv = item->priv = G_TYPE_INSTANCE_GET_PRIVATE (item, IDO_TYPE_SWITCH_MENU_ITEM, IdoSwitchMenuItemPrivate); priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); priv->content_area = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); priv->switch_w = gtk_switch_new (); gtk_box_pack_start (GTK_BOX (priv->box), priv->content_area, TRUE, TRUE, 0); gtk_box_pack_end (GTK_BOX (priv->box), priv->switch_w, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (item), priv->box); gtk_widget_show_all (priv->box); g_object_bind_property (item, "active", priv->switch_w, "active", G_BINDING_SYNC_CREATE); } /*** **** Don't popdown the menu immediately after clicking on a switch... **** wait a moment so the user can see the GtkSwitch be toggled. ***/ static gboolean popdown_later_cb (gpointer widget) { GtkWidget * parent = gtk_widget_get_parent (widget); if (GTK_IS_MENU (parent)) { gtk_menu_shell_deactivate (GTK_MENU_SHELL(parent)); } g_object_unref (widget); return FALSE; /* only call this cb once */ } static gboolean ido_switch_menu_button_release_event (GtkWidget * widget, GdkEventButton * event) { gtk_menu_item_activate (GTK_MENU_ITEM(widget)); g_timeout_add (500, popdown_later_cb, g_object_ref(widget)); return TRUE; /* stop the event so that it doesn't trigger popdown() */ } /** * ido_switch_menu_item_new: * * Creates a new #IdoSwitchMenuItem * * Return Value: a new #IdoSwitchMenuItem. **/ GtkWidget * ido_switch_menu_item_new (void) { return g_object_new (IDO_TYPE_SWITCH_MENU_ITEM, NULL); } /** * ido_switch_menu_item_get_content_area: * @item: The #IdoSwitchMenuItem. * * Get the #GtkContainer to add additional widgets into. * * This function is dperecated. * * Return Value: (transfer none): The #GtkContainer to add additional widgets into. **/ GtkContainer * ido_switch_menu_item_get_content_area (IdoSwitchMenuItem * item) { static gboolean warned = FALSE; g_return_val_if_fail (IDO_IS_SWITCH_MENU_ITEM(item), NULL); if (!warned) { g_warning ("%s is deprecated. Please don't use it, especially if you're using" "ido_switch_menu_set_{label,icon}()", G_STRFUNC); warned = TRUE; } return GTK_CONTAINER (item->priv->content_area); } /** * ido_switch_menu_item_set_label: * @item: a #IdoSwitchMenuItem. * @label: a string to set as the label of @item * * Set the label of @item to @label. **/ void ido_switch_menu_item_set_label (IdoSwitchMenuItem *item, const gchar *label) { IdoSwitchMenuItemPrivate *priv; g_return_if_fail (IDO_IS_SWITCH_MENU_ITEM (item)); g_return_if_fail (label != NULL); priv = item->priv; if (priv->label == NULL) { priv->label = gtk_label_new (NULL); gtk_widget_set_halign (priv->label, GTK_ALIGN_START); gtk_widget_show (priv->label); gtk_box_pack_end (GTK_BOX (priv->content_area), priv->label, TRUE, TRUE, 0); } gtk_label_set_text (GTK_LABEL (priv->label), label); } /** * ido_switch_menu_item_set_icon: * @item: a #IdoSwitchMenuItem. * @icon: (allow-none): a #GIcon * * Set the icon of @item to @icon. **/ void ido_switch_menu_item_set_icon (IdoSwitchMenuItem *item, GIcon *icon) { IdoSwitchMenuItemPrivate *priv; g_return_if_fail (IDO_IS_SWITCH_MENU_ITEM (item)); g_return_if_fail (icon == NULL || G_IS_ICON (icon)); priv = item->priv; if (icon) { if (priv->image == NULL) { priv->image = gtk_image_new (); gtk_widget_show (priv->image); gtk_box_pack_start (GTK_BOX (priv->content_area), priv->image, FALSE, FALSE, 0); } gtk_image_set_from_gicon (GTK_IMAGE (priv->image), icon, GTK_ICON_SIZE_MENU); } else if (priv->image) { gtk_image_clear (GTK_IMAGE (priv->image)); } } static void ido_source_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { IdoSwitchMenuItem *item = user_data; if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN)) gtk_switch_set_active (GTK_SWITCH (item->priv->switch_w), g_variant_get_boolean (state)); } GtkMenuItem * ido_switch_menu_item_new_from_menu_model (GMenuItem *menuitem, GActionGroup *actions) { GtkMenuItem *item; gchar *label; GVariant *serialized_icon; gchar *action = NULL; item = g_object_new (IDO_TYPE_SWITCH_MENU_ITEM, NULL); if (g_menu_item_get_attribute (menuitem, "label", "s", &label)) { ido_switch_menu_item_set_label (IDO_SWITCH_MENU_ITEM (item), label); g_free (label); } serialized_icon = g_menu_item_get_attribute_value (menuitem, "icon", NULL); if (serialized_icon) { GIcon *icon; icon = g_icon_deserialize (serialized_icon); if (icon) { ido_switch_menu_item_set_icon (IDO_SWITCH_MENU_ITEM (item), icon); g_object_unref (icon); } g_variant_unref (serialized_icon); } if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) { IdoActionHelper *helper; helper = ido_action_helper_new (GTK_WIDGET (item), actions, action, NULL); g_signal_connect (helper, "action-state-changed", G_CALLBACK (ido_source_menu_item_state_changed), item); g_signal_connect_object (item, "activate", G_CALLBACK (ido_action_helper_activate), helper, G_CONNECT_SWAPPED); g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper); g_free (action); } return item; } ayatana-ido-0.4.2/src/idoswitchmenuitem.h0000644000000000000000000000516013211262407015273 0ustar /* * A GtkCheckMenuItem that uses a GtkSwitch to show its 'active' property. * * Copyright © 2012 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Author: Charles Kerr */ #ifndef __IDO_SWITCH_MENU_ITEM_H__ #define __IDO_SWITCH_MENU_ITEM_H__ #include G_BEGIN_DECLS #define IDO_TYPE_SWITCH_MENU_ITEM (ido_switch_menu_item_get_type ()) #define IDO_SWITCH_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_SWITCH_MENU_ITEM, IdoSwitchMenuItem)) #define IDO_SWITCH_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_SWITCH_MENU_ITEM, IdoSwitchMenuItemClass)) #define IDO_IS_SWITCH_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_SWITCH_MENU_ITEM)) #define IDO_IS_SWITCH_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_SWITCH_MENU_ITEM)) #define IDO_SWITCH_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_SWITCH_MENU_ITEM, IdoSwitchMenuItemClass)) typedef struct _IdoSwitchMenuItem IdoSwitchMenuItem; typedef struct _IdoSwitchMenuItemClass IdoSwitchMenuItemClass; typedef struct _IdoSwitchMenuItemPrivate IdoSwitchMenuItemPrivate; struct _IdoSwitchMenuItem { GtkCheckMenuItem parent_instance; IdoSwitchMenuItemPrivate *priv; }; struct _IdoSwitchMenuItemClass { GtkCheckMenuItemClass parent_class; }; GType ido_switch_menu_item_get_type (void) G_GNUC_CONST; GtkWidget *ido_switch_menu_item_new (void); GtkContainer *ido_switch_menu_item_get_content_area (IdoSwitchMenuItem * item); GtkMenuItem * ido_switch_menu_item_new_from_menu_model (GMenuItem *menuitem, GActionGroup *actions); void ido_switch_menu_item_set_label (IdoSwitchMenuItem *item, const gchar *label); void ido_switch_menu_item_set_icon (IdoSwitchMenuItem *item, GIcon *icon); G_END_DECLS #endif /* __IDO_SWITCH_MENU_ITEM_H__ */ ayatana-ido-0.4.2/src/idotimeline.c0000644000000000000000000004677413211262407014047 0ustar /* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */ /* gtktimeline.c * * Copyright (C) 2007 Carlos Garnacho * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "idotimeline.h" #include "idotypebuiltins.h" #include #include #define IDO_TIMELINE_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), IDO_TYPE_TIMELINE, IdoTimelinePriv)) #define MSECS_PER_SEC 1000 #define FRAME_INTERVAL(nframes) (MSECS_PER_SEC / nframes) #define DEFAULT_FPS 30 typedef struct IdoTimelinePriv IdoTimelinePriv; struct IdoTimelinePriv { guint duration; guint fps; guint source_id; GTimer *timer; gdouble progress; gdouble last_progress; GdkScreen *screen; guint animations_enabled : 1; guint loop : 1; guint direction : 1; }; enum { PROP_0, PROP_FPS, PROP_DURATION, PROP_LOOP, PROP_DIRECTION, PROP_SCREEN }; enum { STARTED, PAUSED, FINISHED, FRAME, LAST_SIGNAL }; static guint signals [LAST_SIGNAL] = { 0, }; static void ido_timeline_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void ido_timeline_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void ido_timeline_finalize (GObject *object); G_DEFINE_TYPE (IdoTimeline, ido_timeline, G_TYPE_OBJECT) static void ido_timeline_class_init (IdoTimelineClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = ido_timeline_set_property; object_class->get_property = ido_timeline_get_property; object_class->finalize = ido_timeline_finalize; g_object_class_install_property (object_class, PROP_FPS, g_param_spec_uint ("fps", "FPS", "Frames per second for the timeline", 1, G_MAXUINT, DEFAULT_FPS, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_DURATION, g_param_spec_uint ("duration", "Animation Duration", "Animation Duration", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOOP, g_param_spec_boolean ("loop", "Loop", "Whether the timeline loops or not", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_DIRECTION, g_param_spec_enum ("direction", "Direction", "Whether the timeline moves forward or backward in time", IDO_TYPE_TIMELINE_DIRECTION, IDO_TIMELINE_DIRECTION_FORWARD, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_SCREEN, g_param_spec_object ("screen", "Screen", "Screen to get the settings from", GDK_TYPE_SCREEN, G_PARAM_READWRITE)); /** * IdoTimeline::started: * @timeline: The #IdoTimeline emitting the signal. * * The ::started signal is emitted when the timeline starts. */ signals[STARTED] = g_signal_new ("started", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IdoTimelineClass, started), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * IdoTimeline::paused: * @timeline: The #IdoTimeline emitting the signal. * * The ::paused signal is emitted when the timeline pauses. */ signals[PAUSED] = g_signal_new ("paused", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IdoTimelineClass, paused), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * IdoTimeline::finished: * @timeline: The #IdoTimeline emitting the signal. * * The ::paused signal is emitted when the timeline finishes. */ signals[FINISHED] = g_signal_new ("finished", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IdoTimelineClass, finished), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * IdoTimeline::frame: * @timeline: The #IdoTimeline emitting the signal. * @progress: The progress position for this frame from 0.0 (start) to 1.0 (end). * * The ::frame signal is emitted when a frame should be drawn. */ signals[FRAME] = g_signal_new ("frame", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IdoTimelineClass, frame), NULL, NULL, g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE); g_type_class_add_private (klass, sizeof (IdoTimelinePriv)); } static void ido_timeline_init (IdoTimeline *timeline) { IdoTimelinePriv *priv; priv = IDO_TIMELINE_GET_PRIV (timeline); priv->fps = DEFAULT_FPS; priv->duration = 0.0; priv->direction = IDO_TIMELINE_DIRECTION_FORWARD; priv->screen = gdk_screen_get_default (); priv->last_progress = 0; } static void ido_timeline_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { IdoTimeline *timeline; timeline = IDO_TIMELINE (object); switch (prop_id) { case PROP_FPS: ido_timeline_set_fps (timeline, g_value_get_uint (value)); break; case PROP_DURATION: ido_timeline_set_duration (timeline, g_value_get_uint (value)); break; case PROP_LOOP: ido_timeline_set_loop (timeline, g_value_get_boolean (value)); break; case PROP_DIRECTION: ido_timeline_set_direction (timeline, g_value_get_enum (value)); break; case PROP_SCREEN: ido_timeline_set_screen (timeline, (GdkScreen*)g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void ido_timeline_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { IdoTimeline *timeline; IdoTimelinePriv *priv; timeline = IDO_TIMELINE (object); priv = IDO_TIMELINE_GET_PRIV (timeline); switch (prop_id) { case PROP_FPS: g_value_set_uint (value, priv->fps); break; case PROP_DURATION: g_value_set_uint (value, priv->duration); break; case PROP_LOOP: g_value_set_boolean (value, priv->loop); break; case PROP_DIRECTION: g_value_set_enum (value, priv->direction); break; case PROP_SCREEN: g_value_set_object (value, priv->screen); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void ido_timeline_finalize (GObject *object) { IdoTimelinePriv *priv; priv = IDO_TIMELINE_GET_PRIV (object); if (priv->source_id) { g_source_remove (priv->source_id); priv->source_id = 0; } if (priv->timer) g_timer_destroy (priv->timer); G_OBJECT_CLASS (ido_timeline_parent_class)->finalize (object); } static gboolean ido_timeline_run_frame (IdoTimeline *timeline) { IdoTimelinePriv *priv; gdouble delta_progress, progress; guint elapsed_time; priv = IDO_TIMELINE_GET_PRIV (timeline); elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000); g_timer_start (priv->timer); if (priv->animations_enabled) { delta_progress = (gdouble) elapsed_time / priv->duration; progress = priv->last_progress; if (priv->direction == IDO_TIMELINE_DIRECTION_BACKWARD) progress -= delta_progress; else progress += delta_progress; priv->last_progress = progress; progress = CLAMP (progress, 0., 1.); } else progress = (priv->direction == IDO_TIMELINE_DIRECTION_FORWARD) ? 1.0 : 0.0; priv->progress = progress; g_signal_emit (timeline, signals [FRAME], 0, progress); if ((priv->direction == IDO_TIMELINE_DIRECTION_FORWARD && progress == 1.0) || (priv->direction == IDO_TIMELINE_DIRECTION_BACKWARD && progress == 0.0)) { if (!priv->loop) { if (priv->source_id) { g_source_remove (priv->source_id); priv->source_id = 0; } g_timer_stop (priv->timer); g_signal_emit (timeline, signals [FINISHED], 0); return FALSE; } else ido_timeline_rewind (timeline); } return TRUE; } /** * ido_timeline_new: * @duration: duration in milliseconds for the timeline * * Creates a new #IdoTimeline with the specified number of frames. * * Return Value: the newly created #IdoTimeline **/ IdoTimeline * ido_timeline_new (guint duration) { return g_object_new (IDO_TYPE_TIMELINE, "duration", duration, NULL); } /** * ido_timeline_new_for_screen: * @duration: duration in milliseconds for the timeline * @screen: Screen to start on. * * Creates a new #IdoTimeline with the specified number of frames on the given screen. * * Return Value: the newly created #IdoTimeline **/ IdoTimeline * ido_timeline_new_for_screen (guint duration, GdkScreen *screen) { return g_object_new (IDO_TYPE_TIMELINE, "duration", duration, "screen", screen, NULL); } /** * ido_timeline_start: * @timeline: A #IdoTimeline * * Runs the timeline from the current frame. **/ void ido_timeline_start (IdoTimeline *timeline) { IdoTimelinePriv *priv; gboolean enable_animations = FALSE; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (!priv->source_id) { if (priv->timer) g_timer_continue (priv->timer); else priv->timer = g_timer_new (); /* sanity check; CID: 12651 */ priv->fps = priv->fps > 0 ? priv->fps : DEFAULT_FPS; if (priv->screen) { #if 0 GtkSettings *settings = gtk_settings_get_for_screen (priv->screen); g_object_get (settings, "ido-enable-animations", &enable_animations, NULL); #else // XXX enable_animations = TRUE; #endif } priv->animations_enabled = (enable_animations == TRUE); g_signal_emit (timeline, signals [STARTED], 0); if (enable_animations) priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps), (GSourceFunc) ido_timeline_run_frame, timeline); else priv->source_id = gdk_threads_add_idle ((GSourceFunc) ido_timeline_run_frame, timeline); } } /** * ido_timeline_pause: * @timeline: A #IdoTimeline * * Pauses the timeline. **/ void ido_timeline_pause (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (priv->source_id) { g_timer_stop (priv->timer); g_source_remove (priv->source_id); priv->source_id = 0; g_signal_emit (timeline, signals [PAUSED], 0); } } /** * ido_timeline_rewind: * @timeline: A #IdoTimeline * * Rewinds the timeline. **/ void ido_timeline_rewind (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (ido_timeline_get_direction(timeline) != IDO_TIMELINE_DIRECTION_FORWARD) priv->progress = priv->last_progress = 1.; else priv->progress = priv->last_progress = 0.; /* reset timer */ if (priv->timer) { g_timer_start (priv->timer); if (!priv->source_id) g_timer_stop (priv->timer); } } /** * ido_timeline_is_running: * @timeline: A #IdoTimeline * * Returns whether the timeline is running or not. * * Return Value: %TRUE if the timeline is running **/ gboolean ido_timeline_is_running (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), FALSE); priv = IDO_TIMELINE_GET_PRIV (timeline); return (priv->source_id != 0); } /** * ido_timeline_get_fps: * @timeline: A #IdoTimeline * * Returns the number of frames per second. * * Return Value: frames per second **/ guint ido_timeline_get_fps (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), 1); priv = IDO_TIMELINE_GET_PRIV (timeline); return priv->fps; } /** * ido_timeline_set_fps: * @timeline: A #IdoTimeline * @fps: frames per second * * Sets the number of frames per second that * the timeline will play. **/ void ido_timeline_set_fps (IdoTimeline *timeline, guint fps) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); g_return_if_fail (fps > 0); priv = IDO_TIMELINE_GET_PRIV (timeline); /* Coverity CID: 12650/12651: guard against division by 0. */ priv->fps = fps > 0 ? fps : priv->fps; if (ido_timeline_is_running (timeline)) { g_source_remove (priv->source_id); priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps), (GSourceFunc) ido_timeline_run_frame, timeline); } g_object_notify (G_OBJECT (timeline), "fps"); } /** * ido_timeline_get_loop: * @timeline: A #IdoTimeline * * Returns whether the timeline loops to the * beginning when it has reached the end. * * Return Value: %TRUE if the timeline loops **/ gboolean ido_timeline_get_loop (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), FALSE); priv = IDO_TIMELINE_GET_PRIV (timeline); return priv->loop; } /** * ido_timeline_set_loop: * @timeline: A #IdoTimeline * @loop: %TRUE to make the timeline loop * * Sets whether the timeline loops to the beginning * when it has reached the end. **/ void ido_timeline_set_loop (IdoTimeline *timeline, gboolean loop) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (loop != priv->loop) { priv->loop = loop; g_object_notify (G_OBJECT (timeline), "loop"); } } /** * ido_timeline_set_duration: * @timeline: A #IdoTimeline * @duration: Duration in milliseconds. * * Set the animation duration. */ void ido_timeline_set_duration (IdoTimeline *timeline, guint duration) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (duration != priv->duration) { priv->duration = duration; g_object_notify (G_OBJECT (timeline), "duration"); } } /** * ido_timeline_get_duration: * @timeline: A #IdoTimeline * * Set the animation duration. * * Return Value: Duration in milliseconds. */ guint ido_timeline_get_duration (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), 0); priv = IDO_TIMELINE_GET_PRIV (timeline); return priv->duration; } /** * ido_timeline_set_direction: * @timeline: A #IdoTimeline * @direction: direction * * Sets the direction of the timeline. **/ void ido_timeline_set_direction (IdoTimeline *timeline, IdoTimelineDirection direction) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (direction != priv->direction) { priv->direction = direction; g_object_notify (G_OBJECT (timeline), "direction"); } } /** * ido_timeline_get_direction: * @timeline: A #IdoTimeline * * Returns the direction of the timeline. * * Return Value: direction **/ IdoTimelineDirection ido_timeline_get_direction (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), IDO_TIMELINE_DIRECTION_FORWARD); priv = IDO_TIMELINE_GET_PRIV (timeline); return priv->direction; } /** * ido_timeline_set_screen: * @timeline: A #IdoTimeline * @screen: A #GdkScreen to use * * Set the screen the timeline is running on. */ void ido_timeline_set_screen (IdoTimeline *timeline, GdkScreen *screen) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); g_return_if_fail (GDK_IS_SCREEN (screen)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (priv->screen) g_object_unref (priv->screen); priv->screen = g_object_ref (screen); g_object_notify (G_OBJECT (timeline), "screen"); } /** * ido_timeline_get_screen: * @timeline: A #IdoTimeline * * Get the screen this timeline is running on. * * Return Value: (transfer none): The #GdkScreen this timeline is running on. */ GdkScreen * ido_timeline_get_screen (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), NULL); priv = IDO_TIMELINE_GET_PRIV (timeline); return priv->screen; } /** * ido_timeline_get_progress: * @timeline: A #IdoTimeline * * Get the progress on the timeline. * * Return Value: The progress from 0.0 (start) to 1.0 (end) */ gdouble ido_timeline_get_progress (IdoTimeline *timeline) { IdoTimelinePriv *priv; g_return_val_if_fail (IDO_IS_TIMELINE (timeline), 0.); priv = IDO_TIMELINE_GET_PRIV (timeline); return priv->progress; } /** * ido_timeline_set_progress: * @timeline: A #IdoTimeline * @progress: The progress from 0.0 (start) to 1.0 (end) * * Set the progress on the timeline. */ void ido_timeline_set_progress (IdoTimeline *timeline, gdouble progress) { IdoTimelinePriv *priv; g_return_if_fail (IDO_IS_TIMELINE (timeline)); priv = IDO_TIMELINE_GET_PRIV (timeline); if (priv->source_id) { g_timer_stop (priv->timer); g_source_remove (priv->source_id); priv->source_id = 0; } priv->progress = priv->last_progress = progress; ido_timeline_start (timeline); } /** * ido_timeline_calculate_progress: * @linear_progress: The progress from 0.0 (start) to 1.0 (end) * @progress_type: The progress transform to apply * * Transform a linear progress position using the given transform. * * Return Value: the progress position using the provided transform. */ gdouble ido_timeline_calculate_progress (gdouble linear_progress, IdoTimelineProgressType progress_type) { gdouble progress; progress = linear_progress; switch (progress_type) { case IDO_TIMELINE_PROGRESS_LINEAR: break; case IDO_TIMELINE_PROGRESS_SINUSOIDAL: progress = sinf ((progress * G_PI) / 2); break; case IDO_TIMELINE_PROGRESS_EXPONENTIAL: progress *= progress; break; case IDO_TIMELINE_PROGRESS_EASE_IN_EASE_OUT: { progress *= 2; if (progress < 1) progress = pow (progress, 3) / 2; else progress = (pow (progress - 2, 3) + 2) / 2; } } return progress; } ayatana-ido-0.4.2/src/idotimeline.h0000644000000000000000000001163713211262407014042 0ustar /* * Copyright (C) 2007 Carlos Garnacho * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __IDO_TIMELINE_H__ #define __IDO_TIMELINE_H__ #include #include #include G_BEGIN_DECLS #define IDO_TYPE_TIMELINE (ido_timeline_get_type ()) #define IDO_TIMELINE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_TIMELINE, IdoTimeline)) #define IDO_TIMELINE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), IDO_TYPE_TIMELINE, IdoTimelineClass)) #define IDO_IS_TIMELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_TIMELINE)) #define IDO_IS_TIMELINE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IDO_TYPE_TIMELINE)) #define IDO_TIMELINE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_TIMELINE, IdoTimelineClass)) typedef struct IdoTimeline IdoTimeline; typedef struct IdoTimelineClass IdoTimelineClass; typedef enum { IDO_TIMELINE_DIRECTION_FORWARD, IDO_TIMELINE_DIRECTION_BACKWARD } IdoTimelineDirection; typedef enum { IDO_TIMELINE_PROGRESS_LINEAR, IDO_TIMELINE_PROGRESS_SINUSOIDAL, IDO_TIMELINE_PROGRESS_EXPONENTIAL, IDO_TIMELINE_PROGRESS_EASE_IN_EASE_OUT } IdoTimelineProgressType; struct IdoTimeline { GObject parent_instance; }; struct IdoTimelineClass { GObjectClass parent_class; void (* started) (IdoTimeline *timeline); void (* finished) (IdoTimeline *timeline); void (* paused) (IdoTimeline *timeline); void (* frame) (IdoTimeline *timeline, gdouble progress); void (* __ido_reserved1) (void); void (* __ido_reserved2) (void); void (* __ido_reserved3) (void); void (* __ido_reserved4) (void); }; GType ido_timeline_get_type (void) G_GNUC_CONST; IdoTimeline *ido_timeline_new (guint duration); IdoTimeline *ido_timeline_new_for_screen (guint duration, GdkScreen *screen); void ido_timeline_start (IdoTimeline *timeline); void ido_timeline_pause (IdoTimeline *timeline); void ido_timeline_rewind (IdoTimeline *timeline); gboolean ido_timeline_is_running (IdoTimeline *timeline); guint ido_timeline_get_fps (IdoTimeline *timeline); void ido_timeline_set_fps (IdoTimeline *timeline, guint fps); gboolean ido_timeline_get_loop (IdoTimeline *timeline); void ido_timeline_set_loop (IdoTimeline *timeline, gboolean loop); guint ido_timeline_get_duration (IdoTimeline *timeline); void ido_timeline_set_duration (IdoTimeline *timeline, guint duration); GdkScreen *ido_timeline_get_screen (IdoTimeline *timeline); void ido_timeline_set_screen (IdoTimeline *timeline, GdkScreen *screen); IdoTimelineDirection ido_timeline_get_direction (IdoTimeline *timeline); void ido_timeline_set_direction (IdoTimeline *timeline, IdoTimelineDirection direction); gdouble ido_timeline_get_progress (IdoTimeline *timeline); void ido_timeline_set_progress (IdoTimeline *timeline, gdouble progress); gdouble ido_timeline_calculate_progress (gdouble linear_progress, IdoTimelineProgressType progress_type); G_END_DECLS #endif /* __IDO_TIMELINE_H__ */ ayatana-ido-0.4.2/src/idotimestampmenuitem.c0000644000000000000000000001410213211262407015764 0ustar /* * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * Ted Gould * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* strstr() */ #include #include "idoactionhelper.h" #include "idotimestampmenuitem.h" enum { PROP_0, PROP_FORMAT, PROP_DATE_TIME, PROP_LAST }; static GParamSpec *properties[PROP_LAST]; struct _IdoTimeStampMenuItemPrivate { char * format; GDateTime * date_time; }; typedef IdoTimeStampMenuItemPrivate priv_t; G_DEFINE_TYPE (IdoTimeStampMenuItem, ido_time_stamp_menu_item, IDO_TYPE_BASIC_MENU_ITEM); /*** **** GObject Virtual Functions ***/ static void my_get_property (GObject * o, guint property_id, GValue * v, GParamSpec * pspec) { IdoTimeStampMenuItem * self = IDO_TIME_STAMP_MENU_ITEM (o); priv_t * p = self->priv; switch (property_id) { case PROP_FORMAT: g_value_set_string (v, p->format); break; case PROP_DATE_TIME: g_value_set_boxed (v, p->date_time); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_set_property (GObject * o, guint property_id, const GValue * v, GParamSpec * pspec) { IdoTimeStampMenuItem * self = IDO_TIME_STAMP_MENU_ITEM (o); switch (property_id) { case PROP_FORMAT: ido_time_stamp_menu_item_set_format (self, g_value_get_string (v)); break; case PROP_DATE_TIME: ido_time_stamp_menu_item_set_date_time (self, g_value_get_boxed (v)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_dispose (GObject * object) { IdoTimeStampMenuItem * self = IDO_TIME_STAMP_MENU_ITEM (object); priv_t * p = self->priv; g_clear_pointer (&p->date_time, g_date_time_unref); G_OBJECT_CLASS (ido_time_stamp_menu_item_parent_class)->dispose (object); } static void my_finalize (GObject * object) { IdoTimeStampMenuItem * self = IDO_TIME_STAMP_MENU_ITEM (object); priv_t * p = self->priv; g_free (p->format); G_OBJECT_CLASS (ido_time_stamp_menu_item_parent_class)->finalize (object); } /*** **** Instantiation ***/ static void ido_time_stamp_menu_item_class_init (IdoTimeStampMenuItemClass *klass) { GParamFlags prop_flags; GObjectClass * gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (IdoTimeStampMenuItemPrivate)); gobject_class->get_property = my_get_property; gobject_class->set_property = my_set_property; gobject_class->dispose = my_dispose; gobject_class->finalize = my_finalize; prop_flags = G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS; properties[PROP_FORMAT] = g_param_spec_string ( "format", "strftime format", "strftime-style format string for the timestamp", "%F %T", prop_flags); properties[PROP_DATE_TIME] = g_param_spec_boxed ( "date-time", "Date-Time", "GDateTime specifying the time to render", G_TYPE_DATE_TIME, prop_flags); g_object_class_install_properties (gobject_class, PROP_LAST, properties); } static void ido_time_stamp_menu_item_init (IdoTimeStampMenuItem *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, IDO_TYPE_TIME_STAMP_MENU_ITEM, IdoTimeStampMenuItemPrivate); } static void update_timestamp_label (IdoTimeStampMenuItem * self) { char * str; priv_t * p = self->priv; if (p->date_time && p->format) str = g_date_time_format (p->date_time, p->format); else str = NULL; ido_basic_menu_item_set_secondary_text (IDO_BASIC_MENU_ITEM (self), str); g_free (str); } /*** **** Public API ***/ /* create a new IdoTimeStampMenuItem */ GtkWidget * ido_time_stamp_menu_item_new (void) { return GTK_WIDGET (g_object_new (IDO_TYPE_TIME_STAMP_MENU_ITEM, NULL)); } /** * ido_time_stamp_menu_item_set_time: * @time: the time to be rendered in the appointment's timestamp label. * * Set the time that will be displayed in the menuitem's * right-justified timestamp label */ void ido_time_stamp_menu_item_set_date_time (IdoTimeStampMenuItem * self, GDateTime * date_time) { priv_t * p; g_return_if_fail (IDO_IS_TIME_STAMP_MENU_ITEM (self)); p = self->priv; g_clear_pointer (&p->date_time, g_date_time_unref); if (date_time != NULL) p->date_time = g_date_time_ref (date_time); update_timestamp_label (self); } /** * ido_time_stamp_menu_item_set_format: * @format: the format string used when showing the appointment's time * * Set the format string for rendering the appointment's time * in its right-justified secondary label. * * See strfrtime(3) for more information on the format string. */ void ido_time_stamp_menu_item_set_format (IdoTimeStampMenuItem * self, const char * strftime_fmt) { priv_t * p; g_return_if_fail (IDO_IS_TIME_STAMP_MENU_ITEM (self)); p = self->priv; g_free (p->format); p->format = g_strdup (strftime_fmt); update_timestamp_label (self); } const gchar * ido_time_stamp_menu_item_get_format (IdoTimeStampMenuItem * self) { g_return_val_if_fail (IDO_IS_TIME_STAMP_MENU_ITEM (self), NULL); return self->priv->format; } ayatana-ido-0.4.2/src/idotimestampmenuitem.h0000644000000000000000000000461313211262407015777 0ustar /** * Copyright 2013 Canonical Ltd. * * Authors: * Charles Kerr * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef __IDO_TIME_STAMP_MENU_ITEM_H__ #define __IDO_TIME_STAMP_MENU_ITEM_H__ #include #include "idobasicmenuitem.h" G_BEGIN_DECLS #define IDO_TYPE_TIME_STAMP_MENU_ITEM (ido_time_stamp_menu_item_get_type ()) #define IDO_TIME_STAMP_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_TIME_STAMP_MENU_ITEM, IdoTimeStampMenuItem)) #define IDO_IS_TIME_STAMP_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_TIME_STAMP_MENU_ITEM)) typedef struct _IdoTimeStampMenuItem IdoTimeStampMenuItem; typedef struct _IdoTimeStampMenuItemClass IdoTimeStampMenuItemClass; typedef struct _IdoTimeStampMenuItemPrivate IdoTimeStampMenuItemPrivate; struct _IdoTimeStampMenuItemClass { IdoBasicMenuItemClass parent_class; }; /** * A menuitem that contains a left-aligned optional icon and label * and a right-aligned secondary label showing the specified time * in the specified format. * * Used by IdoLocationMenuItem, IdoAppointmentMenuItem, and IdoAlarmMenuItem. */ struct _IdoTimeStampMenuItem { /*< private >*/ IdoBasicMenuItem parent; IdoTimeStampMenuItemPrivate * priv; }; GType ido_time_stamp_menu_item_get_type (void) G_GNUC_CONST; GtkWidget * ido_time_stamp_menu_item_new (void); void ido_time_stamp_menu_item_set_date_time (IdoTimeStampMenuItem * menuitem, GDateTime * date_time); void ido_time_stamp_menu_item_set_format (IdoTimeStampMenuItem * menuitem, const char * strftime_fmt); const char * ido_time_stamp_menu_item_get_format (IdoTimeStampMenuItem * menuitem); G_END_DECLS #endif ayatana-ido-0.4.2/src/idotypebuiltins.c.template0000644000000000000000000000135613211262407016571 0ustar /*** BEGIN file-header ***/ #include "idotypebuiltins.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 ***/ ayatana-ido-0.4.2/src/idotypebuiltins.h.template0000644000000000000000000000100213211262407016562 0ustar /*** BEGIN file-header ***/ #ifndef __IDO_ENUM_TYPES_H__ #define __IDO_ENUM_TYPES_H__ #include G_BEGIN_DECLS /*** END file-header ***/ /*** BEGIN file-production ***/ /* enumerations from "@filename@" */ /*** END file-production ***/ /*** BEGIN file-tail ***/ G_END_DECLS #endif /* !__IDO_ENUM_TYPES_H__ */ /*** END file-tail ***/ /*** BEGIN value-header ***/ GType @enum_name@_get_type (void) G_GNUC_CONST; #define IDO_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) /*** END value-header ***/ ayatana-ido-0.4.2/src/idousermenuitem.c0000644000000000000000000004034113211262407014743 0ustar /* Copyright 2011 Canonical Ltd. Authors: Conor Curran Mirco Müller Charles Kerr This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "idousermenuitem.h" #include "idoactionhelper.h" #define FALLBACK_ICON_NAME "avatar-default" enum { PROP_0, PROP_LABEL, PROP_ICON, PROP_IS_LOGGED_IN, PROP_IS_CURRENT_USER, PROP_LAST }; static GParamSpec *properties[PROP_LAST]; struct _IdoUserMenuItemPrivate { GtkWidget* user_image; GtkWidget* user_name; GtkWidget* container; GtkWidget* tick_icon; gboolean is_logged_in; gboolean is_current_user; gchar * label; GIcon * icon; }; G_DEFINE_TYPE (IdoUserMenuItem, ido_user_menu_item, GTK_TYPE_MENU_ITEM); /* Prototypes */ static gboolean ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * image, cairo_t * cr, gpointer gself); /*** **** GObject virtual functions ***/ static void my_get_property (GObject * o, guint property_id, GValue * value, GParamSpec * pspec) { IdoUserMenuItem * self = IDO_USER_MENU_ITEM (o); switch (property_id) { case PROP_LABEL: g_value_set_string (value, self->priv->label); break; case PROP_ICON: g_value_set_object (value, self->priv->icon); break; case PROP_IS_LOGGED_IN: g_value_set_boolean (value, self->priv->is_logged_in); break; case PROP_IS_CURRENT_USER: g_value_set_boolean (value, self->priv->is_current_user); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_set_property (GObject * o, guint property_id, const GValue * value, GParamSpec * pspec) { IdoUserMenuItem * self = IDO_USER_MENU_ITEM (o); switch (property_id) { case PROP_LABEL: ido_user_menu_item_set_label (self, g_value_get_string (value)); break; case PROP_ICON: ido_user_menu_item_set_icon (self, g_value_get_object (value)); break; case PROP_IS_LOGGED_IN: ido_user_menu_item_set_logged_in (self, g_value_get_boolean (value)); break; case PROP_IS_CURRENT_USER: self->priv->is_current_user = g_value_get_boolean (value); gtk_widget_queue_draw (GTK_WIDGET(self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); break; } } static void my_dispose (GObject *object) { IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object); g_clear_object (&self->priv->icon); G_OBJECT_CLASS (ido_user_menu_item_parent_class)->dispose (object); } static void my_finalize (GObject *object) { IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object); g_free (self->priv->label); G_OBJECT_CLASS (ido_user_menu_item_parent_class)->finalize (object); } static void ido_user_menu_item_class_init (IdoUserMenuItemClass *klass) { GParamFlags prop_flags; GObjectClass * gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (IdoUserMenuItemPrivate)); gobject_class->get_property = my_get_property; gobject_class->set_property = my_set_property; gobject_class->dispose = my_dispose; gobject_class->finalize = my_finalize; prop_flags = G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS; properties[PROP_LABEL] = g_param_spec_string ("label", "The user's name", "The name to display", "J. Random User", prop_flags); properties[PROP_ICON] = g_param_spec_object ("icon", "Icon", "The user's GIcon", G_TYPE_OBJECT, prop_flags); properties[PROP_IS_LOGGED_IN] = g_param_spec_boolean ("is-logged-in", "is logged in", "is user logged in?", FALSE, prop_flags); properties[PROP_IS_CURRENT_USER] = g_param_spec_boolean ("is-current-user", "is current user", "is user current?", FALSE, prop_flags); g_object_class_install_properties (gobject_class, PROP_LAST, properties); } static void ido_user_menu_item_init (IdoUserMenuItem *self) { IdoUserMenuItemPrivate * priv; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, IDO_USER_MENU_ITEM_TYPE, IdoUserMenuItemPrivate); priv = self->priv; // Create the UI elements. priv->user_image = gtk_image_new (); gtk_image_set_from_icon_name (GTK_IMAGE (priv->user_image), FALLBACK_ICON_NAME, GTK_ICON_SIZE_MENU); priv->user_name = gtk_label_new (NULL); priv->container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); priv->tick_icon = gtk_image_new_from_icon_name ("account-logged-in", GTK_ICON_SIZE_MENU); gtk_misc_set_alignment(GTK_MISC(priv->tick_icon), 1.0, 0.5); // Pack it together gtk_box_pack_start (GTK_BOX (priv->container), priv->user_image, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (priv->container), priv->user_name, FALSE, FALSE, 3); gtk_box_pack_end (GTK_BOX(priv->container), priv->tick_icon, FALSE, FALSE, 5); gtk_widget_show_all (priv->container); gtk_container_add (GTK_CONTAINER (self), priv->container); gtk_widget_show_all (priv->tick_icon); gtk_widget_set_no_show_all (priv->tick_icon, TRUE); gtk_widget_hide (priv->tick_icon); // Fetch the drawing context. g_signal_connect_after (GTK_WIDGET(self), "draw", G_CALLBACK(ido_user_menu_item_primitive_draw_cb_gtk_3), GTK_WIDGET(self)); } /*****************************************************************/ static gboolean ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * widget, cairo_t * cr, gpointer user_data) { IdoUserMenuItemPrivate * priv; g_return_val_if_fail(IS_IDO_USER_MENU_ITEM(user_data), FALSE); priv = IDO_USER_MENU_ITEM(user_data)->priv; /* Draw dot only when user is the current user. */ if (priv->is_current_user) { GtkStyleContext * style_context; GtkStateFlags state_flags; GdkRGBA color; gdouble x, y; /* get the foreground color */ style_context = gtk_widget_get_style_context (widget); state_flags = gtk_widget_get_state_flags (widget); gtk_style_context_get_color (style_context, state_flags, &color); GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); x = allocation.x + 13; y = allocation.height / 2; cairo_arc (cr, x, y, 3.0, 0.0, 2 * G_PI); gdk_cairo_set_source_rgba (cr, &color); cairo_fill (cr); } return FALSE; } /*** **** Avatar ***/ static gboolean ido_user_menu_item_set_icon_from_file_icon (IdoUserMenuItem *self, GFileIcon *icon) { GFile *file; gchar *path; gint width; gint height; GdkPixbuf *pixbuf; file = g_file_icon_get_file (G_FILE_ICON (icon)); path = g_file_get_path (file); /* width and height will always be set by this function */ gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (self)), GTK_ICON_SIZE_MENU, &width, &height); pixbuf = gdk_pixbuf_new_from_file_at_scale (path, width, height, TRUE, NULL); g_free (path); if (pixbuf) { gtk_image_set_from_pixbuf (GTK_IMAGE (self->priv->user_image), pixbuf); g_object_unref (pixbuf); return TRUE; } return FALSE; } /*** **** PUBLIC API ***/ void ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon) { IdoUserMenuItemPrivate * p = self->priv; if (p->icon == icon) return; g_clear_object (&p->icon); if (icon) p->icon = g_object_ref (icon); /* Avatars are always loaded from disk. Show the fallback when no icon * is set, the icon is not a file icon, or the file could not be * found. */ if (icon == NULL || !G_IS_FILE_ICON (icon) || !ido_user_menu_item_set_icon_from_file_icon (self, G_FILE_ICON (icon))) { gtk_image_set_from_icon_name (GTK_IMAGE (p->user_image), FALLBACK_ICON_NAME, GTK_ICON_SIZE_MENU); } } void ido_user_menu_item_set_icon_from_file (IdoUserMenuItem * self, const char * filename) { GFile * file = filename ? g_file_new_for_path (filename) : NULL; GIcon * icon = file ? g_file_icon_new (file) : NULL; ido_user_menu_item_set_icon (self, icon); g_clear_object (&icon); g_clear_object (&file); } void ido_user_menu_item_set_logged_in (IdoUserMenuItem * self, gboolean is_logged_in) { gtk_widget_set_visible (self->priv->tick_icon, is_logged_in); } void ido_user_menu_item_set_current_user (IdoUserMenuItem * self, gboolean is_current_user) { self->priv->is_current_user = is_current_user; gtk_widget_queue_draw (GTK_WIDGET (self)); } void ido_user_menu_item_set_label (IdoUserMenuItem * self, const char * label) { gtk_label_set_label (GTK_LABEL(self->priv->user_name), label); } GtkWidget* ido_user_menu_item_new (void) { return GTK_WIDGET (g_object_new (IDO_USER_MENU_ITEM_TYPE, NULL)); } /*** **** ***/ /* * This is a helper function for creating user menuitems for both * "indicator.user-menu-item" and "indicator.guest-menu-item", * since they only differ in how they use their action's state. */ static GtkMenuItem * user_menu_item_new_from_model (GMenuItem * menuitem, GActionGroup * actions, GCallback state_changed_callback) { guint i; guint n; IdoUserMenuItem * ido_user; gchar * str; gchar * action; GVariant * v; GParameter parameters[4]; /* create the ido_user */ n = 0; if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_LABEL, "s", &str)) { GParameter p = { "label", G_VALUE_INIT }; g_value_init (&p.value, G_TYPE_STRING); g_value_take_string (&p.value, str); parameters[n++] = p; } if ((v = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_ICON, NULL))) { GParameter p = { "icon", G_VALUE_INIT }; GIcon * icon = g_icon_deserialize (v); g_value_init (&p.value, G_TYPE_OBJECT); g_value_take_object (&p.value, icon); g_variant_unref (v); parameters[n++] = p; } g_assert (n <= G_N_ELEMENTS (parameters)); ido_user = g_object_newv (IDO_USER_MENU_ITEM_TYPE, n, parameters); for (i=0; i This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __IDO_USER_MENU_ITEM_H__ #define __IDO_USER_MENU_ITEM_H__ #include G_BEGIN_DECLS #define IDO_USER_MENU_ITEM_TYPE (ido_user_menu_item_get_type ()) #define IDO_USER_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_USER_MENU_ITEM_TYPE, IdoUserMenuItem)) #define IDO_USER_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IDO_USER_MENU_ITEM_TYPE, IdoUserMenuItemClass)) #define IS_IDO_USER_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_USER_MENU_ITEM_TYPE)) #define IS_IDO_USER_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IDO_USER_MENU_ITEM_TYPE)) #define IDO_USER_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IDO_USER_MENU_ITEM_TYPE, IdoUserMenuItemClass)) typedef struct _IdoUserMenuItem IdoUserMenuItem; typedef struct _IdoUserMenuItemClass IdoUserMenuItemClass; typedef struct _IdoUserMenuItemPrivate IdoUserMenuItemPrivate; /* property keys */ #define IDO_USER_MENU_ITEM_PROP_LABEL "label" #define IDO_USER_MENU_ITEM_PROP_ICON_FILENAME "icon-filename" #define IDO_USER_MENU_ITEM_PROP_IS_LOGGED_IN "is-logged-in" #define IDO_USER_MENU_ITEM_PROP_IS_CURRENT_USER "is-current-user" struct _IdoUserMenuItemClass { GtkMenuItemClass parent_class; }; struct _IdoUserMenuItem { /*< private >*/ GtkMenuItem parent; IdoUserMenuItemPrivate * priv; }; GType ido_user_menu_item_get_type (void) G_GNUC_CONST; GtkWidget* ido_user_menu_item_new(void); void ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon); void ido_user_menu_item_set_icon_from_file (IdoUserMenuItem * self, const char * filename); void ido_user_menu_item_set_logged_in (IdoUserMenuItem * self, gboolean is_logged_in); void ido_user_menu_item_set_current_user (IdoUserMenuItem * self, gboolean is_current_user); void ido_user_menu_item_set_label (IdoUserMenuItem * self, const char * label); GtkMenuItem * ido_user_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions); GtkMenuItem * ido_guest_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions); G_END_DECLS #endif ayatana-ido-0.4.2/src/libayatana-ido.c0000644000000000000000000000213013211262407014375 0ustar /* * Copyright 2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Lars Uebernickel */ #include /** * ido_init: * * Initializes ido. It has to be called after gtk_init(), but before any * other calls into ido are made. */ void ido_init (void) { GType ido_menu_item_factory_get_type (void); /* make sure this extension point is registered so that gtk calls it * when finding custom menu items */ g_type_ensure (ido_menu_item_factory_get_type ()); } ayatana-ido-0.4.2/src/libayatana-ido.h0000644000000000000000000000230213211262407014403 0ustar /* * Copyright 2010 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of either or both of the following licenses: * * 1) the GNU Lesser General Public License version 3, as published by the * Free Software Foundation; and/or * 2) the GNU Lesser General Public License version 2.1, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License version 3 and version 2.1 along with this program. If not, see * * * Authors: * Cody Russell */ #ifndef __IDO__ #define __IDO__ #include #include #include #include void ido_init (void); #endif /* __IDO__ */ ayatana-ido-0.4.2/src/Makefile.am0000644000000000000000000001050413211262407013413 0ustar CLEANFILES = lib_LTLIBRARIES = libayatana-ido3-0.4.la ido_built_public_sources = \ idotypebuiltins.h stamp_files = \ idotypebuiltins.h \ idotypebuiltins.c sources_h = \ ayatanamenuitemfactory.h \ ayatana-private.h \ idoalarmmenuitem.h \ idocalendarmenuitem.h \ idoentrymenuitem.h \ idomessagedialog.h \ idorange.h \ idoscalemenuitem.h \ idoswitchmenuitem.h \ idousermenuitem.h \ idoappointmentmenuitem.h \ idobasicmenuitem.h \ idoprogressmenuitem.h \ idotimestampmenuitem.h \ idolocationmenuitem.h \ idotimeline.h \ libayatana-ido.h \ idoactionhelper.h \ idomediaplayermenuitem.h \ idoplaybackmenuitem.h \ idoapplicationmenuitem.h \ idodetaillabel.h \ idosourcemenuitem.h EXTRA_DIST = \ ido.list \ idotypebuiltins.h.template \ idotypebuiltins.c.template idotypebuiltins.h: stamp-idotypebuiltins.h stamp-idotypebuiltins.h: $(sources_h) ( cd $(srcdir) && $(GLIB_MKENUMS) --template idotypebuiltins.h.template \ $(sources_h) ) >> xgen-gtbh \ && (cmp -s xgen-gtbh idotypebuiltins.h || cp xgen-gtbh idotypebuiltins.h ) \ && rm -f xgen-gtbh && echo timestamp > $(@F) idotypebuiltins.c: stamp-idotypebuiltins.h ( cd $(srcdir) && $(GLIB_MKENUMS) --template idotypebuiltins.c.template \ $(sources_h) ) > xgen-gtbc \ && cp xgen-gtbc idotypebuiltins.c && rm -f xgen-gtbc INCLUDES = \ -I$(srcdir) \ -I$(top_srcdir) \ -DG_LOG_DOMAIN=\"IDO\" \ -DPREFIX=\"$(prefix)"\" \ -DLIBDIR=\"$(libdir)"\" \ -DG_DISABLE_DEPRECATED \ -DGDK_PIXBUF_DISABLE_DEPRECATED \ -DGDK_DISABLE_DEPRECATED AM_CPPFLAGS = \ $(GCC_FLAGS) \ $(GTK_CFLAGS) \ $(MAINTAINER_CFLAGS) \ -Wall -Werror -Wextra -Wno-unused-parameter -Wno-error=deprecated-declarations AM_CFLAGS = \ $(COVERAGE_CFLAGS) libayatana_ido_0_4_la_SOURCES = \ ayatanamenuitemfactory.c \ libayatana-ido.c \ idotypebuiltins.c \ idocalendarmenuitem.c \ idoalarmmenuitem.c \ idoentrymenuitem.c \ idomessagedialog.c \ idorange.c \ idoscalemenuitem.c \ idoswitchmenuitem.c \ idotimeline.c \ idomenuitemfactory.c \ idoactionhelper.c \ idousermenuitem.c \ idomediaplayermenuitem.c \ idoplaybackmenuitem.c \ idoappointmentmenuitem.c \ idobasicmenuitem.c \ idoprogressmenuitem.c \ idotimestampmenuitem.c \ idolocationmenuitem.c \ idoapplicationmenuitem.c \ idodetaillabel.c \ idosourcemenuitem.c libayatana_ido3_0_4_la_SOURCES = $(libayatana_ido_0_4_la_SOURCES) libayatana_idoincludedir=$(includedir)/libayatana-ido3-0.4/libayatana-ido libayatana_idoinclude_HEADERS = \ idocalendarmenuitem.h \ idoentrymenuitem.h \ idomessagedialog.h \ idorange.h \ idoscalemenuitem.h \ idoswitchmenuitem.h \ idotimeline.h \ libayatana-ido.h libayatana_ido_0_4_la_LIBADD = $(GTK_LIBS) $(LIBM) libayatana_ido_0_4_la_LDFLAGS = \ $(GTK_LT_LDFLAGS) \ $(COVERAGE_LDFLAGS) \ -no-undefined \ -export-symbols-regex "^[^_].*" libayatana_ido3_0_4_la_LIBADD = $(libayatana_ido_0_4_la_LIBADD) libayatana_ido3_0_4_la_LDFLAGS = \ $(libayatana_ido_0_4_la_LDFLAGS) DISTCLEANFILES = \ Makefile.in \ stamp-idotypebuiltins.h \ idotypebuiltins.h \ idotypebuiltins.c -include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = INTROSPECTION_SCANNER_ARGS = \ --symbol-prefix=ido \ --warn-all \ --identifier-prefix=Ido if HAVE_INTROSPECTION AyatanaIdo3-0.4.gir: libayatana-ido3-0.4.la AyatanaIdo3_0_4_gir_INCLUDES = Gtk-3.0 AyatanaIdo3_0_4_gir_CFLAGS = AyatanaIdo3_0_4_gir_LIBS = libayatana-ido3-0.4.la AyatanaIdo3_0_4_gir_FILES = \ idocalendarmenuitem.h \ idoentrymenuitem.h \ idomessagedialog.h \ idorange.h \ idoscalemenuitem.h \ idoswitchmenuitem.h \ idotimeline.h \ $(libayatana_ido_0_4_la_SOURCES) AyatanaIdo3_0_4_gir_NAMESPACE = AyatanaIdo3 AyatanaIdo3_0_4_gir_VERSION = 0.4 AyatanaIdo3_0_4_gir_SCANNER_FLAGS = $(INTROSPECTION_SCANNER_ARGS) INTROSPECTION_GIRS += AyatanaIdo3-0.4.gir girdir = $(datadir)/gir-1.0 gir_DATA = $(INTROSPECTION_GIRS) typelibdir = $(libdir)/girepository-1.0 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) CLEANFILES += $(gir_DATA) $(typelib_DATA) endif if HAVE_INTROSPECTION vapidir = $(datadir)/vala/vapi vapi_DATA = AyatanaIdo3-0.4.vapi AyatanaIdo3-0.4.vapi: AyatanaIdo3-0.4.gir $(VALA_API_GEN) --library=AyatanaIdo3-0.4 \ --pkg gtk+-3.0 \ $< CLEANFILES += $(vapi_DATA) endif ayatana-ido-0.4.2/tests/gtest-menuitems.cpp0000644000000000000000000000451613211262407015576 0ustar #include #include #include "idocalendarmenuitem.h" #include "idoentrymenuitem.h" #include "idoscalemenuitem.h" class TestMenuitems : public ::testing::Test { public: TestMenuitems() { gint argc = 0; gchar * argv[] = {NULL}; gtk_init(&argc, (gchar ***)&argv); return; } }; TEST_F(TestMenuitems, BuildCalendar) { GtkWidget * cal = ido_calendar_menu_item_new(); EXPECT_TRUE(cal != NULL); EXPECT_TRUE(IDO_IS_CALENDAR_MENU_ITEM(cal)); EXPECT_TRUE(GTK_IS_MENU_ITEM(cal)); GtkWidget * menu = gtk_menu_new(); gtk_widget_show(menu); gtk_menu_shell_append(GTK_MENU_SHELL(menu), cal); gtk_widget_show(cal); gtk_widget_realize(cal); EXPECT_TRUE(gtk_widget_get_realized(cal)); g_object_ref_sink(menu); g_object_unref(menu); return; } TEST_F(TestMenuitems, BuildEntry) { GtkWidget * entry = ido_entry_menu_item_new(); EXPECT_TRUE(entry != NULL); EXPECT_TRUE(IDO_IS_ENTRY_MENU_ITEM(entry)); EXPECT_TRUE(GTK_IS_MENU_ITEM(entry)); GtkWidget * menu = gtk_menu_new(); gtk_widget_show(menu); gtk_menu_shell_append(GTK_MENU_SHELL(menu), entry); gtk_widget_show(entry); gtk_widget_realize(entry); EXPECT_TRUE(gtk_widget_get_realized(entry)); g_object_ref_sink(menu); g_object_unref(menu); return; } TEST_F(TestMenuitems, BuildScaleDefault) { GtkWidget * scale = ido_scale_menu_item_new("Label", IDO_RANGE_STYLE_DEFAULT, gtk_adjustment_new(0.5, 0.0, 1.0, 0.01, 0.1, 0.1)); EXPECT_TRUE(scale != NULL); EXPECT_TRUE(IDO_IS_SCALE_MENU_ITEM(scale)); EXPECT_TRUE(GTK_IS_MENU_ITEM(scale)); GtkWidget * menu = gtk_menu_new(); gtk_widget_show(menu); gtk_menu_shell_append(GTK_MENU_SHELL(menu), scale); gtk_widget_show(scale); gtk_widget_realize(scale); EXPECT_TRUE(gtk_widget_get_realized(scale)); g_object_ref_sink(menu); g_object_unref(menu); return; } TEST_F(TestMenuitems, BuildScaleSmall) { GtkWidget * scale = ido_scale_menu_item_new("Label", IDO_RANGE_STYLE_SMALL, gtk_adjustment_new(0.5, 0.0, 1.0, 0.01, 0.1, 0.1)); EXPECT_TRUE(scale != NULL); EXPECT_TRUE(IDO_IS_SCALE_MENU_ITEM(scale)); EXPECT_TRUE(GTK_IS_MENU_ITEM(scale)); GtkWidget * menu = gtk_menu_new(); gtk_widget_show(menu); gtk_menu_shell_append(GTK_MENU_SHELL(menu), scale); gtk_widget_show(scale); gtk_widget_realize(scale); EXPECT_TRUE(gtk_widget_get_realized(scale)); g_object_ref_sink(menu); g_object_unref(menu); return; } ayatana-ido-0.4.2/tests/Makefile.am0000644000000000000000000000223013211262407013763 0ustar IDOLIB = $(top_builddir)/src/libayatana-ido3-0.1.la # xorg-gtest isn't buildable https://bugs.launchpad.net/ubuntu/+source/xorg-gtest/+bug/1388892 # check_LIBRARIES = libgtest.a check_PROGRAMS = TESTS = AM_CPPFLAGS = \ $(GTEST_CPPFLAGS) \ -I${top_srcdir}/src ############################# # Google Test base library ############################# nodist_libgtest_a_SOURCES = \ $(XORG_GTEST_SOURCE)/src/xorg-gtest-all.cpp \ $(GTEST_SOURCE)/gtest-all.cc \ $(XORG_GTEST_SOURCE)/src/xorg-gtest_main.cpp libgtest_a_CPPFLAGS = \ $(XORG_GTEST_CPPFLAGS) \ $(AM_CPPFLAGS) \ $(GTEST_CPPFLAGS) -w libgtest_a_CXXFLAGS = \ $(AM_CXXFLAGS) ############################# # Menuitem tests ############################# # xorg-gtest isn't buildable https://bugs.launchpad.net/ubuntu/+source/xorg-gtest/+bug/1388892 # TESTS += gtest-menuitems # check_PROGRAMS += gtest-menuitems gtest_menuitems_SOURCES = \ gtest-menuitems.cpp gtest_menuitems_CPPFLAGS = \ $(GCC_CFLAGS) \ $(GTK_CFLAGS) \ $(MAINTAINER_CFLAGS) \ $(AM_CPPFLAGS) gtest_menuitems_LDFLAGS = \ -pthread gtest_menuitems_LDADD = \ $(GTK_LIBS) \ $(IDOLIB) \ libgtest.a \ -lX11 -lXi DISTCLEANFILES = Makefile.in ayatana-ido-0.4.2/TODO0000644000000000000000000000000013211262407011246 0ustar