aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2010-07-08 19:31:44 +0200
committerSebastien Bacher <seb128@ubuntu.com>2010-07-08 19:31:44 +0200
commitcf5205162e421080c511428f54cb18d60cd05568 (patch)
treef096e69514b8849f40d73beb3f8cf6646a63f5b8
parentf881060f5a83bea46484083c53ee9b78f01d5d77 (diff)
parent964106d9c8c140d9c27a22aca8078dfdab57c5e9 (diff)
downloadayatana-indicator-sound-cf5205162e421080c511428f54cb18d60cd05568.tar.gz
ayatana-indicator-sound-cf5205162e421080c511428f54cb18d60cd05568.tar.bz2
ayatana-indicator-sound-cf5205162e421080c511428f54cb18d60cd05568.zip
* New upstream release:
-New transport widget integrated -New title widget integrated which allows the user to launch familiar app directly from the menu - UI tidied - Each player that registers with the menu will be stored in the cache file allowing the menu to show the application even if it has not been launched.
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac4
-rw-r--r--data/Makefile.am1
-rw-r--r--debian/changelog13
-rw-r--r--src/Makefile.am7
-rw-r--r--src/Makefile.in47
-rw-r--r--src/common-defs.h3
-rw-r--r--src/dbus-menu-manager.c4
-rw-r--r--src/familiar-players-db.c63
-rw-r--r--src/familiar-players-db.vala3
-rw-r--r--src/indicator-sound.c30
-rw-r--r--src/metadata-menu-item.c43
-rw-r--r--src/metadata-menu-item.vala7
-rw-r--r--src/metadata-widget.c25
-rw-r--r--src/mpris-controller.c138
-rw-r--r--src/mpris-controller.vala41
-rw-r--r--src/music-player-bridge.c208
-rw-r--r--src/music-player-bridge.h118
-rw-r--r--src/music-player-bridge.vala85
-rw-r--r--src/play-button.c800
-rw-r--r--src/play-button.h53
-rw-r--r--src/player-controller.c303
-rw-r--r--src/player-controller.vala109
-rw-r--r--src/player-item.c185
-rw-r--r--src/player-item.vala41
-rw-r--r--src/title-menu-item.c213
-rw-r--r--src/title-menu-item.vala48
-rw-r--r--src/title-widget.c192
-rw-r--r--src/title-widget.h51
-rw-r--r--src/transport-menu-item.c117
-rw-r--r--src/transport-menu-item.vala23
-rw-r--r--src/transport-widget.c136
-rw-r--r--vapi/common-defs.vapi6
33 files changed, 2566 insertions, 571 deletions
diff --git a/configure b/configure
index 1439518..0d44171 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for indicator-sound 0.3.4.
+# Generated by GNU Autoconf 2.65 for indicator-sound 0.3.5.
#
# Report bugs to <conor.curran@canonical.com>.
#
@@ -761,8 +761,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='indicator-sound'
PACKAGE_TARNAME='indicator-sound'
-PACKAGE_VERSION='0.3.4'
-PACKAGE_STRING='indicator-sound 0.3.4'
+PACKAGE_VERSION='0.3.5'
+PACKAGE_STRING='indicator-sound 0.3.5'
PACKAGE_BUGREPORT='conor.curran@canonical.com'
PACKAGE_URL=''
@@ -1555,7 +1555,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures indicator-sound 0.3.4 to adapt to many kinds of systems.
+\`configure' configures indicator-sound 0.3.5 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1625,7 +1625,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of indicator-sound 0.3.4:";;
+ short | recursive ) echo "Configuration of indicator-sound 0.3.5:";;
esac
cat <<\_ACEOF
@@ -1752,7 +1752,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-indicator-sound configure 0.3.4
+indicator-sound configure 0.3.5
generated by GNU Autoconf 2.65
Copyright (C) 2009 Free Software Foundation, Inc.
@@ -2123,7 +2123,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by indicator-sound $as_me 0.3.4, which was
+It was created by indicator-sound $as_me 0.3.5, which was
generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
@@ -2936,7 +2936,7 @@ fi
# Define the identity of the package.
PACKAGE=indicator-sound
- VERSION=0.3.4
+ VERSION=0.3.5
cat >>confdefs.h <<_ACEOF
@@ -14069,7 +14069,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by indicator-sound $as_me 0.3.4, which was
+This file was extended by indicator-sound $as_me 0.3.5, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14135,7 +14135,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-indicator-sound config.status 0.3.4
+indicator-sound config.status 0.3.5
configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index b6c4fe3..5a6abc4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,10 +1,10 @@
-AC_INIT(indicator-sound, 0.3.4, conor.curran@canonical.com)
+AC_INIT(indicator-sound, 0.3.5, conor.curran@canonical.com)
AC_PREREQ(2.53)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(indicator-sound, 0.3.4)
+AM_INIT_AUTOMAKE(indicator-sound, 0.3.5)
AM_MAINTAINER_MODE
diff --git a/data/Makefile.am b/data/Makefile.am
index 0389576..9fa0c9b 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,4 +1,3 @@
-
dbus_servicesdir = $(DBUSSERVICEDIR)
service_in_files = indicator-sound.service.in
dbus_services_DATA = $(service_in_files:.service.in=.service)
diff --git a/debian/changelog b/debian/changelog
index 0821b8c..aedb8ef 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+indicator-sound (0.3.5-0ubuntu1) UNRELEASED; urgency=low
+
+ * New upstream release:
+ -New transport widget integrated
+ -New title widget integrated which allows the user
+ to launch familiar app directly from the menu
+ - UI tidied
+ - Each player that registers with the menu will be stored in the
+ cache file allowing the menu to show the application even if it has
+ not been launched.
+
+ -- Sebastien Bacher <seb128@ubuntu.com> Thu, 08 Jul 2010 19:30:26 +0200
+
indicator-sound (0.3.4-0ubuntu1) maverick; urgency=low
* New upstream version:
diff --git a/src/Makefile.am b/src/Makefile.am
index b33107d..79ba7d2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,11 +13,15 @@ libsoundmenu_la_SOURCES = \
transport-widget.h \
metadata-widget.c \
metadata-widget.h \
+ play-button.c \
+ play-button.h \
indicator-sound.c \
+ title-widget.c \
+ title-widget.h \
dbus-shared-names.h \
sound-service-client.h
-libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror -DG_LOG_DOMAIN=\"Indicator-Sound\"
+libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -DG_LOG_DOMAIN=\"Indicator-Sound\"
libsoundmenu_la_LIBADD = $(APPLET_LIBS)
libsoundmenu_la_LDFLAGS = -module -avoid-version
@@ -54,6 +58,7 @@ music_bridge_VALASOURCES = \
music-player-bridge.vala \
transport-menu-item.vala \
metadata-menu-item.vala \
+ title-menu-item.vala \
player-controller.vala \
mpris-controller-v2.vala \
mpris-controller.vala \
diff --git a/src/Makefile.in b/src/Makefile.in
index e3ddfd3..6f0fd0c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -74,7 +74,9 @@ am__DEPENDENCIES_1 =
libsoundmenu_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libsoundmenu_la_OBJECTS = libsoundmenu_la-transport-widget.lo \
libsoundmenu_la-metadata-widget.lo \
- libsoundmenu_la-indicator-sound.lo
+ libsoundmenu_la-play-button.lo \
+ libsoundmenu_la-indicator-sound.lo \
+ libsoundmenu_la-title-widget.lo
libsoundmenu_la_OBJECTS = $(am_libsoundmenu_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -87,6 +89,7 @@ PROGRAMS = $(libexec_PROGRAMS)
am__objects_1 = indicator_sound_service-music-player-bridge.$(OBJEXT) \
indicator_sound_service-transport-menu-item.$(OBJEXT) \
indicator_sound_service-metadata-menu-item.$(OBJEXT) \
+ indicator_sound_service-title-menu-item.$(OBJEXT) \
indicator_sound_service-player-controller.$(OBJEXT) \
indicator_sound_service-mpris-controller-v2.$(OBJEXT) \
indicator_sound_service-mpris-controller.$(OBJEXT) \
@@ -307,11 +310,15 @@ libsoundmenu_la_SOURCES = \
transport-widget.h \
metadata-widget.c \
metadata-widget.h \
+ play-button.c \
+ play-button.h \
indicator-sound.c \
+ title-widget.c \
+ title-widget.h \
dbus-shared-names.h \
sound-service-client.h
-libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror -DG_LOG_DOMAIN=\"Indicator-Sound\"
+libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -DG_LOG_DOMAIN=\"Indicator-Sound\"
libsoundmenu_la_LIBADD = $(APPLET_LIBS)
libsoundmenu_la_LDFLAGS = -module -avoid-version
@@ -322,6 +329,7 @@ music_bridge_VALASOURCES = \
music-player-bridge.vala \
transport-menu-item.vala \
metadata-menu-item.vala \
+ title-menu-item.vala \
player-controller.vala \
mpris-controller-v2.vala \
mpris-controller.vala \
@@ -522,9 +530,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-slider-menu-item.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-sound-service-dbus.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-sound-service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-title-menu-item.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-transport-menu-item.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-indicator-sound.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-metadata-widget.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-play-button.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-title-widget.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-transport-widget.Plo@am__quote@
.c.o:
@@ -567,6 +578,14 @@ libsoundmenu_la-metadata-widget.lo: metadata-widget.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -c -o libsoundmenu_la-metadata-widget.lo `test -f 'metadata-widget.c' || echo '$(srcdir)/'`metadata-widget.c
+libsoundmenu_la-play-button.lo: play-button.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -MT libsoundmenu_la-play-button.lo -MD -MP -MF $(DEPDIR)/libsoundmenu_la-play-button.Tpo -c -o libsoundmenu_la-play-button.lo `test -f 'play-button.c' || echo '$(srcdir)/'`play-button.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsoundmenu_la-play-button.Tpo $(DEPDIR)/libsoundmenu_la-play-button.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='play-button.c' object='libsoundmenu_la-play-button.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -c -o libsoundmenu_la-play-button.lo `test -f 'play-button.c' || echo '$(srcdir)/'`play-button.c
+
libsoundmenu_la-indicator-sound.lo: indicator-sound.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -MT libsoundmenu_la-indicator-sound.lo -MD -MP -MF $(DEPDIR)/libsoundmenu_la-indicator-sound.Tpo -c -o libsoundmenu_la-indicator-sound.lo `test -f 'indicator-sound.c' || echo '$(srcdir)/'`indicator-sound.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsoundmenu_la-indicator-sound.Tpo $(DEPDIR)/libsoundmenu_la-indicator-sound.Plo
@@ -575,6 +594,14 @@ libsoundmenu_la-indicator-sound.lo: indicator-sound.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -c -o libsoundmenu_la-indicator-sound.lo `test -f 'indicator-sound.c' || echo '$(srcdir)/'`indicator-sound.c
+libsoundmenu_la-title-widget.lo: title-widget.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -MT libsoundmenu_la-title-widget.lo -MD -MP -MF $(DEPDIR)/libsoundmenu_la-title-widget.Tpo -c -o libsoundmenu_la-title-widget.lo `test -f 'title-widget.c' || echo '$(srcdir)/'`title-widget.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsoundmenu_la-title-widget.Tpo $(DEPDIR)/libsoundmenu_la-title-widget.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='title-widget.c' object='libsoundmenu_la-title-widget.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -c -o libsoundmenu_la-title-widget.lo `test -f 'title-widget.c' || echo '$(srcdir)/'`title-widget.c
+
indicator_sound_service-sound-service.o: sound-service.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-sound-service.o -MD -MP -MF $(DEPDIR)/indicator_sound_service-sound-service.Tpo -c -o indicator_sound_service-sound-service.o `test -f 'sound-service.c' || echo '$(srcdir)/'`sound-service.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-sound-service.Tpo $(DEPDIR)/indicator_sound_service-sound-service.Po
@@ -703,6 +730,22 @@ indicator_sound_service-metadata-menu-item.obj: metadata-menu-item.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -c -o indicator_sound_service-metadata-menu-item.obj `if test -f 'metadata-menu-item.c'; then $(CYGPATH_W) 'metadata-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/metadata-menu-item.c'; fi`
+indicator_sound_service-title-menu-item.o: title-menu-item.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-title-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_sound_service-title-menu-item.Tpo -c -o indicator_sound_service-title-menu-item.o `test -f 'title-menu-item.c' || echo '$(srcdir)/'`title-menu-item.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-title-menu-item.Tpo $(DEPDIR)/indicator_sound_service-title-menu-item.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='title-menu-item.c' object='indicator_sound_service-title-menu-item.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -c -o indicator_sound_service-title-menu-item.o `test -f 'title-menu-item.c' || echo '$(srcdir)/'`title-menu-item.c
+
+indicator_sound_service-title-menu-item.obj: title-menu-item.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-title-menu-item.obj -MD -MP -MF $(DEPDIR)/indicator_sound_service-title-menu-item.Tpo -c -o indicator_sound_service-title-menu-item.obj `if test -f 'title-menu-item.c'; then $(CYGPATH_W) 'title-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/title-menu-item.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-title-menu-item.Tpo $(DEPDIR)/indicator_sound_service-title-menu-item.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='title-menu-item.c' object='indicator_sound_service-title-menu-item.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -c -o indicator_sound_service-title-menu-item.obj `if test -f 'title-menu-item.c'; then $(CYGPATH_W) 'title-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/title-menu-item.c'; fi`
+
indicator_sound_service-player-controller.o: player-controller.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-player-controller.o -MD -MP -MF $(DEPDIR)/indicator_sound_service-player-controller.Tpo -c -o indicator_sound_service-player-controller.o `test -f 'player-controller.c' || echo '$(srcdir)/'`player-controller.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-player-controller.Tpo $(DEPDIR)/indicator_sound_service-player-controller.Po
diff --git a/src/common-defs.h b/src/common-defs.h
index dca21cc..9c1fbab 100644
--- a/src/common-defs.h
+++ b/src/common-defs.h
@@ -34,3 +34,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define DBUSMENU_METADATA_MENUITEM_TEXT_TITLE "x-canonical-metadata-text-title"
#define DBUSMENU_METADATA_MENUITEM_TEXT_ALBUM "x-canonical-metadata-text-album"
#define DBUSMENU_METADATA_MENUITEM_ARTURL "x-canonical-metadata-arturl"
+
+#define DBUSMENU_TITLE_MENUITEM_TYPE "x-canonical-sound-menu-player-title-menu-item"
+#define DBUSMENU_TITLE_MENUITEM_TEXT_NAME "x-canonical-sound-menu-player-title-name"
diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c
index d19bfbb..4cd4a6b 100644
--- a/src/dbus-menu-manager.c
+++ b/src/dbus-menu-manager.c
@@ -172,7 +172,9 @@ Bring up the gnome volume preferences dialog
static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data)
{
GError * error = NULL;
- if (!g_spawn_command_line_async("gnome-volume-control", &error)) {
+ if (!g_spawn_command_line_async("gnome-volume-control", &error) &&
+ !g_spawn_command_line_async("xfce4-mixer", &error))
+ {
g_warning("Unable to show dialog: %s", error->message);
g_error_free(error);
}
diff --git a/src/familiar-players-db.c b/src/familiar-players-db.c
index 152571d..9933d4d 100644
--- a/src/familiar-players-db.c
+++ b/src/familiar-players-db.c
@@ -139,17 +139,17 @@ static gboolean familiar_players_db_create_key_file (FamiliarPlayersDB* self) {
_tmp1_ = g_key_file_load_from_file (self->priv->key_file, self->priv->file_name, G_KEY_FILE_NONE, &_inner_error_);
if (_inner_error_ != NULL) {
if (_inner_error_->domain == G_FILE_ERROR) {
- goto __catch2_g_file_error;
+ goto __catch3_g_file_error;
}
- goto __finally2;
+ goto __finally3;
}
if (_tmp1_ == TRUE) {
result = TRUE;
return result;
}
}
- goto __finally2;
- __catch2_g_file_error:
+ goto __finally3;
+ __catch3_g_file_error:
{
GError * e;
e = _inner_error_;
@@ -160,7 +160,7 @@ static gboolean familiar_players_db_create_key_file (FamiliarPlayersDB* self) {
_g_error_free0 (e);
}
}
- __finally2:
+ __finally3:
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
@@ -182,7 +182,7 @@ static gboolean familiar_players_db_check_for_keys (FamiliarPlayersDB* self) {
_tmp0_ = g_key_file_has_key (self->priv->key_file, FAMILIAR_PLAYERS_DB_GROUP_NAME, FAMILIAR_PLAYERS_DB_KEY_NAME, &_inner_error_);
if (_inner_error_ != NULL) {
if (_inner_error_->domain == G_KEY_FILE_ERROR) {
- goto __catch3_g_key_file_error;
+ goto __catch4_g_key_file_error;
}
g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
@@ -193,8 +193,8 @@ static gboolean familiar_players_db_check_for_keys (FamiliarPlayersDB* self) {
return result;
}
}
- goto __finally3;
- __catch3_g_key_file_error:
+ goto __finally4;
+ __catch4_g_key_file_error:
{
GError * e;
e = _inner_error_;
@@ -205,7 +205,7 @@ static gboolean familiar_players_db_check_for_keys (FamiliarPlayersDB* self) {
return result;
}
}
- __finally3:
+ __finally4:
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
@@ -232,9 +232,9 @@ static gboolean familiar_players_db_load_data_from_key_file (FamiliarPlayersDB*
desktops = (_tmp1_ = g_key_file_get_string_list (self->priv->key_file, FAMILIAR_PLAYERS_DB_GROUP_NAME, FAMILIAR_PLAYERS_DB_KEY_NAME, &_tmp0_, &_inner_error_), desktops_length1 = _tmp0_, _desktops_size_ = desktops_length1, _tmp1_);
if (_inner_error_ != NULL) {
if (_inner_error_->domain == G_FILE_ERROR) {
- goto __catch4_g_file_error;
+ goto __catch5_g_file_error;
}
- goto __finally4;
+ goto __finally5;
}
{
char** s_collection;
@@ -255,8 +255,8 @@ static gboolean familiar_players_db_load_data_from_key_file (FamiliarPlayersDB*
desktops = (_vala_array_free (desktops, desktops_length1, (GDestroyNotify) g_free), NULL);
return result;
}
- goto __finally4;
- __catch4_g_file_error:
+ goto __finally5;
+ __catch5_g_file_error:
{
GError * _error_;
_error_ = _inner_error_;
@@ -268,7 +268,7 @@ static gboolean familiar_players_db_load_data_from_key_file (FamiliarPlayersDB*
return result;
}
}
- __finally4:
+ __finally5:
{
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
@@ -324,8 +324,8 @@ static gboolean familiar_players_db_write_db (FamiliarPlayersDB* self) {
char* _tmp4_;
data = (_tmp4_ = g_key_file_to_data (keyfile, &data_length, NULL), _g_free0 (data), _tmp4_);
}
- goto __finally5;
- __catch5_g_error:
+ goto __finally6;
+ __catch6_g_error:
{
GError * e;
e = _inner_error_;
@@ -340,7 +340,7 @@ static gboolean familiar_players_db_write_db (FamiliarPlayersDB* self) {
return result;
}
}
- __finally5:
+ __finally6:
if (_inner_error_ != NULL) {
_g_key_file_free0 (keyfile);
desktops = (_vala_array_free (desktops, desktops_length1, (GDestroyNotify) g_free), NULL);
@@ -362,7 +362,7 @@ static gboolean familiar_players_db_write_db (FamiliarPlayersDB* self) {
_tmp5_ = g_file_set_contents (self->priv->file_name, data, (gssize) data_length, &_inner_error_);
if (_inner_error_ != NULL) {
if (_inner_error_->domain == G_FILE_ERROR) {
- goto __catch6_g_file_error;
+ goto __catch7_g_file_error;
}
_g_key_file_free0 (keyfile);
desktops = (_vala_array_free (desktops, desktops_length1, (GDestroyNotify) g_free), NULL);
@@ -375,8 +375,8 @@ static gboolean familiar_players_db_write_db (FamiliarPlayersDB* self) {
g_warning ("familiar-players-db.vala:123: Unable to write out file '%s'", self->priv->file_name);
}
}
- goto __finally6;
- __catch6_g_file_error:
+ goto __finally7;
+ __catch7_g_file_error:
{
GError * err;
err = _inner_error_;
@@ -386,7 +386,7 @@ static gboolean familiar_players_db_write_db (FamiliarPlayersDB* self) {
_g_error_free0 (err);
}
}
- __finally6:
+ __finally7:
if (_inner_error_ != NULL) {
_g_key_file_free0 (keyfile);
desktops = (_vala_array_free (desktops, desktops_length1, (GDestroyNotify) g_free), NULL);
@@ -426,11 +426,30 @@ void familiar_players_db_insert (FamiliarPlayersDB* self, const char* desktop) {
}
+static char* bool_to_string (gboolean self) {
+ char* result = NULL;
+ if (self) {
+ result = g_strdup ("true");
+ return result;
+ } else {
+ result = g_strdup ("false");
+ return result;
+ }
+}
+
+
gboolean familiar_players_db_already_familiar (FamiliarPlayersDB* self, const char* desktop) {
gboolean result = FALSE;
+ char* _tmp1_;
+ GeeSet* _tmp0_;
+ GeeSet* _tmp2_;
+ gboolean _tmp3_;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (desktop != NULL, FALSE);
- result = GPOINTER_TO_INT (gee_abstract_map_get ((GeeAbstractMap*) self->priv->players_DB, desktop));
+ g_debug ("familiar-players-db.vala:146: playerDB->already_familiar - result %s", _tmp1_ = bool_to_string (gee_collection_contains ((GeeCollection*) (_tmp0_ = gee_map_get_keys ((GeeMap*) self->priv->players_DB)), desktop)));
+ _g_free0 (_tmp1_);
+ _g_object_unref0 (_tmp0_);
+ result = (_tmp3_ = gee_collection_contains ((GeeCollection*) (_tmp2_ = gee_map_get_keys ((GeeMap*) self->priv->players_DB)), desktop), _g_object_unref0 (_tmp2_), _tmp3_);
return result;
}
diff --git a/src/familiar-players-db.vala b/src/familiar-players-db.vala
index 88bc01f..b83caa3 100644
--- a/src/familiar-players-db.vala
+++ b/src/familiar-players-db.vala
@@ -143,7 +143,8 @@ public class FamiliarPlayersDB : GLib.Object
public bool already_familiar(string desktop)
{
- return this.players_DB.get(desktop);
+ debug("playerDB->already_familiar - result %s", this.players_DB.keys.contains(desktop).to_string());
+ return this.players_DB.keys.contains(desktop);
}
public Gee.Set<string> records()
diff --git a/src/indicator-sound.c b/src/indicator-sound.c
index 3f0d2d3..8be97b4 100644
--- a/src/indicator-sound.c
+++ b/src/indicator-sound.c
@@ -40,6 +40,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "indicator-sound.h"
#include "transport-widget.h"
#include "metadata-widget.h"
+#include "title-widget.h"
#include "dbus-shared-names.h"
#include "sound-service-client.h"
#include "common-defs.h"
@@ -96,6 +97,7 @@ static void style_changed_cb(GtkWidget *widget, gpointer user_data);
//player widgets related
static gboolean new_transport_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
static gboolean new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
+static gboolean new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
// DBUS communication
static DBusGProxy *sound_dbus_proxy = NULL;
@@ -243,7 +245,7 @@ get_menu (IndicatorObject * io)
dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);
dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TRANSPORT_MENUITEM_TYPE, new_transport_widget);
dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_METADATA_MENUITEM_TYPE, new_metadata_widget);
-
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TITLE_MENUITEM_TYPE, new_title_widget);
// register Key-press listening on the menu widget as the slider does not allow this.
g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL);
return GTK_MENU(menu);
@@ -326,10 +328,9 @@ new_transport_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbus
bar = transport_widget_new(newitem);
GtkMenuItem *menu_transport_bar = GTK_MENU_ITEM(bar);
+ gtk_widget_show_all(bar);
dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_transport_bar, parent);
- gtk_widget_show_all(bar);
-
return TRUE;
}
@@ -346,16 +347,31 @@ new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm
metadata = metadata_widget_new (newitem);
GtkMenuItem *menu_metadata_widget = GTK_MENU_ITEM(metadata);
+ gtk_widget_show_all(metadata);
dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_metadata_widget, parent);
- gtk_widget_show_all(metadata);
-
return TRUE;
}
-//const gchar* path = dbusmenu_menuitem_property_get(new_item, DBUSMENU_METADATA_MENUITEM_IMAGE_PATH);
+static gboolean
+new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
+{
+ g_debug("indicator-sound: new_title_widget");
+
+ GtkWidget* title = NULL;
+
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+
+ title = title_widget_new (newitem);
+ GtkMenuItem *menu_title_widget = GTK_MENU_ITEM(title);
+
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_title_widget, parent);
-//g_debug("New transport bar path = %s", path);
+ gtk_widget_show_all(title);
+
+ return TRUE;
+}
static void
diff --git a/src/metadata-menu-item.c b/src/metadata-menu-item.c
index f33e848..518bad8 100644
--- a/src/metadata-menu-item.c
+++ b/src/metadata-menu-item.c
@@ -43,16 +43,6 @@ typedef struct _PlayerItem PlayerItem;
typedef struct _PlayerItemClass PlayerItemClass;
typedef struct _PlayerItemPrivate PlayerItemPrivate;
-#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
-#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
-#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
-#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
-#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-
-typedef struct _MprisController MprisController;
-typedef struct _MprisControllerClass MprisControllerClass;
-
#define TYPE_METADATA_MENUITEM (metadata_menuitem_get_type ())
#define METADATA_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_METADATA_MENUITEM, MetadataMenuitem))
#define METADATA_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_METADATA_MENUITEM, MetadataMenuitemClass))
@@ -64,17 +54,14 @@ typedef struct _MetadataMenuitem MetadataMenuitem;
typedef struct _MetadataMenuitemClass MetadataMenuitemClass;
typedef struct _MetadataMenuitemPrivate MetadataMenuitemPrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
-#define _g_free0(var) (var = (g_free (var), NULL))
struct _PlayerItem {
DbusmenuMenuitem parent_instance;
PlayerItemPrivate * priv;
- MprisController* mpris_adaptor;
};
struct _PlayerItemClass {
DbusmenuMenuitemClass parent_class;
- void (*check_layout) (PlayerItem* self);
};
struct _MetadataMenuitem {
@@ -90,26 +77,21 @@ struct _MetadataMenuitemClass {
static gpointer metadata_menuitem_parent_class = NULL;
GType player_item_get_type (void);
-GType mpris_controller_get_type (void);
GType metadata_menuitem_get_type (void);
enum {
METADATA_MENUITEM_DUMMY_PROPERTY
};
-PlayerItem* player_item_new (void);
-PlayerItem* player_item_construct (GType object_type);
MetadataMenuitem* metadata_menuitem_new (void);
MetadataMenuitem* metadata_menuitem_construct (GType object_type);
GeeHashSet* metadata_menuitem_attributes_format (void);
gboolean metadata_menuitem_populated (MetadataMenuitem* self);
-static void metadata_menuitem_real_check_layout (PlayerItem* base);
static int _vala_strcmp0 (const char * str1, const char * str2);
MetadataMenuitem* metadata_menuitem_construct (GType object_type) {
MetadataMenuitem * self;
- self = (MetadataMenuitem*) player_item_construct (object_type);
- dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) self, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_METADATA_MENUITEM_TYPE);
+ self = (MetadataMenuitem*) g_object_new (object_type, "item-type", DBUSMENU_METADATA_MENUITEM_TYPE, NULL);
return self;
}
@@ -132,28 +114,6 @@ GeeHashSet* metadata_menuitem_attributes_format (void) {
}
-static char* bool_to_string (gboolean self) {
- char* result = NULL;
- if (self) {
- result = g_strdup ("true");
- return result;
- } else {
- result = g_strdup ("false");
- return result;
- }
-}
-
-
-static void metadata_menuitem_real_check_layout (PlayerItem* base) {
- MetadataMenuitem * self;
- char* _tmp0_;
- self = (MetadataMenuitem*) base;
- dbusmenu_menuitem_property_set_bool ((DbusmenuMenuitem*) self, DBUSMENU_MENUITEM_PROP_VISIBLE, metadata_menuitem_populated (self));
- g_debug ("metadata-menu-item.vala:43: check layout for the metadata = %s", _tmp0_ = bool_to_string (metadata_menuitem_populated (self)));
- _g_free0 (_tmp0_);
-}
-
-
gboolean metadata_menuitem_populated (MetadataMenuitem* self) {
gboolean result = FALSE;
gboolean _tmp0_ = FALSE;
@@ -170,7 +130,6 @@ gboolean metadata_menuitem_populated (MetadataMenuitem* self) {
static void metadata_menuitem_class_init (MetadataMenuitemClass * klass) {
metadata_menuitem_parent_class = g_type_class_peek_parent (klass);
- PLAYER_ITEM_CLASS (klass)->check_layout = metadata_menuitem_real_check_layout;
}
diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala
index 541fbf4..cfcb3bc 100644
--- a/src/metadata-menu-item.vala
+++ b/src/metadata-menu-item.vala
@@ -25,7 +25,7 @@ public class MetadataMenuitem : PlayerItem
{
public MetadataMenuitem()
{
- this.property_set(MENUITEM_PROP_TYPE, MENUITEM_TYPE);
+ Object(item_type: MENUITEM_TYPE);
}
public static HashSet<string> attributes_format()
@@ -37,11 +37,6 @@ public class MetadataMenuitem : PlayerItem
attrs.add(MENUITEM_ARTURL);
return attrs;
}
-
- public override void check_layout(){
- this.property_set_bool(MENUITEM_PROP_VISIBLE, this.populated());
- debug("check layout for the metadata = %s", this.populated().to_string());
- }
public bool populated()
{
diff --git a/src/metadata-widget.c b/src/metadata-widget.c
index ce3bcd1..8235725 100644
--- a/src/metadata-widget.c
+++ b/src/metadata-widget.c
@@ -47,6 +47,8 @@ static void metadata_widget_class_init (MetadataWidgetClass *klass);
static void metadata_widget_init (MetadataWidget *self);
static void metadata_widget_dispose (GObject *object);
static void metadata_widget_finalize (GObject *object);
+static gboolean metadata_widget_expose_event(GtkWidget* widget, GdkEventExpose* event);
+
// keyevent consumers
static gboolean metadata_widget_button_press_event (GtkWidget *menuitem,
GdkEventButton *event);
@@ -74,7 +76,7 @@ metadata_widget_class_init (MetadataWidgetClass *klass)
widget_class->button_press_event = metadata_widget_button_press_event;
widget_class->button_release_event = metadata_widget_button_release_event;
-
+ widget_class->expose_event = metadata_widget_expose_event;
g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate));
gobject_class->dispose = metadata_widget_dispose;
@@ -110,8 +112,8 @@ metadata_widget_init (MetadataWidget *self)
DBUSMENU_METADATA_MENUITEM_TEXT_ARTIST));
gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0);
- gtk_label_set_width_chars(GTK_LABEL(artist), 20);
- gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_END);
+ gtk_label_set_width_chars(GTK_LABEL(artist), 15);
+ gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE);
priv->artist_label = artist;
// Style it up.
style_artist_text(self);
@@ -121,8 +123,8 @@ metadata_widget_init (MetadataWidget *self)
piece = gtk_label_new(dbusmenu_menuitem_property_get(twin_item,
DBUSMENU_METADATA_MENUITEM_TEXT_TITLE));
gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0);
- gtk_label_set_width_chars(GTK_LABEL(piece), 16);
- gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_END);
+ gtk_label_set_width_chars(GTK_LABEL(piece), 12);
+ gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE);
priv->piece_label = piece;
// Style it up.
style_title_text(self);
@@ -132,8 +134,8 @@ metadata_widget_init (MetadataWidget *self)
container = gtk_label_new(dbusmenu_menuitem_property_get(twin_item,
DBUSMENU_METADATA_MENUITEM_TEXT_ALBUM));
gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0);
- gtk_label_set_width_chars(GTK_LABEL(container), 20);
- gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_END);
+ gtk_label_set_width_chars(GTK_LABEL(container), 15);
+ gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE);
priv->container_label = container;
// Style it up.
style_album_text(self);
@@ -152,6 +154,15 @@ metadata_widget_init (MetadataWidget *self)
}
+static gboolean
+metadata_widget_expose_event(GtkWidget* widget, GdkEventExpose* event)
+{
+ MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget);
+
+ gtk_container_propagate_expose(GTK_CONTAINER(widget), priv->hbox, event);
+ return TRUE;
+}
+
static void
metadata_widget_dispose (GObject *object)
{
diff --git a/src/mpris-controller.c b/src/mpris-controller.c
index a9a26b2..7ef0aa3 100644
--- a/src/mpris-controller.c
+++ b/src/mpris-controller.c
@@ -84,6 +84,8 @@ typedef struct _TransportMenuitem TransportMenuitem;
typedef struct _TransportMenuitemClass TransportMenuitemClass;
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
+#define TRANSPORT_MENUITEM_TYPE_ACTION (transport_menuitem_action_get_type ())
+
struct _MprisController {
GObject parent_instance;
MprisControllerPrivate * priv;
@@ -101,21 +103,26 @@ struct _MprisControllerPrivate {
struct _MprisControllerstatus {
gint32 playback;
- gint32 shuffle;
- gint32 repeat;
- gint32 endless;
};
struct _PlayerController {
GObject parent_instance;
PlayerControllerPrivate * priv;
+ gint current_state;
GeeArrayList* custom_items;
+ MprisController* mpris_adaptor;
};
struct _PlayerControllerClass {
GObjectClass parent_class;
};
+typedef enum {
+ TRANSPORT_MENUITEM_ACTION_PREVIOUS,
+ TRANSPORT_MENUITEM_ACTION_PLAY_PAUSE,
+ TRANSPORT_MENUITEM_ACTION_NEXT
+} TransportMenuitemaction;
+
static gpointer mpris_controller_parent_class = NULL;
@@ -146,9 +153,14 @@ GeeHashSet* metadata_menuitem_attributes_format (void);
MprisController* mpris_controller_new (const char* name, PlayerController* controller, const char* mpris_interface);
MprisController* mpris_controller_construct (GType object_type, const char* name, PlayerController* controller, const char* mpris_interface);
void player_item_reset (PlayerItem* self, GeeHashSet* attrs);
-static void _dynamic_Play2 (DBusGProxy* self, GError** error);
-static void _dynamic_Pause3 (DBusGProxy* self, GError** error);
-void mpris_controller_toggle_playback (MprisController* self, gboolean state);
+GType transport_menuitem_action_get_type (void);
+static void _dynamic_GetStatus2 (DBusGProxy* self, MprisControllerstatus* result, GError** error);
+static void _dynamic_Play3 (DBusGProxy* self, GError** error);
+static void _dynamic_Pause4 (DBusGProxy* self, GError** error);
+static void _dynamic_previous5 (DBusGProxy* self, GError** error);
+static void _dynamic_next6 (DBusGProxy* self, GError** error);
+void mpris_controller_transport_event (MprisController* self, TransportMenuitemaction command);
+gboolean mpris_controller_connected (MprisController* self);
static GValue* _g_value_dup (GValue* self);
GeeHashSet* transport_menuitem_attributes_format (void);
static void mpris_controller_finalize (GObject* obj);
@@ -179,22 +191,19 @@ static void _mpris_controller_onStatusChange_dynamic_StatusChange2_ (DBusGProxy*
void _dynamic_StatusChange3_connect (gpointer obj, const char * signal_name, GCallback handler, gpointer data) {
- dbus_g_object_register_marshaller (g_cclosure_user_marshal_VOID__BOXED, G_TYPE_NONE, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID), G_TYPE_INVALID);
- dbus_g_proxy_add_signal (obj, "StatusChange", dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID), G_TYPE_INVALID);
+ dbus_g_object_register_marshaller (g_cclosure_user_marshal_VOID__BOXED, G_TYPE_NONE, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INVALID), G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (obj, "StatusChange", dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INVALID), G_TYPE_INVALID);
dbus_g_proxy_connect_signal (obj, signal_name, handler, data, NULL);
}
static void _dynamic_GetStatus0 (DBusGProxy* self, MprisControllerstatus* result, GError** error) {
GValueArray* dbus_result;
- dbus_g_proxy_call (self, "GetStatus", error, G_TYPE_INVALID, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID), &dbus_result, G_TYPE_INVALID);
+ dbus_g_proxy_call (self, "GetStatus", error, G_TYPE_INVALID, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INVALID), &dbus_result, G_TYPE_INVALID);
if (*error) {
return;
}
result->playback = g_value_get_int (&dbus_result->values[0]);
- result->shuffle = g_value_get_int (&dbus_result->values[1]);
- result->repeat = g_value_get_int (&dbus_result->values[2]);
- result->endless = g_value_get_int (&dbus_result->values[3]);
}
@@ -234,12 +243,12 @@ MprisController* mpris_controller_construct (GType object_type, const char* name
DBusGConnection* _tmp1_;
_tmp0_ = dbus_g_bus_get (DBUS_BUS_SESSION, &_inner_error_);
if (_inner_error_ != NULL) {
- goto __catch1_g_error;
+ goto __catch2_g_error;
}
self->priv->connection = (_tmp1_ = _tmp0_, _dbus_g_connection_unref0 (self->priv->connection), _tmp1_);
}
- goto __finally1;
- __catch1_g_error:
+ goto __finally2;
+ __catch2_g_error:
{
GError * e;
e = _inner_error_;
@@ -249,7 +258,7 @@ MprisController* mpris_controller_construct (GType object_type, const char* name
_g_error_free0 (e);
}
}
- __finally1:
+ __finally2:
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
@@ -308,7 +317,17 @@ static void mpris_controller_onTrackChange (MprisController* self, DBusGProxy* m
}
-static void _dynamic_Play2 (DBusGProxy* self, GError** error) {
+static void _dynamic_GetStatus2 (DBusGProxy* self, MprisControllerstatus* result, GError** error) {
+ GValueArray* dbus_result;
+ dbus_g_proxy_call (self, "GetStatus", error, G_TYPE_INVALID, dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INVALID), &dbus_result, G_TYPE_INVALID);
+ if (*error) {
+ return;
+ }
+ result->playback = g_value_get_int (&dbus_result->values[0]);
+}
+
+
+static void _dynamic_Play3 (DBusGProxy* self, GError** error) {
dbus_g_proxy_call (self, "Play", error, G_TYPE_INVALID, G_TYPE_INVALID);
if (*error) {
return;
@@ -316,7 +335,7 @@ static void _dynamic_Play2 (DBusGProxy* self, GError** error) {
}
-static void _dynamic_Pause3 (DBusGProxy* self, GError** error) {
+static void _dynamic_Pause4 (DBusGProxy* self, GError** error) {
dbus_g_proxy_call (self, "Pause", error, G_TYPE_INVALID, G_TYPE_INVALID);
if (*error) {
return;
@@ -324,30 +343,89 @@ static void _dynamic_Pause3 (DBusGProxy* self, GError** error) {
}
-void mpris_controller_toggle_playback (MprisController* self, gboolean state) {
+static void _dynamic_previous5 (DBusGProxy* self, GError** error) {
+ dbus_g_proxy_call (self, "Previous", error, G_TYPE_INVALID, G_TYPE_INVALID);
+ if (*error) {
+ return;
+ }
+}
+
+
+static void _dynamic_next6 (DBusGProxy* self, GError** error) {
+ dbus_g_proxy_call (self, "Next", error, G_TYPE_INVALID, G_TYPE_INVALID);
+ if (*error) {
+ return;
+ }
+}
+
+
+void mpris_controller_transport_event (MprisController* self, TransportMenuitemaction command) {
GError * _inner_error_;
g_return_if_fail (self != NULL);
_inner_error_ = NULL;
- if (state == TRUE) {
- g_debug ("mpris-controller.vala:71: about to play");
- _dynamic_Play2 (self->mpris_player, &_inner_error_);
+ g_debug ("mpris-controller.vala:70: transport_event input = %i", (gint) command);
+ if (command == TRANSPORT_MENUITEM_ACTION_PLAY_PAUSE) {
+ MprisControllerstatus _tmp0_ = {0};
+ MprisControllerstatus st;
+ gboolean play_state;
+ gboolean new_play_state;
+ st = (_dynamic_GetStatus2 (self->mpris_player, &_tmp0_, &_inner_error_), _tmp0_);
if (_inner_error_ != NULL) {
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
return;
}
+ play_state = st.playback == 1;
+ g_debug ("mpris-controller.vala:74: toggle_playback - initial play state %i", (gint) play_state);
+ new_play_state = !play_state;
+ g_debug ("mpris-controller.vala:76: toggle_playback - new play state %i", (gint) new_play_state);
+ if (new_play_state == TRUE) {
+ g_debug ("mpris-controller.vala:78: about to play");
+ _dynamic_Play3 (self->mpris_player, &_inner_error_);
+ if (_inner_error_ != NULL) {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return;
+ }
+ } else {
+ g_debug ("mpris-controller.vala:82: about to pause");
+ _dynamic_Pause4 (self->mpris_player, &_inner_error_);
+ if (_inner_error_ != NULL) {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return;
+ }
+ }
} else {
- g_debug ("mpris-controller.vala:75: about to pause");
- _dynamic_Pause3 (self->mpris_player, &_inner_error_);
- if (_inner_error_ != NULL) {
- g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
- g_clear_error (&_inner_error_);
- return;
+ if (command == TRANSPORT_MENUITEM_ACTION_PREVIOUS) {
+ _dynamic_previous5 (self->mpris_player, &_inner_error_);
+ if (_inner_error_ != NULL) {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return;
+ }
+ } else {
+ if (command == TRANSPORT_MENUITEM_ACTION_NEXT) {
+ _dynamic_next6 (self->mpris_player, &_inner_error_);
+ if (_inner_error_ != NULL) {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return;
+ }
+ }
}
}
}
+gboolean mpris_controller_connected (MprisController* self) {
+ gboolean result = FALSE;
+ g_return_val_if_fail (self != NULL, FALSE);
+ result = self->mpris_player != NULL;
+ return result;
+}
+
+
static GValue* _g_value_dup (GValue* self) {
return g_boxed_copy (G_TYPE_VALUE, self);
}
@@ -368,11 +446,11 @@ static void mpris_controller_onStatusChange (MprisController* self, DBusGProxy*
PlayerItem* _tmp0_;
g_return_if_fail (self != NULL);
g_return_if_fail (mpris_client != NULL);
- g_debug ("mpris-controller.vala:82: onStatusChange - signal received");
+ g_debug ("mpris-controller.vala:101: onStatusChange - signal received");
status = st;
ar = (GValueArray*) status;
play_state = g_value_get_int (g_value_array_get_nth (ar, (guint) 0));
- g_debug ("mpris-controller.vala:86: onStatusChange - play state %i", play_state);
+ g_debug ("mpris-controller.vala:105: onStatusChange - play state %i", play_state);
ht = g_hash_table_new (g_str_hash, g_str_equal);
g_value_init (&v, G_TYPE_INT);
g_value_set_int (&v, play_state);
diff --git a/src/mpris-controller.vala b/src/mpris-controller.vala
index beaf02c..2194d44 100644
--- a/src/mpris-controller.vala
+++ b/src/mpris-controller.vala
@@ -27,9 +27,9 @@ public class MprisController : GLib.Object
private PlayerController controller;
struct status {
public int32 playback;
- public int32 shuffle;
- public int32 repeat;
- public int32 endless;
+ //public int32 shuffle; // Not used just yet
+ //public int32 repeat;
+ //public int32 endless;
}
public MprisController(string name, PlayerController controller, string mpris_interface="org.freedesktop.MediaPlayer"){
@@ -65,16 +65,35 @@ public class MprisController : GLib.Object
* TRUE => Playing
* FALSE => Paused
**/
- public void toggle_playback(bool state)
+ public void transport_event(TransportMenuitem.action command)
{
- if(state == true){
- debug("about to play");
- this.mpris_player.Play();
+ debug("transport_event input = %i", (int)command);
+ if(command == TransportMenuitem.action.PLAY_PAUSE){
+ status st = this.mpris_player.GetStatus();
+ bool play_state = st.playback == 1;
+ debug("toggle_playback - initial play state %i", (int)play_state);
+ bool new_play_state = !play_state;
+ debug("toggle_playback - new play state %i", (int)new_play_state);
+ if(new_play_state == true){
+ debug("about to play");
+ this.mpris_player.Play();
+ }
+ else{
+ debug("about to pause");
+ this.mpris_player.Pause();
+ }
}
- else{
- debug("about to pause");
- this.mpris_player.Pause();
- }
+ else if(command == TransportMenuitem.action.PREVIOUS){
+ this.mpris_player.previous();
+ }
+ else if(command == TransportMenuitem.action.NEXT){
+ this.mpris_player.next();
+ }
+ }
+
+ public bool connected()
+ {
+ return (this.mpris_player != null);
}
private void onStatusChange(dynamic DBus.Object mpris_client, status st)
diff --git a/src/music-player-bridge.c b/src/music-player-bridge.c
index 250f761..9fd386a 100644
--- a/src/music-player-bridge.c
+++ b/src/music-player-bridge.c
@@ -70,6 +70,8 @@ typedef struct _FamiliarPlayersDB FamiliarPlayersDB;
typedef struct _FamiliarPlayersDBClass FamiliarPlayersDBClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
+
+#define PLAYER_CONTROLLER_TYPE_STATE (player_controller_state_get_type ())
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
struct _MusicPlayerBridge {
@@ -88,6 +90,14 @@ struct _MusicPlayerBridgePrivate {
FamiliarPlayersDB* playersDB;
};
+typedef enum {
+ PLAYER_CONTROLLER_STATE_OFFLINE,
+ PLAYER_CONTROLLER_STATE_INSTANTIATING,
+ PLAYER_CONTROLLER_STATE_READY,
+ PLAYER_CONTROLLER_STATE_CONNECTED,
+ PLAYER_CONTROLLER_STATE_DISCONNECTED
+} PlayerControllerstate;
+
static gpointer music_player_bridge_parent_class = NULL;
@@ -115,13 +125,19 @@ static void _music_player_bridge_on_server_count_changed_indicate_listener_serve
MusicPlayerBridge* music_player_bridge_new (void);
MusicPlayerBridge* music_player_bridge_construct (GType object_type);
GeeSet* familiar_players_db_records (FamiliarPlayersDB* self);
-PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, gboolean active);
-PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, gboolean active);
+GType player_controller_state_get_type (void);
+PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state);
+PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state);
static void music_player_bridge_try_to_add_inactive_familiar_clients (MusicPlayerBridge* self);
static gboolean music_player_bridge_server_is_not_of_interest (MusicPlayerBridge* self, const char* type);
+void player_controller_update_state (PlayerController* self, PlayerControllerstate new_state);
+void player_controller_activate (PlayerController* self);
+GAppInfo* player_controller_get_app_info (PlayerController* self);
static void music_player_bridge_desktop_info_callback (MusicPlayerBridge* self, IndicateListenerServer* server, char* path, void* data);
void player_controller_vanish (PlayerController* self);
+gboolean familiar_players_db_already_familiar (FamiliarPlayersDB* self, const char* desktop);
void familiar_players_db_insert (FamiliarPlayersDB* self, const char* desktop);
+GAppInfo* music_player_bridge_create_app_info (const char* path);
void music_player_bridge_set_root_menu_item (MusicPlayerBridge* self, DbusmenuMenuitem* menu);
static void music_player_bridge_finalize (GObject* obj);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
@@ -184,6 +200,22 @@ MusicPlayerBridge* music_player_bridge_new (void) {
}
+static gpointer _g_object_ref0 (gpointer self) {
+ return self ? g_object_ref (self) : NULL;
+}
+
+
+static char* string_strip (const char* self) {
+ char* result = NULL;
+ char* _result_;
+ g_return_val_if_fail (self != NULL, NULL);
+ _result_ = g_strdup (self);
+ g_strstrip (_result_);
+ result = _result_;
+ return result;
+}
+
+
static void music_player_bridge_try_to_add_inactive_familiar_clients (MusicPlayerBridge* self) {
GError * _inner_error_;
gint count;
@@ -202,34 +234,43 @@ static void music_player_bridge_try_to_add_inactive_familiar_clients (MusicPlaye
}
app = (char*) gee_iterator_get (_app_it);
if (count == 0) {
- char** _tmp3_;
- gint _bits_size_;
- gint bits_length1;
- char** _tmp2_;
- char** bits;
- g_debug ("music-player-bridge.vala:51: we have found %s", app);
- bits = (_tmp3_ = _tmp2_ = g_strsplit (app, "/", 0), bits_length1 = _vala_array_length (_tmp2_), _bits_size_ = bits_length1, _tmp3_);
+ if (app == NULL) {
+ g_warning ("music-player-bridge.vala:52: App string in keyfile is null therefore m" \
+"oving on to next player");
+ _g_free0 (app);
+ continue;
+ }
{
- gint _tmp5__length1;
- char** _tmp5_;
- char** _tmp4_;
- char* _tmp6_;
- char* app_name;
- PlayerController* ctrl;
GDesktopAppInfo* info;
- char* desc;
- app_name = (_tmp6_ = g_strdup ((_tmp5_ = _tmp4_ = g_strsplit (bits[bits_length1 - 1], ".", 0), _tmp5__length1 = _vala_array_length (_tmp4_), _tmp5_)[0]), _tmp5_ = (_vala_array_free (_tmp5_, _tmp5__length1, (GDestroyNotify) g_free), NULL), _tmp6_);
- g_debug ("music-player-bridge.vala:56: we have found %s", app_name);
- ctrl = player_controller_new (self->priv->root_menu, app_name, FALSE);
- gee_abstract_map_set ((GeeAbstractMap*) self->priv->registered_clients, app_name, ctrl);
- info = g_desktop_app_info_new_from_filename (app_name);
- desc = g_strdup (g_app_info_get_display_name ((GAppInfo*) info));
- g_debug ("music-player-bridge.vala:63: description from app %s", desc);
+ GDesktopAppInfo* _tmp2_;
+ GAppInfo* app_info;
+ PlayerController* ctrl;
+ char* _tmp4_;
+ char* _tmp3_;
+ char* _tmp6_;
+ char* _tmp5_;
+ info = g_desktop_app_info_new_from_filename (app);
+ if (info == NULL) {
+ g_warning ("music-player-bridge.vala:58: Could not create a desktopappinfo instanc" \
+"e from app: %s", app);
+ _g_object_unref0 (info);
+ _g_free0 (app);
+ continue;
+ }
+ app_info = _g_object_ref0 ((_tmp2_ = info, G_IS_APP_INFO (_tmp2_) ? ((GAppInfo*) _tmp2_) : NULL));
+ ctrl = player_controller_new (self->priv->root_menu, g_app_info_get_name (app_info), PLAYER_CONTROLLER_STATE_OFFLINE);
+ g_object_set ((GObject*) ctrl, "app_info", app_info, NULL);
+ gee_abstract_map_set ((GeeAbstractMap*) self->priv->registered_clients, _tmp4_ = string_strip (_tmp3_ = g_utf8_strdown (g_app_info_get_name (app_info), -1)), ctrl);
+ _g_free0 (_tmp4_);
+ _g_free0 (_tmp3_);
+ g_debug ("music-player-bridge.vala:67: Created a player controller for %s which " \
+"was found in the cache file", _tmp6_ = string_strip (_tmp5_ = g_utf8_strdown (g_app_info_get_name (app_info), -1)));
+ _g_free0 (_tmp6_);
+ _g_free0 (_tmp5_);
count = count + 1;
- _g_free0 (app_name);
- _g_object_unref0 (ctrl);
_g_object_unref0 (info);
- _g_free0 (desc);
+ _g_object_unref0 (app_info);
+ _g_object_unref0 (ctrl);
}
goto __finally0;
__catch0_g_error:
@@ -238,21 +279,19 @@ static void music_player_bridge_try_to_add_inactive_familiar_clients (MusicPlaye
er = _inner_error_;
_inner_error_ = NULL;
{
- g_warning ("music-player-bridge.vala:67: desktop path in cache is not formatted as" \
+ g_warning ("music-player-bridge.vala:71: desktop path in cache is not formatted as" \
" we have anticipated");
_g_error_free0 (er);
}
}
__finally0:
if (_inner_error_ != NULL) {
- bits = (_vala_array_free (bits, bits_length1, (GDestroyNotify) g_free), NULL);
_g_free0 (app);
_g_object_unref0 (_app_it);
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
g_clear_error (&_inner_error_);
return;
}
- bits = (_vala_array_free (bits, bits_length1, (GDestroyNotify) g_free), NULL);
}
_g_free0 (app);
break;
@@ -271,7 +310,7 @@ void music_player_bridge_on_server_added (MusicPlayerBridge* self, IndicateListe
gboolean _tmp3_ = FALSE;
g_return_if_fail (self != NULL);
g_return_if_fail (type != NULL);
- g_debug ("music-player-bridge.vala:76: MusicPlayerBridge -> on_server_added with" \
+ g_debug ("music-player-bridge.vala:80: MusicPlayerBridge -> on_server_added with" \
" value %s", type);
if (music_player_bridge_server_is_not_of_interest (self, type)) {
return;
@@ -283,15 +322,32 @@ void music_player_bridge_on_server_added (MusicPlayerBridge* self, IndicateListe
_tmp3_ = FALSE;
}
if (_tmp3_) {
- indicate_listener_get_server_property_cb cb;
- PlayerController* ctrl;
- cb = (indicate_listener_get_server_property_cb) music_player_bridge_desktop_info_callback;
- indicate_listener_server_get_desktop (self->priv->listener, object, cb, self);
- ctrl = player_controller_new (self->priv->root_menu, client_name, TRUE);
- gee_abstract_map_set ((GeeAbstractMap*) self->priv->registered_clients, client_name, ctrl);
- g_debug ("music-player-bridge.vala:84: client of name %s has successfully regist" \
-"ered with us", client_name);
- _g_object_unref0 (ctrl);
+ GeeSet* _tmp4_;
+ gboolean _tmp5_;
+ PlayerController* _tmp8_;
+ gboolean _tmp9_;
+ if ((_tmp5_ = gee_collection_contains ((GeeCollection*) (_tmp4_ = gee_map_get_keys ((GeeMap*) self->priv->registered_clients)), client_name), _g_object_unref0 (_tmp4_), _tmp5_)) {
+ PlayerController* _tmp6_;
+ PlayerController* _tmp7_;
+ g_debug ("music-player-bridge.vala:86: It figured out that it already has an ins" \
+"tance for this player already");
+ player_controller_update_state (_tmp6_ = (PlayerController*) gee_abstract_map_get ((GeeAbstractMap*) self->priv->registered_clients, client_name), PLAYER_CONTROLLER_STATE_READY);
+ _g_object_unref0 (_tmp6_);
+ player_controller_activate (_tmp7_ = (PlayerController*) gee_abstract_map_get ((GeeAbstractMap*) self->priv->registered_clients, client_name));
+ _g_object_unref0 (_tmp7_);
+ } else {
+ PlayerController* ctrl;
+ ctrl = player_controller_new (self->priv->root_menu, client_name, PLAYER_CONTROLLER_STATE_READY);
+ gee_abstract_map_set ((GeeAbstractMap*) self->priv->registered_clients, client_name, ctrl);
+ g_debug ("music-player-bridge.vala:94: New Client of name %s has successfully re" \
+"gistered with us", client_name);
+ _g_object_unref0 (ctrl);
+ }
+ if ((_tmp9_ = player_controller_get_app_info (_tmp8_ = (PlayerController*) gee_abstract_map_get ((GeeAbstractMap*) self->priv->registered_clients, client_name)) == NULL, _g_object_unref0 (_tmp8_), _tmp9_)) {
+ indicate_listener_get_server_property_cb cb;
+ cb = (indicate_listener_get_server_property_cb) music_player_bridge_desktop_info_callback;
+ indicate_listener_server_get_desktop (self->priv->listener, object, cb, self);
+ }
}
_g_free0 (client_name);
}
@@ -306,8 +362,8 @@ void music_player_bridge_on_server_removed (MusicPlayerBridge* self, IndicateLis
gboolean _tmp3_ = FALSE;
g_return_if_fail (self != NULL);
g_return_if_fail (type != NULL);
- g_debug ("music-player-bridge.vala:90: MusicPlayerBridge -> on_server_removed wi" \
-"th value %s", type);
+ g_debug ("music-player-bridge.vala:106: MusicPlayerBridge -> on_server_removed w" \
+"ith value %s", type);
if (music_player_bridge_server_is_not_of_interest (self, type)) {
return;
}
@@ -322,8 +378,8 @@ void music_player_bridge_on_server_removed (MusicPlayerBridge* self, IndicateLis
player_controller_vanish (_tmp4_ = (PlayerController*) gee_abstract_map_get ((GeeAbstractMap*) self->priv->registered_clients, client_name));
_g_object_unref0 (_tmp4_);
gee_map_remove ((GeeMap*) self->priv->registered_clients, client_name, NULL);
- g_debug ("music-player-bridge.vala:96: Successively removed menu_item for client" \
-" %s from registered_clients", client_name);
+ g_debug ("music-player-bridge.vala:112: Successively removed menu_item for clien" \
+"t %s from registered_clients", client_name);
}
_g_free0 (client_name);
}
@@ -347,7 +403,7 @@ static gboolean music_player_bridge_server_is_not_of_interest (MusicPlayerBridge
return result;
}
if (string_contains (type, "music") == FALSE) {
- g_debug ("music-player-bridge.vala:103: server is of no interest, it is not an " \
+ g_debug ("music-player-bridge.vala:120: server is of no interest, it is not an " \
"music server");
result = TRUE;
return result;
@@ -357,19 +413,39 @@ static gboolean music_player_bridge_server_is_not_of_interest (MusicPlayerBridge
}
-static gpointer _g_object_ref0 (gpointer self) {
- return self ? g_object_ref (self) : NULL;
-}
-
-
static void music_player_bridge_desktop_info_callback (MusicPlayerBridge* self, IndicateListenerServer* server, char* path, void* data) {
void* _tmp0_;
MusicPlayerBridge* bridge;
+ gboolean _tmp1_ = FALSE;
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
- g_debug ("music-player-bridge.vala:112: we got a desktop file path hopefully: %s", path);
bridge = _g_object_ref0 ((_tmp0_ = data, IS_MUSIC_PLAYER_BRIDGE (_tmp0_) ? ((MusicPlayerBridge*) _tmp0_) : NULL));
- familiar_players_db_insert (bridge->priv->playersDB, path);
+ if (string_contains (path, "/")) {
+ _tmp1_ = familiar_players_db_already_familiar (bridge->priv->playersDB, path) == FALSE;
+ } else {
+ _tmp1_ = FALSE;
+ }
+ if (_tmp1_) {
+ GAppInfo* app_info;
+ g_debug ("music-player-bridge.vala:131: About to store desktop file path: %s", path);
+ familiar_players_db_insert (bridge->priv->playersDB, path);
+ app_info = music_player_bridge_create_app_info (path);
+ if (app_info != NULL) {
+ char* _tmp3_;
+ char* _tmp2_;
+ PlayerController* _tmp4_;
+ PlayerController* ctrl;
+ ctrl = (_tmp4_ = (PlayerController*) gee_abstract_map_get ((GeeAbstractMap*) bridge->priv->registered_clients, _tmp3_ = string_strip (_tmp2_ = g_utf8_strdown (g_app_info_get_name (app_info), -1))), _g_free0 (_tmp3_), _g_free0 (_tmp2_), _tmp4_);
+ g_object_set ((GObject*) ctrl, "app_info", app_info, NULL);
+ g_debug ("music-player-bridge.vala:137: successfully created appinfo from path a" \
+"nd set it on the respective instance");
+ _g_object_unref0 (ctrl);
+ }
+ _g_object_unref0 (app_info);
+ } else {
+ g_debug ("music-player-bridge.vala:141: Ignoring desktop file path because its e" \
+"ither invalid of the db cache file has it already: %s", path);
+ }
_g_object_unref0 (bridge);
_g_free0 (path);
}
@@ -380,25 +456,26 @@ void music_player_bridge_set_root_menu_item (MusicPlayerBridge* self, DbusmenuMe
g_return_if_fail (self != NULL);
g_return_if_fail (menu != NULL);
self->priv->root_menu = (_tmp0_ = _g_object_ref0 (menu), _g_object_unref0 (self->priv->root_menu), _tmp0_);
+ music_player_bridge_try_to_add_inactive_familiar_clients (self);
}
void music_player_bridge_on_server_count_changed (MusicPlayerBridge* self, IndicateListenerServer* object, guint i) {
g_return_if_fail (self != NULL);
- g_debug ("music-player-bridge.vala:125: MusicPlayerBridge-> on_server_count_chan" \
+ g_debug ("music-player-bridge.vala:153: MusicPlayerBridge-> on_server_count_chan" \
"ged with value %u", i);
}
void music_player_bridge_on_indicator_added (MusicPlayerBridge* self, IndicateListenerServer* object, IndicateListenerIndicator* p0) {
g_return_if_fail (self != NULL);
- g_debug ("music-player-bridge.vala:129: MusicPlayerBridge-> on_indicator_added");
+ g_debug ("music-player-bridge.vala:157: MusicPlayerBridge-> on_indicator_added");
}
void music_player_bridge_on_indicator_removed (MusicPlayerBridge* self, IndicateListenerServer* object, IndicateListenerIndicator* p0) {
g_return_if_fail (self != NULL);
- g_debug ("music-player-bridge.vala:134: MusicPlayerBridge -> on_indicator_remove" \
+ g_debug ("music-player-bridge.vala:162: MusicPlayerBridge -> on_indicator_remove" \
"d");
}
@@ -406,11 +483,32 @@ void music_player_bridge_on_indicator_removed (MusicPlayerBridge* self, Indicate
void music_player_bridge_on_indicator_modified (MusicPlayerBridge* self, IndicateListenerServer* object, IndicateListenerIndicator* p0, const char* s) {
g_return_if_fail (self != NULL);
g_return_if_fail (s != NULL);
- g_debug ("music-player-bridge.vala:139: MusicPlayerBridge -> indicator_modified " \
+ g_debug ("music-player-bridge.vala:167: MusicPlayerBridge -> indicator_modified " \
"with vale %s", s);
}
+GAppInfo* music_player_bridge_create_app_info (const char* path) {
+ GAppInfo* result = NULL;
+ GDesktopAppInfo* info;
+ GDesktopAppInfo* _tmp0_;
+ GAppInfo* app_info;
+ g_return_val_if_fail (path != NULL, NULL);
+ info = g_desktop_app_info_new_from_filename (path);
+ if (path == NULL) {
+ g_warning ("music-player-bridge.vala:174: Could not create a desktopappinfo instan" \
+"ce from app: %s", path);
+ result = NULL;
+ _g_object_unref0 (info);
+ return result;
+ }
+ app_info = _g_object_ref0 ((_tmp0_ = info, G_IS_APP_INFO (_tmp0_) ? ((GAppInfo*) _tmp0_) : NULL));
+ result = app_info;
+ _g_object_unref0 (info);
+ return result;
+}
+
+
static void music_player_bridge_class_init (MusicPlayerBridgeClass * klass) {
music_player_bridge_parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (klass, sizeof (MusicPlayerBridgePrivate));
diff --git a/src/music-player-bridge.h b/src/music-player-bridge.h
index 26fe9c3..d2a031e 100644
--- a/src/music-player-bridge.h
+++ b/src/music-player-bridge.h
@@ -17,6 +17,7 @@
#include <libdbusmenu-glib/menuitem-proxy.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
+#include <gio/gio.h>
#include <gee.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
@@ -46,16 +47,6 @@ typedef struct _PlayerItem PlayerItem;
typedef struct _PlayerItemClass PlayerItemClass;
typedef struct _PlayerItemPrivate PlayerItemPrivate;
-#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
-#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
-#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
-#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
-#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-
-typedef struct _MprisController MprisController;
-typedef struct _MprisControllerClass MprisControllerClass;
-
#define TYPE_TRANSPORT_MENUITEM (transport_menuitem_get_type ())
#define TRANSPORT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TRANSPORT_MENUITEM, TransportMenuitem))
#define TRANSPORT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TRANSPORT_MENUITEM, TransportMenuitemClass))
@@ -67,6 +58,18 @@ typedef struct _TransportMenuitem TransportMenuitem;
typedef struct _TransportMenuitemClass TransportMenuitemClass;
typedef struct _TransportMenuitemPrivate TransportMenuitemPrivate;
+#define TRANSPORT_MENUITEM_TYPE_ACTION (transport_menuitem_action_get_type ())
+
+#define TYPE_PLAYER_CONTROLLER (player_controller_get_type ())
+#define PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLAYER_CONTROLLER, PlayerController))
+#define PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+#define IS_PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLAYER_CONTROLLER))
+#define IS_PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLAYER_CONTROLLER))
+#define PLAYER_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+
+typedef struct _PlayerController PlayerController;
+typedef struct _PlayerControllerClass PlayerControllerClass;
+
#define TYPE_METADATA_MENUITEM (metadata_menuitem_get_type ())
#define METADATA_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_METADATA_MENUITEM, MetadataMenuitem))
#define METADATA_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_METADATA_MENUITEM, MetadataMenuitemClass))
@@ -78,16 +81,29 @@ typedef struct _MetadataMenuitem MetadataMenuitem;
typedef struct _MetadataMenuitemClass MetadataMenuitemClass;
typedef struct _MetadataMenuitemPrivate MetadataMenuitemPrivate;
-#define TYPE_PLAYER_CONTROLLER (player_controller_get_type ())
-#define PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLAYER_CONTROLLER, PlayerController))
-#define PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
-#define IS_PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLAYER_CONTROLLER))
-#define IS_PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLAYER_CONTROLLER))
-#define PLAYER_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+#define TYPE_TITLE_MENUITEM (title_menuitem_get_type ())
+#define TITLE_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TITLE_MENUITEM, TitleMenuitem))
+#define TITLE_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TITLE_MENUITEM, TitleMenuitemClass))
+#define IS_TITLE_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TITLE_MENUITEM))
+#define IS_TITLE_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TITLE_MENUITEM))
+#define TITLE_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TITLE_MENUITEM, TitleMenuitemClass))
-typedef struct _PlayerController PlayerController;
-typedef struct _PlayerControllerClass PlayerControllerClass;
+typedef struct _TitleMenuitem TitleMenuitem;
+typedef struct _TitleMenuitemClass TitleMenuitemClass;
+typedef struct _TitleMenuitemPrivate TitleMenuitemPrivate;
typedef struct _PlayerControllerPrivate PlayerControllerPrivate;
+
+#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
+#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
+#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
+#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
+#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+
+typedef struct _MprisController MprisController;
+typedef struct _MprisControllerClass MprisControllerClass;
+
+#define PLAYER_CONTROLLER_TYPE_STATE (player_controller_state_get_type ())
typedef struct _MprisControllerPrivate MprisControllerPrivate;
#define TYPE_MPRIS_CONTROLLER_V2 (mpris_controller_v2_get_type ())
@@ -124,12 +140,10 @@ struct _MusicPlayerBridgeClass {
struct _PlayerItem {
DbusmenuMenuitem parent_instance;
PlayerItemPrivate * priv;
- MprisController* mpris_adaptor;
};
struct _PlayerItemClass {
DbusmenuMenuitemClass parent_class;
- void (*check_layout) (PlayerItem* self);
};
struct _TransportMenuitem {
@@ -141,6 +155,12 @@ struct _TransportMenuitemClass {
PlayerItemClass parent_class;
};
+typedef enum {
+ TRANSPORT_MENUITEM_ACTION_PREVIOUS,
+ TRANSPORT_MENUITEM_ACTION_PLAY_PAUSE,
+ TRANSPORT_MENUITEM_ACTION_NEXT
+} TransportMenuitemaction;
+
struct _MetadataMenuitem {
PlayerItem parent_instance;
MetadataMenuitemPrivate * priv;
@@ -150,16 +170,35 @@ struct _MetadataMenuitemClass {
PlayerItemClass parent_class;
};
+struct _TitleMenuitem {
+ PlayerItem parent_instance;
+ TitleMenuitemPrivate * priv;
+};
+
+struct _TitleMenuitemClass {
+ PlayerItemClass parent_class;
+};
+
struct _PlayerController {
GObject parent_instance;
PlayerControllerPrivate * priv;
+ gint current_state;
GeeArrayList* custom_items;
+ MprisController* mpris_adaptor;
};
struct _PlayerControllerClass {
GObjectClass parent_class;
};
+typedef enum {
+ PLAYER_CONTROLLER_STATE_OFFLINE,
+ PLAYER_CONTROLLER_STATE_INSTANTIATING,
+ PLAYER_CONTROLLER_STATE_READY,
+ PLAYER_CONTROLLER_STATE_CONNECTED,
+ PLAYER_CONTROLLER_STATE_DISCONNECTED
+} PlayerControllerstate;
+
struct _MprisController {
GObject parent_instance;
MprisControllerPrivate * priv;
@@ -199,11 +238,13 @@ void music_player_bridge_on_server_count_changed (MusicPlayerBridge* self, Indic
void music_player_bridge_on_indicator_added (MusicPlayerBridge* self, IndicateListenerServer* object, IndicateListenerIndicator* p0);
void music_player_bridge_on_indicator_removed (MusicPlayerBridge* self, IndicateListenerServer* object, IndicateListenerIndicator* p0);
void music_player_bridge_on_indicator_modified (MusicPlayerBridge* self, IndicateListenerServer* object, IndicateListenerIndicator* p0, const char* s);
+GAppInfo* music_player_bridge_create_app_info (const char* path);
GType player_item_get_type (void);
-GType mpris_controller_get_type (void);
GType transport_menuitem_get_type (void);
-TransportMenuitem* transport_menuitem_new (void);
-TransportMenuitem* transport_menuitem_construct (GType object_type);
+GType transport_menuitem_action_get_type (void);
+GType player_controller_get_type (void);
+TransportMenuitem* transport_menuitem_new (PlayerController* parent);
+TransportMenuitem* transport_menuitem_construct (GType object_type, PlayerController* parent);
void transport_menuitem_change_play_state (TransportMenuitem* self, gint state);
GeeHashSet* transport_menuitem_attributes_format (void);
GType metadata_menuitem_get_type (void);
@@ -211,26 +252,37 @@ MetadataMenuitem* metadata_menuitem_new (void);
MetadataMenuitem* metadata_menuitem_construct (GType object_type);
GeeHashSet* metadata_menuitem_attributes_format (void);
gboolean metadata_menuitem_populated (MetadataMenuitem* self);
-GType player_controller_get_type (void);
+GType title_menuitem_get_type (void);
+TitleMenuitem* title_menuitem_new (PlayerController* parent, const char* name);
+TitleMenuitem* title_menuitem_construct (GType object_type, PlayerController* parent, const char* name);
+GeeHashSet* title_menuitem_attributes_format (void);
+GType mpris_controller_get_type (void);
+GType player_controller_state_get_type (void);
#define PLAYER_CONTROLLER_METADATA 2
-PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, gboolean active);
-PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, gboolean active);
+PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state);
+PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state);
+void player_controller_update_state (PlayerController* self, PlayerControllerstate new_state);
+void player_controller_activate (PlayerController* self);
+void player_controller_instantiate (PlayerController* self);
void player_controller_vanish (PlayerController* self);
+const char* player_controller_get_name (PlayerController* self);
+void player_controller_set_name (PlayerController* self, const char* value);
+GAppInfo* player_controller_get_app_info (PlayerController* self);
+void player_controller_set_app_info (PlayerController* self, GAppInfo* value);
GType mpris_controller_v2_get_type (void);
MprisControllerV2* mpris_controller_v2_new (const char* name, PlayerController* controller);
MprisControllerV2* mpris_controller_v2_construct (GType object_type, const char* name, PlayerController* controller);
MprisController* mpris_controller_new (const char* name, PlayerController* controller, const char* mpris_interface);
MprisController* mpris_controller_construct (GType object_type, const char* name, PlayerController* controller, const char* mpris_interface);
-void mpris_controller_toggle_playback (MprisController* self, gboolean state);
-PlayerItem* player_item_new (void);
-PlayerItem* player_item_construct (GType object_type);
+void mpris_controller_transport_event (MprisController* self, TransportMenuitemaction command);
+gboolean mpris_controller_connected (MprisController* self);
+PlayerItem* player_item_new (const char* type);
+PlayerItem* player_item_construct (GType object_type, const char* type);
void player_item_reset (PlayerItem* self, GeeHashSet* attrs);
void player_item_update (PlayerItem* self, GHashTable* data, GeeHashSet* attributes);
-void player_item_set_adaptor (PlayerItem* self, MprisController* adaptor);
char* player_item_sanitize_string (const char* st);
-PlayerItem* player_item_new_title_item (const char* name);
-PlayerItem* player_item_new_separator_item (void);
-void player_item_check_layout (PlayerItem* self);
+PlayerController* player_item_get_owner (PlayerItem* self);
+const char* player_item_get_item_type (PlayerItem* self);
GType familiar_players_db_get_type (void);
FamiliarPlayersDB* familiar_players_db_new (void);
FamiliarPlayersDB* familiar_players_db_construct (GType object_type);
diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala
index 6fc9032..d771192 100644
--- a/src/music-player-bridge.vala
+++ b/src/music-player-bridge.vala
@@ -42,25 +42,29 @@ public class MusicPlayerBridge : GLib.Object
listener.server_removed.connect(on_server_removed);
listener.server_count_changed.connect(on_server_count_changed);
}
- // Alpha 2 not in use ... yet.
+
private void try_to_add_inactive_familiar_clients(){
- // for now just use one of the entries.
+ // TODO handle multple players - just working with one right now
int count = 0;
foreach(string app in this.playersDB.records()){
if(count == 0){
- debug("we have found %s", app);
- string[] bits = app.split("/");
-
+ if(app == null){
+ warning("App string in keyfile is null therefore moving on to next player");
+ continue;
+ }
try{
- string app_name = bits[bits.length -1].split(".")[0];
- debug("we have found %s", app_name);
+ DesktopAppInfo info = new DesktopAppInfo.from_filename(app);
+ if(info == null){
+ warning("Could not create a desktopappinfo instance from app: %s", app);
+ continue;
+ }
+ GLib.AppInfo app_info = info as GLib.AppInfo;
PlayerController ctrl = new PlayerController(this.root_menu,
- app_name,
- false);
- this.registered_clients.set(app_name, ctrl);
- DesktopAppInfo info = new DesktopAppInfo.from_filename(app_name);
- string desc = info.get_display_name();
- debug("description from app %s", desc);
+ app_info.get_name(),
+ PlayerController.state.OFFLINE);
+ ctrl.set("app_info", app_info);
+ this.registered_clients.set(app_info.get_name().down().strip(), ctrl);
+ debug("Created a player controller for %s which was found in the cache file", app_info.get_name().down().strip());
count += 1;
}
catch(Error er){
@@ -75,13 +79,25 @@ public class MusicPlayerBridge : GLib.Object
{
debug("MusicPlayerBridge -> on_server_added with value %s", type);
if(server_is_not_of_interest(type)) return;
- string client_name = type.split(".")[1];
+ string client_name = type.split(".")[1];
if (root_menu != null && client_name != null){
- listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback;
- this.listener.server_get_desktop(object, cb, this);
- PlayerController ctrl = new PlayerController(root_menu, client_name, true);
- registered_clients.set(client_name, ctrl);
- debug("client of name %s has successfully registered with us", client_name);
+ // If we have an instance already for this player, ensure it is switched to active
+ if(this.registered_clients.keys.contains(client_name)){
+ debug("It figured out that it already has an instance for this player already");
+ this.registered_clients[client_name].update_state(PlayerController.state.READY);
+ this.registered_clients[client_name].activate();
+ }
+ //else init a new one
+ else{
+ PlayerController ctrl = new PlayerController(root_menu, client_name, PlayerController.state.READY);
+ registered_clients.set(client_name, ctrl);
+ debug("New Client of name %s has successfully registered with us", client_name);
+ }
+ // irregardless check that it has a desktop file if not kick off a request for it
+ if(this.registered_clients[client_name].app_info == null){
+ listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback;
+ this.listener.server_get_desktop(object, cb, this);
+ }
}
}
@@ -93,7 +109,8 @@ public class MusicPlayerBridge : GLib.Object
if (root_menu != null && client_name != null){
registered_clients[client_name].vanish();
registered_clients.remove(client_name);
- debug("Successively removed menu_item for client %s from registered_clients", client_name);
+ debug("Successively removed menu_item for client %s from registered_clients",
+ client_name);
}
}
@@ -109,15 +126,26 @@ public class MusicPlayerBridge : GLib.Object
private void desktop_info_callback(Indicate.ListenerServer server,
owned string path, void* data)
{
- debug("we got a desktop file path hopefully: %s", path);
MusicPlayerBridge bridge = data as MusicPlayerBridge;
- bridge.playersDB.insert(path);
+ if(path.contains("/") && bridge.playersDB.already_familiar(path) == false){
+ debug("About to store desktop file path: %s", path);
+ bridge.playersDB.insert(path);
+ AppInfo? app_info = create_app_info(path);
+ if(app_info != null){
+ PlayerController ctrl = bridge.registered_clients[app_info.get_name().down().strip()];
+ ctrl.set("app_info", app_info);
+ debug("successfully created appinfo from path and set it on the respective instance");
+ }
+ }
+ else{
+ debug("Ignoring desktop file path because its either invalid of the db cache file has it already: %s", path);
+ }
}
public void set_root_menu_item(Dbusmenu.Menuitem menu)
{
this.root_menu = menu;
- //try_to_add_inactive_familiar_clients();
+ try_to_add_inactive_familiar_clients();
}
public void on_server_count_changed(Indicate.ListenerServer object, uint i)
@@ -139,6 +167,17 @@ public class MusicPlayerBridge : GLib.Object
debug("MusicPlayerBridge -> indicator_modified with vale %s", s );
}
+ public static AppInfo? create_app_info(string path)
+ {
+ DesktopAppInfo info = new DesktopAppInfo.from_filename(path);
+ if(path == null){
+ warning("Could not create a desktopappinfo instance from app: %s", path);
+ return null;
+ }
+ GLib.AppInfo app_info = info as GLib.AppInfo;
+ return app_info;
+ }
+
}
diff --git a/src/play-button.c b/src/play-button.c
new file mode 100644
index 0000000..2fddbcf
--- /dev/null
+++ b/src/play-button.c
@@ -0,0 +1,800 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+ Mirco Müller <mirco.mueller@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+
+Uses code from ctk
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "play-button.h"
+
+#define RECT_WIDTH 130.0f
+#define Y 15.0f
+#define X 22.0f
+#define INNER_RADIUS 12.5
+#define MIDDLE_RADIUS 13.5f
+#define OUTER_RADIUS 14.5f
+#define CIRCLE_RADIUS 19.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 20.0f
+#define PREV_Y 21.0f
+#define NEXT_X 98.0f
+#define NEXT_Y 21.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 62.0f
+#define PAUSE_Y 15.0f
+
+// Transport events
+enum {
+ PREVIOUS,
+ PLAY_PAUSE,
+ NEXT
+};
+
+typedef struct _PlayButtonPrivate PlayButtonPrivate;
+
+struct _PlayButtonPrivate
+{
+ GdkColor background_colour_fg;
+ GdkColor background_colour_bg_dark;
+ GdkColor background_colour_bg_light;
+ GdkColor foreground_colour_fg;
+ GdkColor foreground_colour_bg;
+};
+
+#define PLAY_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PLAY_BUTTON_TYPE, PlayButtonPrivate))
+
+/* Gobject boiler plate */
+static void play_button_class_init (PlayButtonClass *klass);
+static void play_button_init (PlayButton *self);
+static void play_button_dispose (GObject *object);
+static void play_button_finalize (GObject *object);
+
+static gboolean play_button_expose (GtkWidget *button, GdkEventExpose *event);
+static void draw (GtkWidget* button, cairo_t *cr);
+
+G_DEFINE_TYPE (PlayButton, play_button, GTK_TYPE_DRAWING_AREA);
+
+/// internal helper functions //////////////////////////////////////////////////
+
+static double
+_align (double val)
+{
+ double fract = val - (int) val;
+
+ if (fract != 0.5f)
+ return (double) ((int) val + 0.5f);
+ else
+ return val;
+}
+
+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);
+}
+
+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;
+}
+
+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);
+}
+
+/// GObject functions //////////////////////////////////////////////////////////
+
+static void
+play_button_class_init (PlayButtonClass *klass)
+{
+
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (PlayButtonPrivate));
+
+ widget_class->expose_event = play_button_expose;
+
+ gobject_class->dispose = play_button_dispose;
+ gobject_class->finalize = play_button_finalize;
+}
+
+static void
+play_button_init (PlayButton *self)
+{
+ gtk_widget_set_size_request(GTK_WIDGET(self), 200, 80);
+}
+
+static void
+play_button_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (play_button_parent_class)->dispose (object);
+}
+
+static void
+play_button_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (play_button_parent_class)->finalize (object);
+}
+
+static gboolean
+play_button_expose (GtkWidget *button, GdkEventExpose *event)
+{
+ cairo_t *cr;
+ cr = gdk_cairo_create (button->window);
+
+ cairo_rectangle (cr,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+
+ cairo_clip(cr);
+ draw (button, cr);
+ cairo_destroy (cr);
+ return FALSE;
+}
+
+
+gint
+determine_button_event(GtkWidget* button, GdkEventButton* event)
+{
+ g_debug("event x coordinate = %f", event->x);
+ g_debug("event y coordinate = %f", event->y);
+ gint result = 0;
+ // For now very simple rectangular collision detection
+ if(event->x > 40 && event->x < 80
+ && event->y > 22 && event->y < 46){
+ result = PREVIOUS;
+ }
+ else if(event->x > 86 && event->x < 118
+ && event->y > 20 && event->y < 47){
+ result = PLAY_PAUSE;
+ }
+ else if(event->x > 122 && event->x < 164
+ && event->y > 22 && event->y < 46){
+ result = NEXT;
+ }
+
+ return result;
+}
+
+void
+play_button_set_style(GtkWidget* button, GtkStyle* style)
+{
+ PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(button);
+ priv->background_colour_fg = style->fg[GTK_STATE_NORMAL];
+ priv->background_colour_bg_dark = style->bg[GTK_STATE_NORMAL];
+ priv->background_colour_bg_light = style->base[GTK_STATE_NORMAL];
+ priv->foreground_colour_fg = style->fg[GTK_STATE_PRELIGHT];
+ priv->foreground_colour_bg = style->bg[GTK_STATE_NORMAL];
+}
+
+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
+_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
+draw (GtkWidget* button, cairo_t *cr)
+{
+ cairo_surface_t* surf = NULL;
+ cairo_t* cr_surf = NULL;
+
+ double INNER_START[] = {229.0f/255.0f, 223.0f/255.0f, 215.0f/255.0f, 1.0f};
+ double INNER_END[] = {183.0f / 255.0f, 178.0f / 255.0f, 172.0f / 255.0f, 1.0f};
+ double MIDDLE_START[] = {61.0f / 255.0f, 60.0f / 255.0f, 57.0f / 255.0f, 1.0f};
+ double MIDDLE_END[] = {94.0f / 255.0f,93.0f / 255.0f, 90.0f / 255.0f,1.0f};
+ double OUTER_START[] = {36.0f / 255.0f, 35.0f / 255.0f, 33.0f / 255.0f, 1.0f};
+ double OUTER_END[] = {123.0f / 255.0f, 123.0f / 255.0f, 120.0f / 255.0f, 1.0f};
+ double BUTTON_START[] = {252.0f / 255.0f, 251.0f / 255.0f, 251.0f / 255.0f,1.0f};
+ double BUTTON_END[] = {186.0f / 255.0f,180.0f / 255.0f, 170.0f / 255.0f, 1.0f};
+ double BUTTON_SHADOW[] = {0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 0.75f};
+
+
+ // prev/next-background
+ 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,
+ INNER_RADIUS,
+ INNER_START,
+ INNER_END);
+
+ // play/pause-background
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 4.5f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)),
+ CIRCLE_RADIUS,
+ OUTER_START,
+ OUTER_END);
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 4.5f + 1.0f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.0f,
+ CIRCLE_RADIUS - 1,
+ MIDDLE_START,
+ MIDDLE_END);
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 4.5f + 2.0f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 2.0f,
+ CIRCLE_RADIUS - 2.0f,
+ INNER_START,
+ INNER_END);
+
+ // draw previous-button drop-shadow
+ _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, 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, PREV_X, PREV_Y);
+
+ // draw next-button drop-shadow
+ _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, 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, NEXT_X, NEXT_Y);
+
+ // draw pause-button drop-shadow
+ _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, 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, PAUSE_X, PAUSE_Y);
+}
+
+
+/**
+* play_button_new:
+* @returns: a new #PlayButton.
+**/
+GtkWidget*
+play_button_new()
+{
+
+ GtkWidget* widget = g_object_new(PLAY_BUTTON_TYPE, NULL);
+ gtk_widget_set_app_paintable (widget, TRUE);
+ return widget;
+}
+
diff --git a/src/play-button.h b/src/play-button.h
new file mode 100644
index 0000000..3eaabcc
--- /dev/null
+++ b/src/play-button.h
@@ -0,0 +1,53 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef __PLAY_BUTTON_H__
+#define __PLAY_BUTTON_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PLAY_BUTTON_TYPE (play_button_get_type ())
+#define PLAY_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLAY_BUTTON_TYPE, PlayButton))
+#define PLAY_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PLAY_BUTTON_TYPE, PlayButtonClass))
+#define IS_PLAY_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PLAY_BUTTON_TYPE))
+#define IS_PLAY_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PLAY_BUTTON_TYPE))
+#define PLAY_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PLAY_BUTTON_TYPE, PlayButtonClass))
+
+typedef struct _PlayButton PlayButton;
+typedef struct _PlayButtonClass PlayButtonClass;
+
+struct _PlayButtonClass {
+ GtkDrawingAreaClass parent_class;
+};
+
+struct _PlayButton {
+ GtkDrawingArea parent;
+};
+
+GType play_button_get_type (void);
+void play_button_set_style(GtkWidget* button, GtkStyle* style);
+gint determine_button_event(GtkWidget* button, GdkEventButton* event);
+
+GtkWidget* play_button_new();
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/player-controller.c b/src/player-controller.c
index 5c4e0cc..bbdbcbf 100644
--- a/src/player-controller.c
+++ b/src/player-controller.c
@@ -30,6 +30,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/server.h>
#include <stdlib.h>
#include <string.h>
+#include <gio/gio.h>
#define TYPE_PLAYER_CONTROLLER (player_controller_get_type ())
@@ -62,8 +63,11 @@ typedef struct _PlayerItemClass PlayerItemClass;
typedef struct _MprisController MprisController;
typedef struct _MprisControllerClass MprisControllerClass;
+
+#define PLAYER_CONTROLLER_TYPE_STATE (player_controller_state_get_type ())
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define TYPE_MPRIS_CONTROLLER_V2 (mpris_controller_v2_get_type ())
#define MPRIS_CONTROLLER_V2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER_V2, MprisControllerV2))
@@ -75,6 +79,16 @@ typedef struct _MprisControllerClass MprisControllerClass;
typedef struct _MprisControllerV2 MprisControllerV2;
typedef struct _MprisControllerV2Class MprisControllerV2Class;
+#define TYPE_TITLE_MENUITEM (title_menuitem_get_type ())
+#define TITLE_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TITLE_MENUITEM, TitleMenuitem))
+#define TITLE_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TITLE_MENUITEM, TitleMenuitemClass))
+#define IS_TITLE_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TITLE_MENUITEM))
+#define IS_TITLE_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TITLE_MENUITEM))
+#define TITLE_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TITLE_MENUITEM, TitleMenuitemClass))
+
+typedef struct _TitleMenuitem TitleMenuitem;
+typedef struct _TitleMenuitemClass TitleMenuitemClass;
+
#define TYPE_METADATA_MENUITEM (metadata_menuitem_get_type ())
#define METADATA_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_METADATA_MENUITEM, MetadataMenuitem))
#define METADATA_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_METADATA_MENUITEM, MetadataMenuitemClass))
@@ -98,7 +112,9 @@ typedef struct _TransportMenuitemClass TransportMenuitemClass;
struct _PlayerController {
GObject parent_instance;
PlayerControllerPrivate * priv;
+ gint current_state;
GeeArrayList* custom_items;
+ MprisController* mpris_adaptor;
};
struct _PlayerControllerClass {
@@ -107,12 +123,18 @@ struct _PlayerControllerClass {
struct _PlayerControllerPrivate {
DbusmenuMenuitem* root_menu;
- char* name;
- gboolean is_active;
- MprisController* mpris_adaptor;
- char* desktop_path;
+ char* _name;
+ GAppInfo* _app_info;
};
+typedef enum {
+ PLAYER_CONTROLLER_STATE_OFFLINE,
+ PLAYER_CONTROLLER_STATE_INSTANTIATING,
+ PLAYER_CONTROLLER_STATE_READY,
+ PLAYER_CONTROLLER_STATE_CONNECTED,
+ PLAYER_CONTROLLER_STATE_DISCONNECTED
+} PlayerControllerstate;
+
static gpointer player_controller_parent_class = NULL;
@@ -121,34 +143,63 @@ GType player_item_get_type (void);
GType mpris_controller_get_type (void);
#define PLAYER_CONTROLLER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_PLAYER_CONTROLLER, PlayerControllerPrivate))
enum {
- PLAYER_CONTROLLER_DUMMY_PROPERTY
+ PLAYER_CONTROLLER_DUMMY_PROPERTY,
+ PLAYER_CONTROLLER_NAME,
+ PLAYER_CONTROLLER_APP_INFO
};
+GType player_controller_state_get_type (void);
#define PLAYER_CONTROLLER_METADATA 2
#define PLAYER_CONTROLLER_TRANSPORT 3
static char* player_controller_format_client_name (const char* client_name);
-static gboolean player_controller_self_construct (PlayerController* self);
+void player_controller_set_name (PlayerController* self, const char* value);
+void player_controller_update_state (PlayerController* self, PlayerControllerstate new_state);
+static void player_controller_construct_widgets (PlayerController* self);
+static void player_controller_establish_mpris_connection (PlayerController* self);
+static void player_controller_update_layout (PlayerController* self);
+PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state);
+PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state);
+void player_controller_activate (PlayerController* self);
+GAppInfo* player_controller_get_app_info (PlayerController* self);
+const char* player_controller_get_name (PlayerController* self);
+void player_controller_instantiate (PlayerController* self);
MprisControllerV2* mpris_controller_v2_new (const char* name, PlayerController* controller);
MprisControllerV2* mpris_controller_v2_construct (GType object_type, const char* name, PlayerController* controller);
GType mpris_controller_v2_get_type (void);
MprisController* mpris_controller_new (const char* name, PlayerController* controller, const char* mpris_interface);
MprisController* mpris_controller_construct (GType object_type, const char* name, PlayerController* controller, const char* mpris_interface);
-void player_item_set_adaptor (PlayerItem* self, MprisController* adaptor);
-PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, gboolean active);
-PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, gboolean active);
+gboolean mpris_controller_connected (MprisController* self);
void player_controller_vanish (PlayerController* self);
-PlayerItem* player_item_new_separator_item (void);
-PlayerItem* player_item_new_title_item (const char* name);
+PlayerItem* player_item_new (const char* type);
+PlayerItem* player_item_construct (GType object_type, const char* type);
+TitleMenuitem* title_menuitem_new (PlayerController* parent, const char* name);
+TitleMenuitem* title_menuitem_construct (GType object_type, PlayerController* parent, const char* name);
+GType title_menuitem_get_type (void);
MetadataMenuitem* metadata_menuitem_new (void);
MetadataMenuitem* metadata_menuitem_construct (GType object_type);
GType metadata_menuitem_get_type (void);
-TransportMenuitem* transport_menuitem_new (void);
-TransportMenuitem* transport_menuitem_construct (GType object_type);
+TransportMenuitem* transport_menuitem_new (PlayerController* parent);
+TransportMenuitem* transport_menuitem_construct (GType object_type, PlayerController* parent);
GType transport_menuitem_get_type (void);
+void player_controller_set_app_info (PlayerController* self, GAppInfo* value);
static void player_controller_finalize (GObject* obj);
+static void player_controller_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
+static void player_controller_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
static int _vala_strcmp0 (const char * str1, const char * str2);
+GType player_controller_state_get_type (void) {
+ static volatile gsize player_controller_state_type_id__volatile = 0;
+ if (g_once_init_enter (&player_controller_state_type_id__volatile)) {
+ static const GEnumValue values[] = {{PLAYER_CONTROLLER_STATE_OFFLINE, "PLAYER_CONTROLLER_STATE_OFFLINE", "offline"}, {PLAYER_CONTROLLER_STATE_INSTANTIATING, "PLAYER_CONTROLLER_STATE_INSTANTIATING", "instantiating"}, {PLAYER_CONTROLLER_STATE_READY, "PLAYER_CONTROLLER_STATE_READY", "ready"}, {PLAYER_CONTROLLER_STATE_CONNECTED, "PLAYER_CONTROLLER_STATE_CONNECTED", "connected"}, {PLAYER_CONTROLLER_STATE_DISCONNECTED, "PLAYER_CONTROLLER_STATE_DISCONNECTED", "disconnected"}, {0, NULL, NULL}};
+ GType player_controller_state_type_id;
+ player_controller_state_type_id = g_enum_register_static ("PlayerControllerstate", values);
+ g_once_init_leave (&player_controller_state_type_id__volatile, player_controller_state_type_id);
+ }
+ return player_controller_state_type_id__volatile;
+}
+
+
static gpointer _g_object_ref0 (gpointer self) {
return self ? g_object_ref (self) : NULL;
}
@@ -165,37 +216,101 @@ static char* string_strip (const char* self) {
}
-PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, gboolean active) {
+PlayerController* player_controller_construct (GType object_type, DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state) {
PlayerController * self;
DbusmenuMenuitem* _tmp0_;
char* _tmp2_;
char* _tmp1_;
GeeArrayList* _tmp3_;
- PlayerItem* _tmp6_;
g_return_val_if_fail (root != NULL, NULL);
g_return_val_if_fail (client_name != NULL, NULL);
self = (PlayerController*) g_object_new (object_type, NULL);
self->priv->root_menu = (_tmp0_ = _g_object_ref0 (root), _g_object_unref0 (self->priv->root_menu), _tmp0_);
- self->priv->name = (_tmp2_ = player_controller_format_client_name (_tmp1_ = string_strip (client_name)), _g_free0 (self->priv->name), _tmp2_);
+ player_controller_set_name (self, _tmp2_ = player_controller_format_client_name (_tmp1_ = string_strip (client_name)));
+ _g_free0 (_tmp2_);
_g_free0 (_tmp1_);
- self->priv->is_active = active;
self->custom_items = (_tmp3_ = gee_array_list_new (TYPE_PLAYER_ITEM, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL), _g_object_unref0 (self->custom_items), _tmp3_);
- player_controller_self_construct (self);
- if (_vala_strcmp0 (self->priv->name, "Vlc") == 0) {
- MprisController* _tmp4_;
- self->priv->mpris_adaptor = (_tmp4_ = (MprisController*) mpris_controller_v2_new (self->priv->name, self), _g_object_unref0 (self->priv->mpris_adaptor), _tmp4_);
- } else {
- MprisController* _tmp5_;
- self->priv->mpris_adaptor = (_tmp5_ = mpris_controller_new (self->priv->name, self, "org.freedesktop.MediaPlayer"), _g_object_unref0 (self->priv->mpris_adaptor), _tmp5_);
- }
- player_item_set_adaptor (_tmp6_ = (PlayerItem*) gee_abstract_list_get ((GeeAbstractList*) self->custom_items, PLAYER_CONTROLLER_TRANSPORT), self->priv->mpris_adaptor);
- _g_object_unref0 (_tmp6_);
+ player_controller_update_state (self, initial_state);
+ player_controller_construct_widgets (self);
+ player_controller_establish_mpris_connection (self);
+ player_controller_update_layout (self);
return self;
}
-PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, gboolean active) {
- return player_controller_construct (TYPE_PLAYER_CONTROLLER, root, client_name, active);
+PlayerController* player_controller_new (DbusmenuMenuitem* root, const char* client_name, PlayerControllerstate initial_state) {
+ return player_controller_construct (TYPE_PLAYER_CONTROLLER, root, client_name, initial_state);
+}
+
+
+void player_controller_update_state (PlayerController* self, PlayerControllerstate new_state) {
+ g_return_if_fail (self != NULL);
+ g_debug ("player-controller.vala:59: update_state : new state %i", (gint) new_state);
+ self->current_state = (gint) new_state;
+}
+
+
+void player_controller_activate (PlayerController* self) {
+ PlayerItem* _tmp0_;
+ g_return_if_fail (self != NULL);
+ player_controller_establish_mpris_connection (self);
+ dbusmenu_menuitem_property_set_bool ((DbusmenuMenuitem*) (_tmp0_ = (PlayerItem*) gee_abstract_list_get ((GeeAbstractList*) self->custom_items, PLAYER_CONTROLLER_METADATA)), DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+ _g_object_unref0 (_tmp0_);
+}
+
+
+void player_controller_instantiate (PlayerController* self) {
+ GError * _inner_error_;
+ g_return_if_fail (self != NULL);
+ _inner_error_ = NULL;
+ {
+ g_app_info_launch (self->priv->_app_info, NULL, NULL, &_inner_error_);
+ if (_inner_error_ != NULL) {
+ goto __catch1_g_error;
+ }
+ player_controller_update_state (self, PLAYER_CONTROLLER_STATE_INSTANTIATING);
+ }
+ goto __finally1;
+ __catch1_g_error:
+ {
+ GError * _error_;
+ _error_ = _inner_error_;
+ _inner_error_ = NULL;
+ {
+ g_warning ("player-controller.vala:82: Failed to launch app %s with error message:" \
+" %s", self->priv->_name, _error_->message);
+ _g_error_free0 (_error_);
+ }
+ }
+ __finally1:
+ if (_inner_error_ != NULL) {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return;
+ }
+}
+
+
+static void player_controller_establish_mpris_connection (PlayerController* self) {
+ g_return_if_fail (self != NULL);
+ if (self->current_state != PLAYER_CONTROLLER_STATE_READY) {
+ g_debug ("player-controller.vala:89: establish_mpris_connection - Not ready to c" \
+"onnect");
+ return;
+ }
+ if (_vala_strcmp0 (self->priv->_name, "Vlc") == 0) {
+ MprisController* _tmp0_;
+ self->mpris_adaptor = (_tmp0_ = (MprisController*) mpris_controller_v2_new (self->priv->_name, self), _g_object_unref0 (self->mpris_adaptor), _tmp0_);
+ } else {
+ MprisController* _tmp1_;
+ self->mpris_adaptor = (_tmp1_ = mpris_controller_new (self->priv->_name, self, "org.freedesktop.MediaPlayer"), _g_object_unref0 (self->mpris_adaptor), _tmp1_);
+ }
+ if (mpris_controller_connected (self->mpris_adaptor) == TRUE) {
+ player_controller_update_state (self, PLAYER_CONTROLLER_STATE_CONNECTED);
+ } else {
+ player_controller_update_state (self, PLAYER_CONTROLLER_STATE_DISCONNECTED);
+ }
+ player_controller_update_layout (self);
}
@@ -218,21 +333,52 @@ void player_controller_vanish (PlayerController* self) {
}
-static gboolean player_controller_self_construct (PlayerController* self) {
- gboolean result = FALSE;
- PlayerItem* _tmp0_;
+static char* bool_to_string (gboolean self) {
+ char* result = NULL;
+ if (self) {
+ result = g_strdup ("true");
+ return result;
+ } else {
+ result = g_strdup ("false");
+ return result;
+ }
+}
+
+
+static void player_controller_update_layout (PlayerController* self) {
+ gboolean visibility;
+ char* _tmp0_;
PlayerItem* _tmp1_;
+ PlayerItem* _tmp2_;
+ g_return_if_fail (self != NULL);
+ visibility = TRUE;
+ if (self->current_state != PLAYER_CONTROLLER_STATE_CONNECTED) {
+ visibility = FALSE;
+ }
+ g_debug ("player-controller.vala:120: about the set the visibility on both the t" \
+"ransport and metadata widget to %s", _tmp0_ = bool_to_string (visibility));
+ _g_free0 (_tmp0_);
+ dbusmenu_menuitem_property_set_bool ((DbusmenuMenuitem*) (_tmp1_ = (PlayerItem*) gee_abstract_list_get ((GeeAbstractList*) self->custom_items, PLAYER_CONTROLLER_TRANSPORT)), DBUSMENU_MENUITEM_PROP_VISIBLE, visibility);
+ _g_object_unref0 (_tmp1_);
+ dbusmenu_menuitem_property_set_bool ((DbusmenuMenuitem*) (_tmp2_ = (PlayerItem*) gee_abstract_list_get ((GeeAbstractList*) self->custom_items, PLAYER_CONTROLLER_METADATA)), DBUSMENU_MENUITEM_PROP_VISIBLE, visibility);
+ _g_object_unref0 (_tmp2_);
+}
+
+
+static void player_controller_construct_widgets (PlayerController* self) {
+ PlayerItem* _tmp0_;
+ TitleMenuitem* title_menu_item;
MetadataMenuitem* metadata_item;
TransportMenuitem* transport_item;
gint offset;
- g_return_val_if_fail (self != NULL, FALSE);
- gee_abstract_collection_add ((GeeAbstractCollection*) self->custom_items, _tmp0_ = player_item_new_separator_item ());
+ g_return_if_fail (self != NULL);
+ gee_abstract_collection_add ((GeeAbstractCollection*) self->custom_items, _tmp0_ = player_item_new (DBUSMENU_CLIENT_TYPES_SEPARATOR));
_g_object_unref0 (_tmp0_);
- gee_abstract_collection_add ((GeeAbstractCollection*) self->custom_items, _tmp1_ = player_item_new_title_item (self->priv->name));
- _g_object_unref0 (_tmp1_);
+ title_menu_item = title_menuitem_new (self, self->priv->_name);
+ gee_abstract_collection_add ((GeeAbstractCollection*) self->custom_items, (PlayerItem*) title_menu_item);
metadata_item = metadata_menuitem_new ();
gee_abstract_collection_add ((GeeAbstractCollection*) self->custom_items, (PlayerItem*) metadata_item);
- transport_item = transport_menuitem_new ();
+ transport_item = transport_menuitem_new (self);
gee_abstract_collection_add ((GeeAbstractCollection*) self->custom_items, (PlayerItem*) transport_item);
offset = 2;
{
@@ -249,10 +395,9 @@ static gboolean player_controller_self_construct (PlayerController* self) {
}
_g_object_unref0 (_item_it);
}
- result = TRUE;
+ _g_object_unref0 (title_menu_item);
_g_object_unref0 (metadata_item);
_g_object_unref0 (transport_item);
- return result;
}
@@ -301,22 +446,60 @@ static char* player_controller_format_client_name (const char* client_name) {
formatted = (_tmp2_ = g_strconcat (_tmp0_ = g_utf8_strup (client_name, (gssize) 1), _tmp1_ = string_slice (client_name, (glong) 1, g_utf8_strlen (client_name, -1)), NULL), _g_free0 (formatted), _tmp2_);
_g_free0 (_tmp1_);
_g_free0 (_tmp0_);
- g_debug ("player-controller.vala:93: PlayerController->format_client_name - : %s", formatted);
+ g_debug ("player-controller.vala:154: PlayerController->format_client_name - : %" \
+"s", formatted);
}
result = formatted;
return result;
}
+const char* player_controller_get_name (PlayerController* self) {
+ const char* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self->priv->_name;
+ return result;
+}
+
+
+void player_controller_set_name (PlayerController* self, const char* value) {
+ char* _tmp0_;
+ g_return_if_fail (self != NULL);
+ self->priv->_name = (_tmp0_ = g_strdup (value), _g_free0 (self->priv->_name), _tmp0_);
+ g_object_notify ((GObject *) self, "name");
+}
+
+
+GAppInfo* player_controller_get_app_info (PlayerController* self) {
+ GAppInfo* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self->priv->_app_info;
+ return result;
+}
+
+
+void player_controller_set_app_info (PlayerController* self, GAppInfo* value) {
+ GAppInfo* _tmp0_;
+ g_return_if_fail (self != NULL);
+ self->priv->_app_info = (_tmp0_ = _g_object_ref0 (value), _g_object_unref0 (self->priv->_app_info), _tmp0_);
+ g_object_notify ((GObject *) self, "app-info");
+}
+
+
static void player_controller_class_init (PlayerControllerClass * klass) {
player_controller_parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (klass, sizeof (PlayerControllerPrivate));
+ G_OBJECT_CLASS (klass)->get_property = player_controller_get_property;
+ G_OBJECT_CLASS (klass)->set_property = player_controller_set_property;
G_OBJECT_CLASS (klass)->finalize = player_controller_finalize;
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PLAYER_CONTROLLER_NAME, g_param_spec_string ("name", "name", "name", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PLAYER_CONTROLLER_APP_INFO, g_param_spec_object ("app-info", "app-info", "app-info", G_TYPE_APP_INFO, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
}
static void player_controller_instance_init (PlayerController * self) {
self->priv = PLAYER_CONTROLLER_GET_PRIVATE (self);
+ self->current_state = (gint) PLAYER_CONTROLLER_STATE_OFFLINE;
}
@@ -324,10 +507,10 @@ static void player_controller_finalize (GObject* obj) {
PlayerController * self;
self = PLAYER_CONTROLLER (obj);
_g_object_unref0 (self->priv->root_menu);
- _g_free0 (self->priv->name);
+ _g_free0 (self->priv->_name);
_g_object_unref0 (self->custom_items);
- _g_object_unref0 (self->priv->mpris_adaptor);
- _g_free0 (self->priv->desktop_path);
+ _g_object_unref0 (self->mpris_adaptor);
+ _g_object_unref0 (self->priv->_app_info);
G_OBJECT_CLASS (player_controller_parent_class)->finalize (obj);
}
@@ -344,6 +527,40 @@ GType player_controller_get_type (void) {
}
+static void player_controller_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+ PlayerController * self;
+ self = PLAYER_CONTROLLER (object);
+ switch (property_id) {
+ case PLAYER_CONTROLLER_NAME:
+ g_value_set_string (value, player_controller_get_name (self));
+ break;
+ case PLAYER_CONTROLLER_APP_INFO:
+ g_value_set_object (value, player_controller_get_app_info (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void player_controller_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+ PlayerController * self;
+ self = PLAYER_CONTROLLER (object);
+ switch (property_id) {
+ case PLAYER_CONTROLLER_NAME:
+ player_controller_set_name (self, g_value_get_string (value));
+ break;
+ case PLAYER_CONTROLLER_APP_INFO:
+ player_controller_set_app_info (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
static int _vala_strcmp0 (const char * str1, const char * str2) {
if (str1 == NULL) {
return -(str1 != str2);
diff --git a/src/player-controller.vala b/src/player-controller.vala
index 0d8dc01..3fb4750 100644
--- a/src/player-controller.vala
+++ b/src/player-controller.vala
@@ -25,66 +25,127 @@ public class PlayerController : GLib.Object
{
public const int METADATA = 2;
private const int TRANSPORT = 3;
+
+ public enum state{
+ OFFLINE,
+ INSTANTIATING,
+ READY,
+ CONNECTED,
+ DISCONNECTED
+ }
+
+ public int current_state = state.OFFLINE;
+
private Dbusmenu.Menuitem root_menu;
- private string name;
- private bool is_active;
+ public string name { get; set;}
public ArrayList<PlayerItem> custom_items;
- private MprisController mpris_adaptor;
- private string desktop_path;
-
- public PlayerController(Dbusmenu.Menuitem root, string client_name, bool active)
+ public MprisController mpris_adaptor;
+ public AppInfo? app_info { get; set;}
+
+ public PlayerController(Dbusmenu.Menuitem root, string client_name, state initial_state)
{
this.root_menu = root;
this.name = format_client_name(client_name.strip());
- this.is_active = active;
this.custom_items = new ArrayList<PlayerItem>();
- self_construct();
-
- // Temporary scenario to handle both v1 and v2 of MPRIS.
+ this.update_state(initial_state);
+ construct_widgets();
+ establish_mpris_connection();
+ update_layout();
+ }
+
+ public void update_state(state new_state)
+ {
+ debug("update_state : new state %i", new_state);
+ this.current_state = new_state;
+ }
+
+ public void activate()
+ {
+ this.establish_mpris_connection();
+ this.custom_items[METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, true);
+ }
+
+ /*
+ instantiate()
+ The user should be able to start the app from the transport bar when in an offline state
+ There is a need to wait before the application is on DBus before attempting to access its mpris address
+ Hence only when the it has registered with us via libindicate do we attempt to kick off mpris communication
+ */
+ public void instantiate()
+ {
+ try{
+ this.app_info.launch(null, null);
+ this.update_state(state.INSTANTIATING);
+ }
+ catch(GLib.Error error){
+ warning("Failed to launch app %s with error message: %s", this.name, error.message);
+ }
+ }
+
+ private void establish_mpris_connection()
+ {
+ if(this.current_state != state.READY){
+ debug("establish_mpris_connection - Not ready to connect");
+ return;
+ }
if(this.name == "Vlc"){
this.mpris_adaptor = new MprisControllerV2(this.name, this);
}
else{
this.mpris_adaptor = new MprisController(this.name, this);
- }
- this.custom_items[TRANSPORT].set_adaptor(this.mpris_adaptor);
-
- // At start up if there is no metadata then hide the item.
- // TODO: NOT working -> dbus menu bug ?
- //((MetadataMenuitem)this.custom_items[METADATA]).check_layout();
+ }
+ if(this.mpris_adaptor.connected() == true){
+ this.update_state(state.CONNECTED);
+ }
+ else{
+ this.update_state(state.DISCONNECTED);
+ }
+ this.update_layout();
}
-
+
public void vanish()
{
foreach(Dbusmenu.Menuitem item in this.custom_items){
root_menu.child_delete(item);
}
}
+
+ private void update_layout()
+ {
+ bool visibility = true;
+ if(this.current_state != state.CONNECTED){
+ visibility = false;
+ }
+ debug("about the set the visibility on both the transport and metadata widget to %s", visibility.to_string());
+ this.custom_items[TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, visibility);
+ this.custom_items[METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, visibility);
+ }
+
- private bool self_construct()
+ private void construct_widgets()
{
// Separator item
- this.custom_items.add(PlayerItem.new_separator_item());
+ this.custom_items.add(new PlayerItem(CLIENT_TYPES_SEPARATOR));
// Title item
- this.custom_items.add(PlayerItem.new_title_item(this.name));
+ TitleMenuitem title_menu_item = new TitleMenuitem(this, this.name);
+ this.custom_items.add(title_menu_item);
// Metadata item
MetadataMenuitem metadata_item = new MetadataMenuitem();
this.custom_items.add(metadata_item);
// Transport item
- TransportMenuitem transport_item = new TransportMenuitem();
+ TransportMenuitem transport_item = new TransportMenuitem(this);
this.custom_items.add(transport_item);
int offset = 2;
foreach(PlayerItem item in this.custom_items){
root_menu.child_add_position(item, offset + this.custom_items.index_of(item));
}
- return true;
}
-
+
private static string format_client_name(string client_name)
{
string formatted = client_name;
@@ -94,5 +155,5 @@ public class PlayerController : GLib.Object
}
return formatted;
}
-
+
} \ No newline at end of file
diff --git a/src/player-item.c b/src/player-item.c
index bd9d78c..6152703 100644
--- a/src/player-item.c
+++ b/src/player-item.c
@@ -26,9 +26,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/menuitem-proxy.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
-#include <gee.h>
#include <stdlib.h>
#include <string.h>
+#include <gee.h>
#define TYPE_PLAYER_ITEM (player_item_get_type ())
@@ -42,65 +42,74 @@ typedef struct _PlayerItem PlayerItem;
typedef struct _PlayerItemClass PlayerItemClass;
typedef struct _PlayerItemPrivate PlayerItemPrivate;
-#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
-#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
-#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
-#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
-#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+#define TYPE_PLAYER_CONTROLLER (player_controller_get_type ())
+#define PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLAYER_CONTROLLER, PlayerController))
+#define PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+#define IS_PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLAYER_CONTROLLER))
+#define IS_PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLAYER_CONTROLLER))
+#define PLAYER_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
-typedef struct _MprisController MprisController;
-typedef struct _MprisControllerClass MprisControllerClass;
+typedef struct _PlayerController PlayerController;
+typedef struct _PlayerControllerClass PlayerControllerClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
struct _PlayerItem {
DbusmenuMenuitem parent_instance;
PlayerItemPrivate * priv;
- MprisController* mpris_adaptor;
};
struct _PlayerItemClass {
DbusmenuMenuitemClass parent_class;
- void (*check_layout) (PlayerItem* self);
+};
+
+struct _PlayerItemPrivate {
+ PlayerController* _owner;
+ char* _item_type;
};
static gpointer player_item_parent_class = NULL;
GType player_item_get_type (void);
-GType mpris_controller_get_type (void);
+GType player_controller_get_type (void);
+#define PLAYER_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_PLAYER_ITEM, PlayerItemPrivate))
enum {
- PLAYER_ITEM_DUMMY_PROPERTY
+ PLAYER_ITEM_DUMMY_PROPERTY,
+ PLAYER_ITEM_OWNER,
+ PLAYER_ITEM_ITEM_TYPE
};
-PlayerItem* player_item_new (void);
-PlayerItem* player_item_construct (GType object_type);
+PlayerItem* player_item_new (const char* type);
+PlayerItem* player_item_construct (GType object_type, const char* type);
void player_item_reset (PlayerItem* self, GeeHashSet* attrs);
static gboolean player_item_ensure_valid_updates (GHashTable* data, GeeHashSet* attributes);
static GValue* _g_value_dup (GValue* self);
char* player_item_sanitize_string (const char* st);
void player_item_update (PlayerItem* self, GHashTable* data, GeeHashSet* attributes);
-void player_item_set_adaptor (PlayerItem* self, MprisController* adaptor);
-PlayerItem* player_item_new_title_item (const char* name);
-PlayerItem* player_item_new_separator_item (void);
-void player_item_check_layout (PlayerItem* self);
-static void player_item_real_check_layout (PlayerItem* self);
+PlayerController* player_item_get_owner (PlayerItem* self);
+static void player_item_set_owner (PlayerItem* self, PlayerController* value);
+const char* player_item_get_item_type (PlayerItem* self);
+static void player_item_set_item_type (PlayerItem* self, const char* value);
+static GObject * player_item_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
static void player_item_finalize (GObject* obj);
+static void player_item_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
+static void player_item_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
static gint _vala_array_length (gpointer array);
-PlayerItem* player_item_construct (GType object_type) {
+PlayerItem* player_item_construct (GType object_type, const char* type) {
PlayerItem * self;
- self = g_object_newv (object_type, 0, NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+ self = (PlayerItem*) g_object_new (object_type, "item-type", type, NULL);
return self;
}
-PlayerItem* player_item_new (void) {
- return player_item_construct (TYPE_PLAYER_ITEM);
+PlayerItem* player_item_new (const char* type) {
+ return player_item_construct (TYPE_PLAYER_ITEM, type);
}
@@ -116,7 +125,7 @@ void player_item_reset (PlayerItem* self, GeeHashSet* attrs) {
break;
}
s = (char*) gee_iterator_get (_s_it);
- g_debug ("player-item.vala:33: attempting to set prop %s to null", s);
+ g_debug ("player-item.vala:39: attempting to set prop %s to null", s);
dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) self, s, NULL);
_g_free0 (s);
}
@@ -139,9 +148,9 @@ void player_item_update (PlayerItem* self, GHashTable* data, GeeHashSet* attribu
g_return_if_fail (self != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (attributes != NULL);
- g_debug ("player-item.vala:40: PlayerItem::update()");
+ g_debug ("player-item.vala:46: PlayerItem::update()");
if (player_item_ensure_valid_updates (data, attributes) == FALSE) {
- g_debug ("player-item.vala:42: PlayerItem::Update -> The hashtable update does n" \
+ g_debug ("player-item.vala:48: PlayerItem::Update -> The hashtable update does n" \
"ot contain what we were expecting - just leave it!");
return;
}
@@ -165,16 +174,16 @@ void player_item_update (PlayerItem* self, GHashTable* data, GeeHashSet* attribu
property = (char*) gee_iterator_get (_property_it);
input_keys = (_tmp1_ = _tmp0_ = g_strsplit (property, "-", 0), input_keys_length1 = _vala_array_length (_tmp0_), _input_keys_size_ = input_keys_length1, _tmp1_);
search_key = g_strdup ((_tmp3_ = input_keys + (input_keys_length1 - 1), _tmp2_ = input_keys_length1 - (input_keys_length1 - 1), _tmp3_)[0]);
- g_debug ("player-item.vala:48: search key = %s", search_key);
+ g_debug ("player-item.vala:54: search key = %s", search_key);
v = __g_value_dup0 ((GValue*) g_hash_table_lookup (data, search_key));
if (G_VALUE_HOLDS (v, G_TYPE_STRING)) {
char* _tmp4_;
- g_debug ("player-item.vala:52: with value : %s", g_value_get_string (v));
+ g_debug ("player-item.vala:58: with value : %s", g_value_get_string (v));
dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) self, property, _tmp4_ = player_item_sanitize_string (g_value_get_string (v)));
_g_free0 (_tmp4_);
} else {
if (G_VALUE_HOLDS (v, G_TYPE_INT)) {
- g_debug ("player-item.vala:56: with value : %i", g_value_get_int (v));
+ g_debug ("player-item.vala:62: with value : %i", g_value_get_int (v));
dbusmenu_menuitem_property_set_int ((DbusmenuMenuitem*) self, property, g_value_get_int (v));
} else {
if (G_VALUE_HOLDS (v, G_TYPE_BOOLEAN)) {
@@ -192,19 +201,6 @@ void player_item_update (PlayerItem* self, GHashTable* data, GeeHashSet* attribu
}
-static gpointer _g_object_ref0 (gpointer self) {
- return self ? g_object_ref (self) : NULL;
-}
-
-
-void player_item_set_adaptor (PlayerItem* self, MprisController* adaptor) {
- MprisController* _tmp0_;
- g_return_if_fail (self != NULL);
- g_return_if_fail (adaptor != NULL);
- self->mpris_adaptor = (_tmp0_ = _g_object_ref0 (adaptor), _g_object_unref0 (self->mpris_adaptor), _tmp0_);
-}
-
-
static gboolean player_item_ensure_valid_updates (GHashTable* data, GeeHashSet* attributes) {
gboolean result = FALSE;
g_return_val_if_fail (data != NULL, FALSE);
@@ -214,7 +210,7 @@ static gboolean player_item_ensure_valid_updates (GHashTable* data, GeeHashSet*
return result;
}
if (g_hash_table_size (data) < gee_collection_get_size ((GeeCollection*) attributes)) {
- g_warning ("player-item.vala:78: update hash was too small for the target");
+ g_warning ("player-item.vala:77: update hash was too small for the target");
result = FALSE;
return result;
}
@@ -276,60 +272,85 @@ char* player_item_sanitize_string (const char* st) {
char* _tmp0_;
_result_ = (_tmp0_ = string_slice (_result_, (glong) 7, g_utf8_strlen (_result_, -1)), _g_free0 (_result_), _tmp0_);
}
- g_debug ("player-item.vala:90: Sanitize string - result = %s", _result_);
+ g_debug ("player-item.vala:89: Sanitize string - result = %s", _result_);
result = _result_;
return result;
}
-PlayerItem* player_item_new_title_item (const char* name) {
- PlayerItem* result = NULL;
- PlayerItem* item;
- g_return_val_if_fail (name != NULL, NULL);
- item = player_item_new ();
- dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) item, DBUSMENU_MENUITEM_PROP_LABEL, name);
- dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) item, DBUSMENU_MENUITEM_PROP_ICON_NAME, "applications-multimedia");
- result = item;
+PlayerController* player_item_get_owner (PlayerItem* self) {
+ PlayerController* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self->priv->_owner;
return result;
}
-PlayerItem* player_item_new_separator_item (void) {
- PlayerItem* result = NULL;
- PlayerItem* separator;
- separator = player_item_new ();
- dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- result = separator;
+static gpointer _g_object_ref0 (gpointer self) {
+ return self ? g_object_ref (self) : NULL;
+}
+
+
+static void player_item_set_owner (PlayerItem* self, PlayerController* value) {
+ PlayerController* _tmp0_;
+ g_return_if_fail (self != NULL);
+ self->priv->_owner = (_tmp0_ = _g_object_ref0 (value), _g_object_unref0 (self->priv->_owner), _tmp0_);
+ g_object_notify ((GObject *) self, "owner");
+}
+
+
+const char* player_item_get_item_type (PlayerItem* self) {
+ const char* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self->priv->_item_type;
return result;
}
-static void player_item_real_check_layout (PlayerItem* self) {
+static void player_item_set_item_type (PlayerItem* self, const char* value) {
+ char* _tmp0_;
g_return_if_fail (self != NULL);
- g_warning ("player-item.vala:114: this should not be hit");
+ self->priv->_item_type = (_tmp0_ = g_strdup (value), _g_free0 (self->priv->_item_type), _tmp0_);
+ g_object_notify ((GObject *) self, "item-type");
}
-void player_item_check_layout (PlayerItem* self) {
- PLAYER_ITEM_GET_CLASS (self)->check_layout (self);
+static GObject * player_item_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
+ GObject * obj;
+ GObjectClass * parent_class;
+ PlayerItem * self;
+ parent_class = G_OBJECT_CLASS (player_item_parent_class);
+ obj = parent_class->constructor (type, n_construct_properties, construct_properties);
+ self = PLAYER_ITEM (obj);
+ {
+ dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) self, DBUSMENU_MENUITEM_PROP_TYPE, self->priv->_item_type);
+ }
+ return obj;
}
static void player_item_class_init (PlayerItemClass * klass) {
player_item_parent_class = g_type_class_peek_parent (klass);
- PLAYER_ITEM_CLASS (klass)->check_layout = player_item_real_check_layout;
+ g_type_class_add_private (klass, sizeof (PlayerItemPrivate));
+ G_OBJECT_CLASS (klass)->get_property = player_item_get_property;
+ G_OBJECT_CLASS (klass)->set_property = player_item_set_property;
+ G_OBJECT_CLASS (klass)->constructor = player_item_constructor;
G_OBJECT_CLASS (klass)->finalize = player_item_finalize;
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PLAYER_ITEM_OWNER, g_param_spec_object ("owner", "owner", "owner", TYPE_PLAYER_CONTROLLER, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PLAYER_ITEM_ITEM_TYPE, g_param_spec_string ("item-type", "item-type", "item-type", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}
static void player_item_instance_init (PlayerItem * self) {
+ self->priv = PLAYER_ITEM_GET_PRIVATE (self);
}
static void player_item_finalize (GObject* obj) {
PlayerItem * self;
self = PLAYER_ITEM (obj);
- _g_object_unref0 (self->mpris_adaptor);
+ _g_object_unref0 (self->priv->_owner);
+ _g_free0 (self->priv->_item_type);
G_OBJECT_CLASS (player_item_parent_class)->finalize (obj);
}
@@ -346,6 +367,40 @@ GType player_item_get_type (void) {
}
+static void player_item_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+ PlayerItem * self;
+ self = PLAYER_ITEM (object);
+ switch (property_id) {
+ case PLAYER_ITEM_OWNER:
+ g_value_set_object (value, player_item_get_owner (self));
+ break;
+ case PLAYER_ITEM_ITEM_TYPE:
+ g_value_set_string (value, player_item_get_item_type (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void player_item_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+ PlayerItem * self;
+ self = PLAYER_ITEM (object);
+ switch (property_id) {
+ case PLAYER_ITEM_OWNER:
+ player_item_set_owner (self, g_value_get_object (value));
+ break;
+ case PLAYER_ITEM_ITEM_TYPE:
+ player_item_set_item_type (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
diff --git a/src/player-item.vala b/src/player-item.vala
index a5c5512..171c140 100644
--- a/src/player-item.vala
+++ b/src/player-item.vala
@@ -22,10 +22,16 @@ using Gee;
public class PlayerItem : Dbusmenu.Menuitem
{
- public MprisController mpris_adaptor;
-
- public PlayerItem()
+ public PlayerController owner {get; construct;}
+ public string item_type { get; construct; }
+
+ public PlayerItem(string type)
{
+ Object(item_type: type);
+ }
+
+ construct {
+ this.property_set(MENUITEM_PROP_TYPE, item_type);
}
public void reset(HashSet<string> attrs){
@@ -60,15 +66,8 @@ public class PlayerItem : Dbusmenu.Menuitem
this.property_set_bool(property, v.get_boolean());
}
}
- // TODO: not working
- //this.check_layout();
}
- public void set_adaptor(MprisController adaptor)
- {
- this.mpris_adaptor = adaptor;
- }
-
private static bool ensure_valid_updates(HashTable<string, Value?> data, HashSet<string> attributes)
{
if(data == null){
@@ -91,27 +90,5 @@ public class PlayerItem : Dbusmenu.Menuitem
return result;
}
-
- //----- Custom constructors for player items ----------------//
- // Title item
- public static PlayerItem new_title_item(dynamic string name)
- {
- PlayerItem item = new PlayerItem();
- item.property_set(MENUITEM_PROP_LABEL, name);
- item.property_set(MENUITEM_PROP_ICON_NAME, "applications-multimedia");
- return item;
- }
-
- // Separator item
- public static PlayerItem new_separator_item()
- {
- PlayerItem separator = new PlayerItem();
- separator.property_set(MENUITEM_PROP_TYPE, CLIENT_TYPES_SEPARATOR);
- return separator;
- }
-
- public virtual void check_layout(){
- warning("this should not be hit");
- }
}
diff --git a/src/title-menu-item.c b/src/title-menu-item.c
new file mode 100644
index 0000000..0bf7db1
--- /dev/null
+++ b/src/title-menu-item.c
@@ -0,0 +1,213 @@
+/* title-menu-item.c generated by valac, the Vala compiler
+ * generated from title-menu-item.vala, do not modify */
+
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-glib/menuitem-proxy.h>
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-glib/server.h>
+#include <common-defs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gee.h>
+
+
+#define TYPE_PLAYER_ITEM (player_item_get_type ())
+#define PLAYER_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLAYER_ITEM, PlayerItem))
+#define PLAYER_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLAYER_ITEM, PlayerItemClass))
+#define IS_PLAYER_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLAYER_ITEM))
+#define IS_PLAYER_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLAYER_ITEM))
+#define PLAYER_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLAYER_ITEM, PlayerItemClass))
+
+typedef struct _PlayerItem PlayerItem;
+typedef struct _PlayerItemClass PlayerItemClass;
+typedef struct _PlayerItemPrivate PlayerItemPrivate;
+
+#define TYPE_TITLE_MENUITEM (title_menuitem_get_type ())
+#define TITLE_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TITLE_MENUITEM, TitleMenuitem))
+#define TITLE_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TITLE_MENUITEM, TitleMenuitemClass))
+#define IS_TITLE_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TITLE_MENUITEM))
+#define IS_TITLE_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TITLE_MENUITEM))
+#define TITLE_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TITLE_MENUITEM, TitleMenuitemClass))
+
+typedef struct _TitleMenuitem TitleMenuitem;
+typedef struct _TitleMenuitemClass TitleMenuitemClass;
+typedef struct _TitleMenuitemPrivate TitleMenuitemPrivate;
+
+#define TYPE_PLAYER_CONTROLLER (player_controller_get_type ())
+#define PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLAYER_CONTROLLER, PlayerController))
+#define PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+#define IS_PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLAYER_CONTROLLER))
+#define IS_PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLAYER_CONTROLLER))
+#define PLAYER_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+
+typedef struct _PlayerController PlayerController;
+typedef struct _PlayerControllerClass PlayerControllerClass;
+#define _g_free0(var) (var = (g_free (var), NULL))
+typedef struct _PlayerControllerPrivate PlayerControllerPrivate;
+
+#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
+#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
+#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
+#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
+#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+
+typedef struct _MprisController MprisController;
+typedef struct _MprisControllerClass MprisControllerClass;
+
+#define PLAYER_CONTROLLER_TYPE_STATE (player_controller_state_get_type ())
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+
+struct _PlayerItem {
+ DbusmenuMenuitem parent_instance;
+ PlayerItemPrivate * priv;
+};
+
+struct _PlayerItemClass {
+ DbusmenuMenuitemClass parent_class;
+};
+
+struct _TitleMenuitem {
+ PlayerItem parent_instance;
+ TitleMenuitemPrivate * priv;
+};
+
+struct _TitleMenuitemClass {
+ PlayerItemClass parent_class;
+};
+
+struct _PlayerController {
+ GObject parent_instance;
+ PlayerControllerPrivate * priv;
+ gint current_state;
+ GeeArrayList* custom_items;
+ MprisController* mpris_adaptor;
+};
+
+struct _PlayerControllerClass {
+ GObjectClass parent_class;
+};
+
+typedef enum {
+ PLAYER_CONTROLLER_STATE_OFFLINE,
+ PLAYER_CONTROLLER_STATE_INSTANTIATING,
+ PLAYER_CONTROLLER_STATE_READY,
+ PLAYER_CONTROLLER_STATE_CONNECTED,
+ PLAYER_CONTROLLER_STATE_DISCONNECTED
+} PlayerControllerstate;
+
+
+static gpointer title_menuitem_parent_class = NULL;
+
+GType player_item_get_type (void);
+GType title_menuitem_get_type (void);
+enum {
+ TITLE_MENUITEM_DUMMY_PROPERTY
+};
+GType player_controller_get_type (void);
+TitleMenuitem* title_menuitem_new (PlayerController* parent, const char* name);
+TitleMenuitem* title_menuitem_construct (GType object_type, PlayerController* parent, const char* name);
+PlayerController* player_item_get_owner (PlayerItem* self);
+GType mpris_controller_get_type (void);
+GType player_controller_state_get_type (void);
+void player_controller_instantiate (PlayerController* self);
+static void title_menuitem_real_handle_event (DbusmenuMenuitem* base, const char* name, GValue* input_value, guint timestamp);
+GeeHashSet* title_menuitem_attributes_format (void);
+
+
+
+TitleMenuitem* title_menuitem_construct (GType object_type, PlayerController* parent, const char* name) {
+ TitleMenuitem * self;
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ self = (TitleMenuitem*) g_object_new (object_type, "item-type", DBUSMENU_TITLE_MENUITEM_TYPE, "owner", parent, NULL);
+ dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) self, DBUSMENU_TITLE_MENUITEM_TEXT_NAME, name);
+ return self;
+}
+
+
+TitleMenuitem* title_menuitem_new (PlayerController* parent, const char* name) {
+ return title_menuitem_construct (TYPE_TITLE_MENUITEM, parent, name);
+}
+
+
+static char* bool_to_string (gboolean self) {
+ char* result = NULL;
+ if (self) {
+ result = g_strdup ("true");
+ return result;
+ } else {
+ result = g_strdup ("false");
+ return result;
+ }
+}
+
+
+static void title_menuitem_real_handle_event (DbusmenuMenuitem* base, const char* name, GValue* input_value, guint timestamp) {
+ TitleMenuitem * self;
+ char* _tmp0_;
+ self = (TitleMenuitem*) base;
+ g_return_if_fail (name != NULL);
+ g_debug ("title-menu-item.vala:34: handle_event with bool value %s", _tmp0_ = bool_to_string (g_value_get_boolean (input_value)));
+ _g_free0 (_tmp0_);
+ if (player_item_get_owner ((PlayerItem*) self)->current_state == PLAYER_CONTROLLER_STATE_OFFLINE) {
+ player_controller_instantiate (player_item_get_owner ((PlayerItem*) self));
+ }
+}
+
+
+GeeHashSet* title_menuitem_attributes_format (void) {
+ GeeHashSet* result = NULL;
+ GeeHashSet* attrs;
+ attrs = gee_hash_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL);
+ gee_abstract_collection_add ((GeeAbstractCollection*) attrs, DBUSMENU_TITLE_MENUITEM_TEXT_NAME);
+ result = attrs;
+ return result;
+}
+
+
+static void title_menuitem_class_init (TitleMenuitemClass * klass) {
+ title_menuitem_parent_class = g_type_class_peek_parent (klass);
+ DBUSMENU_MENUITEM_CLASS (klass)->handle_event = title_menuitem_real_handle_event;
+}
+
+
+static void title_menuitem_instance_init (TitleMenuitem * self) {
+}
+
+
+GType title_menuitem_get_type (void) {
+ static volatile gsize title_menuitem_type_id__volatile = 0;
+ if (g_once_init_enter (&title_menuitem_type_id__volatile)) {
+ static const GTypeInfo g_define_type_info = { sizeof (TitleMenuitemClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) title_menuitem_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (TitleMenuitem), 0, (GInstanceInitFunc) title_menuitem_instance_init, NULL };
+ GType title_menuitem_type_id;
+ title_menuitem_type_id = g_type_register_static (TYPE_PLAYER_ITEM, "TitleMenuitem", &g_define_type_info, 0);
+ g_once_init_leave (&title_menuitem_type_id__volatile, title_menuitem_type_id);
+ }
+ return title_menuitem_type_id__volatile;
+}
+
+
+
+
diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala
new file mode 100644
index 0000000..612d279
--- /dev/null
+++ b/src/title-menu-item.vala
@@ -0,0 +1,48 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+using Dbusmenu;
+using DbusmenuTitle;
+using Gee;
+
+public class TitleMenuitem : PlayerItem
+{
+ public TitleMenuitem(PlayerController parent, string name)
+ {
+ Object(item_type: MENUITEM_TYPE, owner: parent);
+ this.property_set(MENUITEM_TEXT_NAME, name);
+ }
+
+ public override void handle_event(string name, GLib.Value input_value, uint timestamp)
+ {
+ debug("handle_event with bool value %s", input_value.get_boolean().to_string());
+ if(this.owner.current_state == PlayerController.state.OFFLINE)
+ {
+ this.owner.instantiate();
+ }
+ }
+
+
+ public static HashSet<string> attributes_format()
+ {
+ HashSet<string> attrs = new HashSet<string>();
+ attrs.add(MENUITEM_TEXT_NAME);
+ return attrs;
+ }
+} \ No newline at end of file
diff --git a/src/title-widget.c b/src/title-widget.c
new file mode 100644
index 0000000..1b57fe9
--- /dev/null
+++ b/src/title-widget.c
@@ -0,0 +1,192 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+#include "title-widget.h"
+#include "common-defs.h"
+#include <gtk/gtk.h>
+#include <libindicator/indicator-image-helper.h>
+
+static DbusmenuMenuitem* twin_item;
+
+typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
+
+struct _TitleWidgetPrivate
+{
+ GtkWidget* hbox;
+ GtkWidget* name;
+ GtkWidget* player_icon;
+};
+
+#define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate))
+
+/* Prototypes */
+static void title_widget_class_init (TitleWidgetClass *klass);
+static void title_widget_init (TitleWidget *self);
+static void title_widget_dispose (GObject *object);
+static void title_widget_finalize (GObject *object);
+
+// keyevent consumers
+static gboolean title_widget_button_press_event (GtkWidget *menuitem,
+ GdkEventButton *event);
+static gboolean title_widget_button_release_event (GtkWidget *menuitem,
+ GdkEventButton *event);
+static gboolean title_widget_expose_event(GtkWidget* widget,
+ GdkEventExpose* event);
+
+// Dbusmenuitem properties update callback
+static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
+ GValue* value, gpointer userdata);
+static void style_name_text(TitleWidget* self);
+G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_MENU_ITEM);
+
+
+
+static void
+title_widget_class_init (TitleWidgetClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->button_press_event = title_widget_button_press_event;
+ widget_class->button_release_event = title_widget_button_release_event;
+ widget_class->expose_event = title_widget_expose_event;
+
+ g_type_class_add_private (klass, sizeof (TitleWidgetPrivate));
+
+ gobject_class->dispose = title_widget_dispose;
+ gobject_class->finalize = title_widget_finalize;
+
+}
+
+static void
+title_widget_init (TitleWidget *self)
+{
+ g_debug("TitleWidget::title_widget_init");
+
+ TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
+
+ GtkWidget *hbox;
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ priv->hbox = hbox;
+ g_signal_connect(G_OBJECT(twin_item), "property-changed",
+ G_CALLBACK(title_widget_property_update), self);
+
+ priv->player_icon = indicator_image_helper("sound_icon");
+ gtk_box_pack_start(GTK_BOX (priv->hbox), priv->player_icon, FALSE, FALSE, 0);
+
+ priv->name = gtk_label_new(dbusmenu_menuitem_property_get(twin_item,
+ DBUSMENU_TITLE_MENUITEM_TEXT_NAME));
+ gtk_misc_set_padding(GTK_MISC(priv->name), 10, 0);
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, 0);
+
+ style_name_text(self);
+
+ gtk_widget_show_all (priv->hbox);
+ gtk_container_add (GTK_CONTAINER (self), hbox);
+
+}
+
+static void
+title_widget_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (title_widget_parent_class)->dispose (object);
+}
+
+static void
+title_widget_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (title_widget_parent_class)->finalize (object);
+}
+
+/* Suppress/consume keyevents */
+static gboolean
+title_widget_button_press_event (GtkWidget *menuitem,
+ GdkEventButton *event)
+{
+ g_debug("TitleWidget::menu_press_event");
+
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_BOOLEAN);
+
+ g_value_set_boolean(&value, TRUE);
+ dbusmenu_menuitem_handle_event (twin_item, "Title menu event", &value, 0);
+
+ return TRUE;
+}
+
+static gboolean
+title_widget_button_release_event (GtkWidget *menuitem,
+ GdkEventButton *event)
+{
+ g_debug("TitleWidget::menu_release_event");
+ return TRUE;
+}
+
+static gboolean
+title_widget_expose_event(GtkWidget* widget, GdkEventExpose* event)
+{
+ TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(widget);
+
+ gtk_container_propagate_expose(GTK_CONTAINER(widget), priv->hbox, event);
+ return TRUE;
+}
+
+static void
+title_widget_property_update(DbusmenuMenuitem* item, gchar* property,
+ GValue* value, gpointer userdata)
+{
+ g_return_if_fail (IS_TITLE_WIDGET (userdata));
+ TitleWidget* mitem = TITLE_WIDGET(userdata);
+ TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(mitem);
+
+ if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_TEXT_NAME, property) == 0){
+ gtk_label_set_text(GTK_LABEL(priv->name), g_value_get_string(value));
+ style_name_text(mitem);
+ }
+}
+
+static void
+style_name_text(TitleWidget* self)
+{
+ TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self);
+
+ char* markup;
+ markup = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
+ gtk_label_get_text(GTK_LABEL(priv->name)));
+ gtk_label_set_markup (GTK_LABEL (priv->name), markup);
+ g_free(markup);
+}
+
+ /**
+ * transport_new:
+ * @returns: a new #TitleWidget.
+ **/
+GtkWidget*
+title_widget_new(DbusmenuMenuitem *item)
+{
+ twin_item = item;
+ return g_object_new(TITLE_WIDGET_TYPE, NULL);
+}
+
diff --git a/src/title-widget.h b/src/title-widget.h
new file mode 100644
index 0000000..efc0c78
--- /dev/null
+++ b/src/title-widget.h
@@ -0,0 +1,51 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+#ifndef __TITLE_WIDGET_H__
+#define __TITLE_WIDGET_H__
+
+#include <gtk/gtkmenuitem.h>
+#include <libdbusmenu-gtk/menu.h>
+
+G_BEGIN_DECLS
+
+#define TITLE_WIDGET_TYPE (title_widget_get_type ())
+#define TITLE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TITLE_WIDGET_TYPE, TitleWidget))
+#define TITLE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TITLE_WIDGET_TYPE, TitleWidgetClass))
+#define IS_TITLE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TITLE_WIDGET_TYPE))
+#define IS_TITLE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TITLE_WIDGET_TYPE))
+#define TITLE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TITLE_WIDGET_TYPE, TitleWidgetClass))
+
+typedef struct _TitleWidget TitleWidget;
+typedef struct _TitleWidgetClass TitleWidgetClass;
+
+struct _TitleWidgetClass {
+ GtkMenuItemClass parent_class;
+};
+
+struct _TitleWidget {
+ GtkMenuItem parent;
+};
+
+GType title_widget_get_type (void);
+GtkWidget* title_widget_new(DbusmenuMenuitem *twin_item);
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/transport-menu-item.c b/src/transport-menu-item.c
index 96d3576..48c437a 100644
--- a/src/transport-menu-item.c
+++ b/src/transport-menu-item.c
@@ -27,9 +27,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
#include <common-defs.h>
+#include <gee.h>
#include <stdlib.h>
#include <string.h>
-#include <gee.h>
#define TYPE_PLAYER_ITEM (player_item_get_type ())
@@ -43,16 +43,6 @@ typedef struct _PlayerItem PlayerItem;
typedef struct _PlayerItemClass PlayerItemClass;
typedef struct _PlayerItemPrivate PlayerItemPrivate;
-#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
-#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
-#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
-#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
-#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
-
-typedef struct _MprisController MprisController;
-typedef struct _MprisControllerClass MprisControllerClass;
-
#define TYPE_TRANSPORT_MENUITEM (transport_menuitem_get_type ())
#define TRANSPORT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TRANSPORT_MENUITEM, TransportMenuitem))
#define TRANSPORT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TRANSPORT_MENUITEM, TransportMenuitemClass))
@@ -63,18 +53,39 @@ typedef struct _MprisControllerClass MprisControllerClass;
typedef struct _TransportMenuitem TransportMenuitem;
typedef struct _TransportMenuitemClass TransportMenuitemClass;
typedef struct _TransportMenuitemPrivate TransportMenuitemPrivate;
+
+#define TRANSPORT_MENUITEM_TYPE_ACTION (transport_menuitem_action_get_type ())
+
+#define TYPE_PLAYER_CONTROLLER (player_controller_get_type ())
+#define PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PLAYER_CONTROLLER, PlayerController))
+#define PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+#define IS_PLAYER_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PLAYER_CONTROLLER))
+#define IS_PLAYER_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PLAYER_CONTROLLER))
+#define PLAYER_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PLAYER_CONTROLLER, PlayerControllerClass))
+
+typedef struct _PlayerController PlayerController;
+typedef struct _PlayerControllerClass PlayerControllerClass;
#define _g_free0(var) (var = (g_free (var), NULL))
+typedef struct _PlayerControllerPrivate PlayerControllerPrivate;
+
+#define TYPE_MPRIS_CONTROLLER (mpris_controller_get_type ())
+#define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MPRIS_CONTROLLER, MprisController))
+#define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+#define IS_MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MPRIS_CONTROLLER))
+#define IS_MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MPRIS_CONTROLLER))
+#define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MPRIS_CONTROLLER, MprisControllerClass))
+
+typedef struct _MprisController MprisController;
+typedef struct _MprisControllerClass MprisControllerClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
struct _PlayerItem {
DbusmenuMenuitem parent_instance;
PlayerItemPrivate * priv;
- MprisController* mpris_adaptor;
};
struct _PlayerItemClass {
DbusmenuMenuitemClass parent_class;
- void (*check_layout) (PlayerItem* self);
};
struct _TransportMenuitem {
@@ -86,38 +97,67 @@ struct _TransportMenuitemClass {
PlayerItemClass parent_class;
};
+typedef enum {
+ TRANSPORT_MENUITEM_ACTION_PREVIOUS,
+ TRANSPORT_MENUITEM_ACTION_PLAY_PAUSE,
+ TRANSPORT_MENUITEM_ACTION_NEXT
+} TransportMenuitemaction;
+
+struct _PlayerController {
+ GObject parent_instance;
+ PlayerControllerPrivate * priv;
+ gint current_state;
+ GeeArrayList* custom_items;
+ MprisController* mpris_adaptor;
+};
+
+struct _PlayerControllerClass {
+ GObjectClass parent_class;
+};
+
static gpointer transport_menuitem_parent_class = NULL;
GType player_item_get_type (void);
-GType mpris_controller_get_type (void);
GType transport_menuitem_get_type (void);
enum {
TRANSPORT_MENUITEM_DUMMY_PROPERTY
};
-PlayerItem* player_item_new (void);
-PlayerItem* player_item_construct (GType object_type);
-TransportMenuitem* transport_menuitem_new (void);
-TransportMenuitem* transport_menuitem_construct (GType object_type);
+GType transport_menuitem_action_get_type (void);
+GType player_controller_get_type (void);
+TransportMenuitem* transport_menuitem_new (PlayerController* parent);
+TransportMenuitem* transport_menuitem_construct (GType object_type, PlayerController* parent);
void transport_menuitem_change_play_state (TransportMenuitem* self, gint state);
-void mpris_controller_toggle_playback (MprisController* self, gboolean state);
+PlayerController* player_item_get_owner (PlayerItem* self);
+GType mpris_controller_get_type (void);
+void mpris_controller_transport_event (MprisController* self, TransportMenuitemaction command);
static void transport_menuitem_real_handle_event (DbusmenuMenuitem* base, const char* name, GValue* input_value, guint timestamp);
-static void transport_menuitem_real_check_layout (PlayerItem* base);
GeeHashSet* transport_menuitem_attributes_format (void);
-TransportMenuitem* transport_menuitem_construct (GType object_type) {
+GType transport_menuitem_action_get_type (void) {
+ static volatile gsize transport_menuitem_action_type_id__volatile = 0;
+ if (g_once_init_enter (&transport_menuitem_action_type_id__volatile)) {
+ static const GEnumValue values[] = {{TRANSPORT_MENUITEM_ACTION_PREVIOUS, "TRANSPORT_MENUITEM_ACTION_PREVIOUS", "previous"}, {TRANSPORT_MENUITEM_ACTION_PLAY_PAUSE, "TRANSPORT_MENUITEM_ACTION_PLAY_PAUSE", "play-pause"}, {TRANSPORT_MENUITEM_ACTION_NEXT, "TRANSPORT_MENUITEM_ACTION_NEXT", "next"}, {0, NULL, NULL}};
+ GType transport_menuitem_action_type_id;
+ transport_menuitem_action_type_id = g_enum_register_static ("TransportMenuitemaction", values);
+ g_once_init_leave (&transport_menuitem_action_type_id__volatile, transport_menuitem_action_type_id);
+ }
+ return transport_menuitem_action_type_id__volatile;
+}
+
+
+TransportMenuitem* transport_menuitem_construct (GType object_type, PlayerController* parent) {
TransportMenuitem * self;
- self = (TransportMenuitem*) player_item_construct (object_type);
- dbusmenu_menuitem_property_set ((DbusmenuMenuitem*) self, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_TRANSPORT_MENUITEM_TYPE);
- g_debug ("transport-menu-item.vala:30: transport on the vala side");
+ g_return_val_if_fail (parent != NULL, NULL);
+ self = (TransportMenuitem*) g_object_new (object_type, "item-type", DBUSMENU_TRANSPORT_MENUITEM_TYPE, "owner", parent, NULL);
return self;
}
-TransportMenuitem* transport_menuitem_new (void) {
- return transport_menuitem_construct (TYPE_TRANSPORT_MENUITEM);
+TransportMenuitem* transport_menuitem_new (PlayerController* parent) {
+ return transport_menuitem_construct (TYPE_TRANSPORT_MENUITEM, parent);
}
@@ -127,32 +167,16 @@ void transport_menuitem_change_play_state (TransportMenuitem* self, gint state)
}
-static char* bool_to_string (gboolean self) {
- char* result = NULL;
- if (self) {
- result = g_strdup ("true");
- return result;
- } else {
- result = g_strdup ("false");
- return result;
- }
-}
-
-
static void transport_menuitem_real_handle_event (DbusmenuMenuitem* base, const char* name, GValue* input_value, guint timestamp) {
TransportMenuitem * self;
+ gint input;
char* _tmp0_;
self = (TransportMenuitem*) base;
g_return_if_fail (name != NULL);
- g_debug ("transport-menu-item.vala:40: handle_event with bool value %s", _tmp0_ = bool_to_string (g_value_get_boolean (input_value)));
+ input = g_value_get_int (input_value);
+ g_debug ("transport-menu-item.vala:45: handle_event with value %s", _tmp0_ = g_strdup_printf ("%i", input));
_g_free0 (_tmp0_);
- mpris_controller_toggle_playback (((PlayerItem*) self)->mpris_adaptor, g_value_get_boolean (input_value));
-}
-
-
-static void transport_menuitem_real_check_layout (PlayerItem* base) {
- TransportMenuitem * self;
- self = (TransportMenuitem*) base;
+ mpris_controller_transport_event (player_item_get_owner ((PlayerItem*) self)->mpris_adaptor, (TransportMenuitemaction) input);
}
@@ -169,7 +193,6 @@ GeeHashSet* transport_menuitem_attributes_format (void) {
static void transport_menuitem_class_init (TransportMenuitemClass * klass) {
transport_menuitem_parent_class = g_type_class_peek_parent (klass);
DBUSMENU_MENUITEM_CLASS (klass)->handle_event = transport_menuitem_real_handle_event;
- PLAYER_ITEM_CLASS (klass)->check_layout = transport_menuitem_real_check_layout;
}
diff --git a/src/transport-menu-item.vala b/src/transport-menu-item.vala
index 264e153..e0710a8 100644
--- a/src/transport-menu-item.vala
+++ b/src/transport-menu-item.vala
@@ -23,11 +23,15 @@ using DbusmenuTransport;
public class TransportMenuitem : PlayerItem
{
+ public enum action{
+ PREVIOUS,
+ PLAY_PAUSE,
+ NEXT
+ }
- public TransportMenuitem()
+ public TransportMenuitem(PlayerController parent)
{
- this.property_set(MENUITEM_PROP_TYPE, MENUITEM_TYPE);
- debug("transport on the vala side");
+ Object(item_type: MENUITEM_TYPE, owner: parent);
}
public void change_play_state(int state)
@@ -37,14 +41,11 @@ public class TransportMenuitem : PlayerItem
public override void handle_event(string name, GLib.Value input_value, uint timestamp)
{
- debug("handle_event with bool value %s", input_value.get_boolean().to_string());
- this.mpris_adaptor.toggle_playback(input_value.get_boolean());
- }
-
- public override void check_layout(){
- // nothing to be done for this item - always active
- }
-
+ int input = input_value.get_int();
+ debug("handle_event with value %s", input.to_string());
+ // Fire and forgot - the widget would not have sent it over it didn't think it was relevant.
+ this.owner.mpris_adaptor.transport_event((action)input);
+ }
public static HashSet<string> attributes_format()
{
diff --git a/src/transport-widget.c b/src/transport-widget.c
index bc9df53..9852b50 100644
--- a/src/transport-widget.c
+++ b/src/transport-widget.c
@@ -25,8 +25,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "transport-widget.h"
#include "common-defs.h"
#include <gtk/gtk.h>
+#include "play-button.h"
-// TODO: think about leakage: ted !
static DbusmenuMenuitem* twin_item;
@@ -38,16 +38,6 @@ struct _TransportWidgetPrivate
GtkWidget* play_button;
};
-enum {
- PLAY,
- PAUSE,
- NEXT,
- PREVIOUS,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
#define TRANSPORT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRANSPORT_WIDGET_TYPE, TransportWidgetPrivate))
/* Gobject boiler plate */
@@ -55,26 +45,20 @@ static void transport_widget_class_init (TransportWidgetClass *klass);
static void transport_widget_init (TransportWidget *self);
static void transport_widget_dispose (GObject *object);
static void transport_widget_finalize (GObject *object);
+static gboolean transport_widget_expose_event(GtkWidget* widget, GdkEventExpose* event);
/* UI and dbusmenu callbacks */
static gboolean transport_widget_button_press_event (GtkWidget *menuitem,
GdkEventButton *event);
static gboolean transport_widget_button_release_event (GtkWidget *menuitem,
- GdkEventButton *event);
-static void transport_widget_play_clicked (GtkWidget* button,
- TransportWidget* self);
-
+ GdkEventButton *event);
static void transport_widget_property_update(DbusmenuMenuitem* item,
- gchar * property,
- GValue * value,
- gpointer userdata);
-// utility methods
-static gchar* transport_widget_toggle_play_label(gint state);
+ gchar * property,
+ GValue * value,
+ gpointer userdata);
G_DEFINE_TYPE (TransportWidget, transport_widget, GTK_TYPE_MENU_ITEM);
-
-
static void
transport_widget_class_init (TransportWidgetClass *klass)
{
@@ -84,45 +68,12 @@ transport_widget_class_init (TransportWidgetClass *klass)
menu_item_class->hide_on_activate = FALSE;
widget_class->button_press_event = transport_widget_button_press_event;
- widget_class->button_release_event = transport_widget_button_release_event;
-
+ widget_class->button_release_event = transport_widget_button_release_event;
+ widget_class->expose_event = transport_widget_expose_event;
g_type_class_add_private (klass, sizeof (TransportWidgetPrivate));
gobject_class->dispose = transport_widget_dispose;
gobject_class->finalize = transport_widget_finalize;
-
- signals[PLAY] = g_signal_new ("play",
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[PAUSE] = g_signal_new ("pause",
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
-
- signals[NEXT] = g_signal_new ("next",
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[PREVIOUS] = g_signal_new ("previous",
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
static void
@@ -131,19 +82,19 @@ transport_widget_init (TransportWidget *self)
g_debug("TransportWidget::transport_widget_init");
TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(self);
- GtkWidget *hbox;
+ GtkWidget* hbox;
hbox = gtk_hbox_new(TRUE, 2);
- gchar* symbol = transport_widget_toggle_play_label(dbusmenu_menuitem_property_get_int(twin_item, DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE));
- priv->play_button = gtk_button_new_with_label(symbol);
- //g_free(symbol);
- gtk_box_pack_start (GTK_BOX (hbox), priv->play_button, FALSE, TRUE, 0);
+ GtkStyle* style = gtk_rc_get_style(GTK_WIDGET(self));
+
priv->hbox = hbox;
+ priv->play_button = play_button_new();
+ play_button_set_style(priv->play_button, style);
+
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->play_button, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(transport_widget_property_update), self);
-
- g_signal_connect(priv->play_button, "clicked", G_CALLBACK(transport_widget_play_clicked), self);
gtk_container_add (GTK_CONTAINER (self), priv->hbox);
@@ -162,6 +113,15 @@ transport_widget_finalize (GObject *object)
G_OBJECT_CLASS (transport_widget_parent_class)->finalize (object);
}
+static gboolean
+transport_widget_expose_event(GtkWidget* widget, GdkEventExpose* event)
+{
+ //TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(widget);
+ //gtk_container_propagate_expose(GTK_CONTAINER(widget),priv->play_button, event);
+ return TRUE;
+}
+
+
/* keyevents */
static gboolean
transport_widget_button_press_event (GtkWidget *menuitem,
@@ -174,26 +134,26 @@ transport_widget_button_press_event (GtkWidget *menuitem,
TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem));
- gtk_widget_event (priv->hbox, (GdkEvent*)event);
- gboolean state = g_ascii_strcasecmp(gtk_button_get_label(GTK_BUTTON(priv->play_button)), ">") == 0;
+ GtkWidget *parent;
- gtk_button_set_label(GTK_BUTTON(priv->play_button), transport_widget_toggle_play_label((gint)state));
- GValue value = {0};
- g_value_init(&value, G_TYPE_BOOLEAN);
- g_debug("TransportWidget::menu_press_event - going to send value %i", state);
+ // can we block emissions of "grab-notify" on parent??
+ parent = gtk_widget_get_parent (GTK_WIDGET (menuitem));
+ gint result = determine_button_event(priv->play_button, event);
+
+ //GTK_OBJECT_FLAGS (scale) |= GTK_HAS_GRAB;
+ //gtk_widget_event (scale,
+ //((GdkEvent *)(void*)(event)));
+ //GTK_OBJECT_FLAGS (scale) &= ~(GTK_HAS_GRAB);
- g_value_set_boolean(&value, state);
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_INT);
+ g_debug("TransportWidget::menu_press_event - going to send value %i", result);
+ g_value_set_int(&value, result);
dbusmenu_menuitem_handle_event (twin_item, "Transport state change", &value, 0);
return TRUE;
}
-static void
-transport_widget_play_clicked(GtkWidget* button,
- TransportWidget* self)
-{
- g_debug("Transport_widget_play_clicked");
-}
static gboolean
transport_widget_button_release_event (GtkWidget *menuitem,
@@ -203,9 +163,6 @@ transport_widget_button_release_event (GtkWidget *menuitem,
if(IS_TRANSPORT_WIDGET(menuitem) == FALSE){
return FALSE;
}
-
- TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem));
- gtk_widget_event (priv->hbox, (GdkEvent*)event);
return TRUE;
}
@@ -219,23 +176,12 @@ transport_widget_property_update(DbusmenuMenuitem* item, gchar* property,
GValue* value, gpointer userdata)
{
g_debug("transport_widget_update_state - with property %s", property);
- int update_value = g_value_get_int(value);
- g_debug("transport_widget_update_state - with value %i", update_value);
+ //int update_value = g_value_get_int(value);
+ //g_debug("transport_widget_update_state - with value %i", update_value);
- TransportWidget* bar = (TransportWidget*)userdata;
- TransportWidgetPrivate *priv = TRANSPORT_WIDGET_GET_PRIVATE(bar);
+ //TransportWidget* bar = (TransportWidget*)userdata;
+ //TransportWidgetPrivate *priv = TRANSPORT_WIDGET_GET_PRIVATE(bar);
- gtk_button_set_label(GTK_BUTTON(priv->play_button), transport_widget_toggle_play_label(update_value));
-}
-
-// will be needed for image swapping
-static gchar* transport_widget_toggle_play_label(int play_state)
-{
- gchar* label = ">";
- if(play_state == 1){
- label = "||";
- }
- return label;
}
/**
diff --git a/vapi/common-defs.vapi b/vapi/common-defs.vapi
index 222fb67..6649b26 100644
--- a/vapi/common-defs.vapi
+++ b/vapi/common-defs.vapi
@@ -30,4 +30,10 @@ namespace DbusmenuMetadata{
namespace DbusmenuTransport{
public const string MENUITEM_TYPE;
public const string MENUITEM_PLAY_STATE;
+}
+
+[CCode (cheader_filename = "common-defs.h")]
+namespace DbusmenuTitle{
+ public const string MENUITEM_TYPE;
+ public const string MENUITEM_TEXT_NAME;
} \ No newline at end of file