From b683ce2789d95b2e9f221e75adc30efd91cfb901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sat, 24 Jan 2015 11:03:06 +0100 Subject: Imported Upstream version 0.5.7 --- CMakeLists.txt | 55 ++-------- README.md | 20 +--- resources/gnome-pie.desktop | 1 + resources/ui/icon_select.ui | 64 +++++++---- resources/ui/preferences.ui | 46 ++++---- resources/ui/rename_pie.ui | 12 +- resources/ui/settings.ui | 62 +++++++++-- resources/ui/slice_select.ui | 45 ++++---- resources/ui/trigger_select.ui | 27 ++--- src/CMakeLists.txt | 4 - src/deamon.vala | 143 +++++++++++------------- src/gui/aboutWindow.vala | 26 ++--- src/gui/iconSelectWindow.vala | 216 +++++++++++++++++------------------- src/gui/indicator.vala | 13 +-- src/gui/newSliceWindow.vala | 178 +++++++++++++++--------------- src/gui/newsWindow.vala | 40 +++---- src/gui/piePreview.vala | 198 ++++++++++++++++----------------- src/gui/piePreviewCenter.vala | 65 +++++------ src/gui/piePreviewRenderer.vala | 201 ++++++++++++++++++---------------- src/gui/preferencesWindow.vala | 231 +++++++++++++++++++-------------------- src/gui/settingsWindow.vala | 88 ++++++++------- src/gui/triggerSelectWindow.vala | 78 ++++++------- src/images/image.vala | 95 ++++++++-------- src/renderers/pieRenderer.vala | 150 ++++++++++++------------- src/renderers/pieWindow.vala | 38 +++---- src/utilities/color.vala | 87 +++++++-------- src/utilities/config.vala | 62 ++++++----- src/utilities/focusGrabber.vala | 120 ++++++++------------ 28 files changed, 1162 insertions(+), 1203 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c7729e..cf015a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,24 +26,13 @@ ensure_vala_version("0.11.0" MINIMUM) find_package(PkgConfig) # check whether GTK3 is supported -pkg_check_modules(GTK3 gtk+-3.0) - -if (${GTK3_FOUND}) - pkg_check_modules(INDICATOR3 appindicator3-0.1) - pkg_check_modules(UNIQUE REQUIRED unique-3.0) - pkg_check_modules(WNCK REQUIRED libwnck-3.0) - pkg_check_modules(BAMF REQUIRED libbamf3) -else (${GTK3_FOUND}) - pkg_check_modules(GTK2 REQUIRED gtk+-2.0) - pkg_check_modules(INDICATOR appindicator-0.1) - pkg_check_modules(UNIQUE REQUIRED unique-1.0) - pkg_check_modules(WNCK REQUIRED libwnck-1.0) - pkg_check_modules(BAMF REQUIRED libbamf) -endif (${GTK3_FOUND}) - +pkg_check_modules(GTK3 REQUIRED gtk+-3.0) +pkg_check_modules(INDICATOR3 appindicator3-0.1) +pkg_check_modules(WNCK REQUIRED libwnck-3.0) +pkg_check_modules(BAMF REQUIRED libbamf3) pkg_check_modules(GIO REQUIRED gio-unix-2.0) pkg_check_modules(CAIRO REQUIRED cairo) -pkg_check_modules(GEE REQUIRED gee-1.0) +pkg_check_modules(GEE REQUIRED gee-0.8) pkg_check_modules(X11 REQUIRED x11) pkg_check_modules(XML REQUIRED libxml-2.0) pkg_check_modules(XTST REQUIRED xtst) @@ -54,7 +43,6 @@ find_library(GTHREAD_LIB gthread-2.0) set(CFLAGS ${GIO_CFLAGS} - ${GTK2_CFLAGS} ${GTK2_CFLAGS_OTHER} ${GTK3_CFLAGS} ${GTK3_CFLAGS_OTHER} ${CAIRO_CFLAGS} ${CAIRO_CFLAGS_OTHER} ${GEE_CFLAGS} ${CAIRO_CFLAGS_OTHER} @@ -66,11 +54,6 @@ set(CFLAGS # -g ) -# fallback to gtk2 if gtk3 wasn't found -if (${GTK3_FOUND}) - LIST(APPEND CFLAGS -DHAVE_GTK_3) -endif (${GTK3_FOUND}) - # fallback to gnome-menus2 if gnome-menus3 wasn't found if (${GMENU3_FOUND}) LIST(APPEND CFLAGS -DHAVE_GMENU_3) @@ -90,7 +73,6 @@ add_definitions(${CFLAGS}) set(LIBS ${GIO_LIBRARIES} - ${GTK2_LIBRARIES} ${GTK3_LIBRARIES} ${CAIRO_LIBRARIES} ${GEE_LIBRARIES} @@ -100,7 +82,6 @@ set(LIBS ${XTST_LIBRARIES} ${GMENU_LIBRARIES} ${GMENU3_LIBRARIES} - ${UNIQUE_LIBRARIES} ${X11_LIBRARIES} ${WNCK_LIBRARIES} ${BAMF_LIBRARIES} @@ -111,7 +92,6 @@ link_libraries(${LIBS}) set(LIB_PATHS ${GIO_LIBRARY_DIRS} - ${GTK2_LIBRARY_DIRS} ${GTK3_LIBRARY_DIRS} ${CAIRO_LIBRARY_DIRS} ${GEE_LIBRARY_DIRS} @@ -121,7 +101,6 @@ set(LIB_PATHS ${XTST_LIBRARY_DIRS} ${GMENU_LIBRARY_DIRS} ${GMENU3_LIBRARY_DIRS} - ${UNIQUE_LIBRARY_DIRS} ${X11_LIBRARY_DIRS} ${WNCK_LIBRARY_DIRS} ${BAMF_LIBRARY_DIRS} @@ -130,7 +109,6 @@ link_directories(${LIB_PATHS}) set(INCLUDE_PATHS ${GIO_INCLUDE_DIRS} - ${GTK2_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS} ${GEE_INCLUDE_DIRS} @@ -140,7 +118,6 @@ set(INCLUDE_PATHS ${XTST_INCLUDE_DIRS} ${GMENU_INCLUDE_DIRS} ${GMENU3_INCLUDE_DIRS} - ${UNIQUE_INCLUDE_DIRS} ${X11_INCLUDE_DIRS} ${BAMF_INCLUDE_DIRS} ${WNCK_INCLUDE_DIRS} @@ -154,8 +131,12 @@ include_directories(${INCLUDE_PATHS}) set(EXECUTABLE_OUTPUT_PATH ${gnomepie_SOURCE_DIR}) set(VALA_PKGS + gtk+-3.0 + gdk-x11-3.0 + libwnck-3.0 + libbamf3 cairo - gee-1.0 + gee-0.8 x11 gio-unix-2.0 posix @@ -177,20 +158,6 @@ else (${GMENU3_FOUND}) LIST(APPEND VALA_PKGS libgnome-menu) endif (${GMENU3_FOUND}) -if (${GTK3_FOUND}) - LIST(APPEND VALA_PKGS gtk+-3.0) - LIST(APPEND VALA_PKGS gdk-x11-3.0) - LIST(APPEND VALA_PKGS libbamf3) - LIST(APPEND VALA_PKGS libwnck-3.0) - LIST(APPEND VALA_PKGS unique-3.0) -else (${GTK3_FOUND}) - LIST(APPEND VALA_PKGS gtk+-2.0) - LIST(APPEND VALA_PKGS gdk-x11-2.0) - LIST(APPEND VALA_PKGS bamf) - LIST(APPEND VALA_PKGS libwnck-1.0) - LIST(APPEND VALA_PKGS unique-1.0) -endif (${GTK3_FOUND}) - add_subdirectory(src) ################################################################ @@ -214,7 +181,6 @@ message( "Summary:" ) message( " EXECUTABLE_OUTPUT_PATH = ${EXECUTABLE_OUTPUT_PATH}" ) message( " VALA_EXECUTABLE = ${VALA_EXECUTABLE}" ) message( "Libs:" ) -message( " GTK2_LIBRARIES = ${GTK2_LIBRARIES}" ) message( " GTK3_LIBRARIES = ${GTK3_LIBRARIES}" ) message( " CAIRO_LIBRARIES = ${CAIRO_LIBRARIES}" ) message( " GEE_LIBRARIES = ${GEE_LIBRARIES}" ) @@ -224,7 +190,6 @@ message( " XML_LIBRARIES = ${XML_LIBRARIES}" ) message( " XTST_LIBRARIES = ${XTST_LIBRARIES}" ) message( " GMENU_LIBRARIES = ${GMENU_LIBRARIES}" ) message( " GMENU3_LIBRARIES = ${GMENU3_LIBRARIES}" ) -message( " UNIQUE_LIBRARIES = ${UNIQUE_LIBRARIES}" ) message( " X11_LIBRARIES = ${X11_LIBRARIES}" ) message( " BAMF_LIBRARIES = ${BAMF_LIBRARIES}" ) message( " WNCK_LIBRARIES = ${WNCK_LIBRARIES}" ) diff --git a/README.md b/README.md index d9d6698..c8342ce 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Gnome-Pie **Gnome-Pie** is a circular application launcher for Linux. It is made of several pies, each consisting of multiple slices. The user presses a key stroke which opens the desired pie. By activating one of its slices, applications may be launched, key presses may be simulated or files can be opened. -Feel free to visit its **homepage** at http://gnome-pie.simonschneegans.de +Feel free to visit its **homepage** at http://simmesimme.github.io/gnome-pie.html It is inspired by an addon written for the game World of Warcraft. (http://go-hero.net/opie/) @@ -20,25 +20,19 @@ sudo apt-get install gnome-pie ## Compiling and installing from source! -First of all, install all dependancies. For compilation and linking against GTK3: +First of all, install all dependancies: ~~~~ sudo apt-get install libgtk-3-dev libcairo2-dev libappindicator3-dev libgee-dev libxml2-dev libxtst-dev libgnome-menu-3-dev valac cmake libunique-3.0-dev libbamf3-dev libwnck-3-dev bamfdaemon ~~~~ -For compilation and linking against GTK2: - -~~~~ -sudo apt-get install libgtk2.0-dev libcairo2-dev libappindicator-dev libgee-dev libxml2-dev libxtst-dev libgnome-menu-dev valac cmake libunique-dev libbamf-dev libwnck-dev bamfdaemon -~~~~ - Then build Gnome-Pie by typing: ~~~~ ./make.sh ~~~~ -Launch it with +Launch it with ~~~~ ./gnome-pie @@ -62,11 +56,7 @@ I really like working on Gnome-Pie — and you can help improving it! There are ### Translate Gnome-Pie! -This is really easy: [There is an easy-to-follow step-by-step-guide available](http://www.simonschneegans.de/?p=439)! - -### Create Themes for Gnome-Pie! - -If you have some ideas on how Gnome-Pie should look: It’s easy to create new themes! I would love to include some true art in this software! [There is an comprehensive guide as well](http://www.simonschneegans.de/?p=246). +This is really easy: [There is an easy-to-follow step-by-step-guide available](http://simmesimme.github.io/lessons/2011/11/09/translate-gnome-pie/)! ### Donate! @@ -74,7 +64,7 @@ If you can’t afford the time to do the stuff mentioned above, but still want t ## License -Copyright (C) 2011-2012 Simon Schneegans +Copyright (C) 2011-2015 Simon Schneegans This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/resources/gnome-pie.desktop b/resources/gnome-pie.desktop index ae5811d..e6ea73d 100755 --- a/resources/gnome-pie.desktop +++ b/resources/gnome-pie.desktop @@ -5,3 +5,4 @@ Comment=Cakes don't lie. Exec=gnome-pie Icon=gnome-pie Categories=GNOME;Utility; +Keywords=Utility;Menu; diff --git a/resources/ui/icon_select.ui b/resources/ui/icon_select.ui index 3aae9f7..6870f53 100644 --- a/resources/ui/icon_select.ui +++ b/resources/ui/icon_select.ui @@ -1,43 +1,72 @@ + - + 525 425 False Select an icon - True True True dialog - + 300 200 True False 12 + vertical - + True False + vertical 6 True True - + True False 6 + vertical 6 - + True False + 6 - + + True + False + + + + + + False + True + 0 + + + + + True + True + gtk-find + gtk-clear + False + + + True + True + 1 + @@ -47,18 +76,7 @@ - - True - True - gtk-find - gtk-clear - False - - - False - True - 1 - + @@ -92,7 +110,7 @@ True False - 6 + 0 1 @@ -117,7 +135,7 @@ - + True False 6 @@ -139,10 +157,10 @@ gtk-cancel + False True True True - False True @@ -154,10 +172,10 @@ gtk-ok + False True True True - False True diff --git a/resources/ui/preferences.ui b/resources/ui/preferences.ui index d6a5686..7712566 100644 --- a/resources/ui/preferences.ui +++ b/resources/ui/preferences.ui @@ -1,18 +1,18 @@ + - + - 600 - 475 False Gnome-Pie Settings - True center - False - + + 625 + 500 True False + vertical True @@ -20,9 +20,9 @@ both-horiz + False True False - False True General Settings True @@ -41,19 +41,21 @@ - + False 10 + vertical 10 - + True False 6 - + True False + vertical 170 @@ -79,9 +81,9 @@ 1 + False True False - False True list-add-symbolic @@ -92,9 +94,9 @@ + False True False - False True list-remove-symbolic @@ -118,21 +120,22 @@ - + True False + vertical 6 - + True False 6 + False True True True - False none False @@ -151,15 +154,16 @@ - + True False + vertical + False True True True - False none True False @@ -185,10 +189,10 @@ + False True True True - False none True False @@ -249,10 +253,11 @@ True False - + True False 2 + vertical False @@ -294,9 +299,10 @@ Start by creating one! </b> This can be done by clicking on the tiny littl - + True False + vertical diff --git a/resources/ui/rename_pie.ui b/resources/ui/rename_pie.ui index 4536598..fca075c 100644 --- a/resources/ui/rename_pie.ui +++ b/resources/ui/rename_pie.ui @@ -1,8 +1,8 @@ + - + - 350 False 5 Rename a Pie @@ -11,7 +11,6 @@ center-on-parent True dialog - False False @@ -23,10 +22,10 @@ gtk-cancel + False True True True - False True @@ -38,10 +37,10 @@ gtk-ok + False True True True - False True @@ -59,10 +58,11 @@ - + True False 6 + vertical 6 diff --git a/resources/ui/settings.ui b/resources/ui/settings.ui index 21d1fb5..d993748 100644 --- a/resources/ui/settings.ui +++ b/resources/ui/settings.ui @@ -1,9 +1,7 @@ - + - 550 - 450 False 5 General Settings @@ -15,6 +13,8 @@ False + 550 + 450 False vertical @@ -45,7 +45,8 @@ - + + vertical True False 6 @@ -65,7 +66,8 @@ 6 6 - + + vertical True False 6 @@ -143,7 +145,8 @@ 6 6 - + + vertical True False 6 @@ -164,7 +167,7 @@ - + True False 6 @@ -181,7 +184,7 @@ - + True True 2 @@ -202,6 +205,45 @@ 1 + + + True + False + 6 + + + True + False + Maximum activation radius + + + False + False + 0 + + + + + True + True + 2000 + 0 + 0 + right + + + True + True + 1 + + + + + False + True + 2 + + Display Slice labels @@ -218,7 +260,7 @@ False True - 2 + 3 @@ -226,7 +268,7 @@ - + True False Appearance diff --git a/resources/ui/slice_select.ui b/resources/ui/slice_select.ui index c09adac..e3bab16 100644 --- a/resources/ui/slice_select.ui +++ b/resources/ui/slice_select.ui @@ -1,22 +1,19 @@ + - + - 550 - 450 - 550 - 450 False 5 Slice Options - True True center-on-parent True dialog - False + 550 + 450 False vertical @@ -26,10 +23,10 @@ gtk-close + False True True True - False True @@ -41,10 +38,10 @@ gtk-ok + False True True True - False True @@ -62,10 +59,11 @@ - + True False 6 + vertical 6 @@ -98,16 +96,16 @@ 6 6 - + True False 6 + False True True True - False none @@ -125,14 +123,16 @@ - + True False + vertical True - + True False + vertical True @@ -154,7 +154,7 @@ - + True False 6 @@ -177,7 +177,6 @@ True True - True False @@ -193,7 +192,7 @@ - + True False 6 @@ -216,7 +215,6 @@ True True - True False @@ -232,7 +230,7 @@ - + True False 6 @@ -255,7 +253,6 @@ True True - True False @@ -271,7 +268,7 @@ - + True False 6 @@ -300,7 +297,7 @@ - + True False 6 @@ -329,7 +326,7 @@ - + True False 6 @@ -349,13 +346,13 @@ + False True True False True This Slice will be executed when you click in the middle of the Pie. This Slice will be executed when you click in the middle of the Pie. - False 0 True diff --git a/resources/ui/trigger_select.ui b/resources/ui/trigger_select.ui index 6ffa4a7..d98d889 100644 --- a/resources/ui/trigger_select.ui +++ b/resources/ui/trigger_select.ui @@ -1,20 +1,18 @@ + - + - 350 - 350 False 5 Activation Settings - True True center-on-parent True dialog - False + 350 False vertical @@ -24,10 +22,10 @@ gtk-cancel + False True True True - False True @@ -39,10 +37,10 @@ gtk-ok + False True True True - False True @@ -60,15 +58,17 @@ - + True False 6 + vertical 6 - + True False + vertical @@ -111,19 +111,20 @@ 6 6 - + True False + vertical Turbo mode + False True True False True If checked, the Pie will close when you release the chosen hot key. If checked, the Pie will close when you release the chosen hot key. - False 0 True @@ -136,13 +137,13 @@ Long press for activation + False True True False True If checked, the Pie will only open if you press this hot key a bit longer. If checked, the Pie will only open if you press this hot key a bit longer. - False 0 True @@ -155,13 +156,13 @@ Open Pie centered on the screen + False True True False True If checked, the Pie will open in the middle of your screen. Else it will pop up at your pointer. If checked, the Pie will open in the middle of your screen. Else it will pop up at your pointer. - False 0 True diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7138fdd..ee08045 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,10 +12,6 @@ if (${INDICATOR3_FOUND}) LIST(APPEND DEFINES --define HAVE_APPINDICATOR) endif(${INDICATOR3_FOUND}) -if (${GTK3_FOUND}) - LIST(APPEND DEFINES --define HAVE_GTK_3) -endif(${GTK3_FOUND}) - if (${GMENU3_FOUND}) LIST(APPEND DEFINES --define HAVE_GMENU_3) endif (${GMENU3_FOUND}) diff --git a/src/deamon.vala b/src/deamon.vala index fb9618b..2e79d10 100644 --- a/src/deamon.vala +++ b/src/deamon.vala @@ -36,15 +36,12 @@ public class Deamon : GLib.Object { ///////////////////////////////////////////////////////////////////// public static int main(string[] args) { - version = "0.5.6"; + version = "0.5.7"; Logger.init(); - Gdk.threads_init(); Gtk.init(ref args); Paths.init(); - message("Welcome to Gnome-Pie " + version + "!"); - // create the Deamon and run it var deamon = new GnomePie.Deamon(); deamon.run(args); @@ -83,95 +80,51 @@ public class Deamon : GLib.Object { ///////////////////////////////////////////////////////////////////// public void run(string[] args) { - // create command line options - var context = new GLib.OptionContext(""); - context.set_help_enabled(true); - context.add_main_entries(options, null); - context.add_group(Gtk.get_option_group (false)); - - try { - context.parse(ref args); - } catch(GLib.OptionError error) { - warning(error.message); - } - - if (Deamon.reset) { - if (GLib.FileUtils.remove(Paths.pie_config) == 0) - message("Removed file \"%s\"", Paths.pie_config); - if (GLib.FileUtils.remove(Paths.settings) == 0) - message("Removed file \"%s\"", Paths.settings); - - return; - } // create unique application - var app = new Unique.App("org.gnome.gnomepie", null); - - #if HAVE_GTK_3 - if (app.is_running()) { - #else - if (app.is_running) { - #endif - // inform the running instance of the pie to be opened - if (open_pie != null) { - message("Gnome-Pie is already running. Sending request to open pie " + open_pie + "."); - var data = new Unique.MessageData(); - data.set_text(open_pie, open_pie.length); - app.send_message(Unique.Command.ACTIVATE, data); - - return; - } - - message("Gnome-Pie is already running. Sending request to open config menu."); - app.send_message(Unique.Command.ACTIVATE, null); + var app = new GLib.Application("org.gnome.gnomepie", GLib.ApplicationFlags.HANDLES_COMMAND_LINE); - return; - } - - // wait for incoming messages - app.message_received.connect((cmd, data, event_time) => { - if (cmd == Unique.Command.ACTIVATE) { - var pie = data.get_text(); - - if (pie != null && pie != "") PieManager.open_pie(pie); - else this.indicator.show_preferences(); - - return Unique.Response.OK; + app.command_line.connect((cmd) => { + string[] tmp = cmd.get_arguments(); + unowned string[] remote_args = tmp; + if (!handle_command_line(remote_args, true)) { + Gtk.main_quit(); } - return Unique.Response.PASSTHROUGH; + return 0; }); - Gdk.threads_enter(); + app.startup.connect(() => { - // init locale support - Intl.bindtextdomain ("gnomepie", Paths.locales); - Intl.textdomain ("gnomepie"); + message("Welcome to Gnome-Pie " + version + "!"); - // init toolkits and static stuff - ActionRegistry.init(); - GroupRegistry.init(); + // init locale support + Intl.bindtextdomain ("gnomepie", Paths.locales); + Intl.textdomain ("gnomepie"); - PieManager.init(); - Icon.init(); + // init toolkits and static stuff + ActionRegistry.init(); + GroupRegistry.init(); - // launch the indicator - this.indicator = new Indicator(); + PieManager.init(); + Icon.init(); - // connect SigHandlers - Posix.signal(Posix.SIGINT, sig_handler); - Posix.signal(Posix.SIGTERM, sig_handler); + // launch the indicator + this.indicator = new Indicator(); - // finished loading... so run the prog! - message("Started happily..."); + // connect SigHandlers + Posix.signal(Posix.SIGINT, sig_handler); + Posix.signal(Posix.SIGTERM, sig_handler); - // open pie if neccessary - if (open_pie != null) - PieManager.open_pie(open_pie); + // finished loading... so run the prog! + message("Started happily..."); - Gtk.main(); + if (handle_command_line(args, false)) { + Gtk.main(); + } + }); - Gdk.threads_leave(); + app.run(args); } ///////////////////////////////////////////////////////////////////// @@ -183,6 +136,42 @@ public class Deamon : GLib.Object { message("Caught signal (%d), bye!".printf(sig)); Gtk.main_quit(); } + + ///////////////////////////////////////////////////////////////////// + /// Handles command line parameters. + ///////////////////////////////////////////////////////////////////// + + private bool handle_command_line(string[] args, bool show_preferences) { + // create command line options + var context = new GLib.OptionContext(""); + context.set_help_enabled(true); + context.add_main_entries(options, null); + context.add_group(Gtk.get_option_group (false)); + + try { + context.parse(ref args); + } catch(GLib.OptionError error) { + warning(error.message); + } + + if (reset) { + if (GLib.FileUtils.remove(Paths.pie_config) == 0) + message("Removed file \"%s\"", Paths.pie_config); + if (GLib.FileUtils.remove(Paths.settings) == 0) + message("Removed file \"%s\"", Paths.settings); + + return false; + } + + if (open_pie != null && open_pie != "") { + PieManager.open_pie(open_pie); + open_pie = ""; + } else if (show_preferences) { + this.indicator.show_preferences(); + } + + return true; + } } } diff --git a/src/gui/aboutWindow.vala b/src/gui/aboutWindow.vala index c6b7453..39258cb 100644 --- a/src/gui/aboutWindow.vala +++ b/src/gui/aboutWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,25 +12,25 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A simple about dialog. ///////////////////////////////////////////////////////////////////////// public class AboutWindow: Gtk.AboutDialog { - + ///////////////////////////////////////////////////////////////////// /// C'tor, creates a new about dialog. The entries are sorted alpha- /// betically. ///////////////////////////////////////////////////////////////////// - + public AboutWindow () { string[] devs = { - "Simon Schneegans ", + "Simon Schneegans ", "Francesco Piccinno " }; string[] artists = { @@ -48,29 +48,29 @@ public class AboutWindow: Gtk.AboutDialog { "Ting Zhou (ZH-CN)", "Martin Dinov (BG)" }; - + // sort translators GLib.List translator_list = new GLib.List(); foreach (var translator in translators) translator_list.append(translator); - + translator_list.sort((a, b) => { return a.ascii_casecmp(b); }); - + string translator_string = ""; foreach (var translator in translator_list) translator_string += translator + "\n"; - + GLib.Object ( artists : artists, authors : devs, translator_credits : translator_string, - copyright : "Copyright (C) 2011-2012 Simon Schneegans ", + copyright : "Copyright (C) 2011-2015 Simon Schneegans ", program_name: "Gnome-Pie", logo_icon_name: "gnome-pie", - website: "http://www.simonschneegans.de/?page_id=12", - website_label: "www.gnome-pie.simonschneegans.de", + website: "http://simmesimme.github.io/gnome-pie.html", + website_label: "Homepage", version: Deamon.version ); } diff --git a/src/gui/iconSelectWindow.vala b/src/gui/iconSelectWindow.vala index 9159f15..2560811 100644 --- a/src/gui/iconSelectWindow.vala +++ b/src/gui/iconSelectWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,29 +12,29 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// -/// A window which allows selection of an Icon of the user's current icon +///////////////////////////////////////////////////////////////////////// +/// A window which allows selection of an Icon of the user's current icon /// theme. Custom icons/images can be selested as well. Loading of icons /// happens in an extra thread and a spinner is displayed while loading. ///////////////////////////////////////////////////////////////////////// public class IconSelectWindow : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// This signal gets emitted when the user selects a new icon. ///////////////////////////////////////////////////////////////////// - + public signal void on_ok(string icon_name); - + ///////////////////////////////////////////////////////////////////// /// Stores the currently selected icon. ///////////////////////////////////////////////////////////////////// - + private string active_icon = ""; ///////////////////////////////////////////////////////////////////// @@ -42,64 +42,64 @@ public class IconSelectWindow : GLib.Object { ///////////////////////////////////////////////////////////////////// private static Gtk.ListStore icon_list = null; - + ///////////////////////////////////////////////////////////////////// /// True, if the icon theme is currently reloaded. ///////////////////////////////////////////////////////////////////// - + private static bool loading = false; - + ///////////////////////////////////////////////////////////////////// /// If set to true, the icon list will be reloaded next time the /// window opens. ///////////////////////////////////////////////////////////////////// - + private static bool need_reload = true; - + ///////////////////////////////////////////////////////////////////// /// Icons of these contexts won't appear in the list. ///////////////////////////////////////////////////////////////////// - + private const string disabled_contexts = "Animations, FileSystems"; - + ///////////////////////////////////////////////////////////////////// /// The list of icons, filtered according to the chosen type and /// filter string. ///////////////////////////////////////////////////////////////////// - + private Gtk.TreeModelFilter icon_list_filtered = null; - + ///////////////////////////////////////////////////////////////////// /// The Gtk widget displaying the icons. ///////////////////////////////////////////////////////////////////// - + private Gtk.IconView icon_view = null; - + ///////////////////////////////////////////////////////////////////// /// This spinner is displayed when the icons are loaded. ///////////////////////////////////////////////////////////////////// - + private Gtk.Spinner spinner = null; - + ///////////////////////////////////////////////////////////////////// /// A Gtk widget used for custom icon/image selection. ///////////////////////////////////////////////////////////////////// - + private Gtk.FileChooserWidget file_chooser = null; - + ///////////////////////////////////////////////////////////////////// /// The notebook containing the different icon choice possibilities: /// from the theme or custom. ///////////////////////////////////////////////////////////////////// - + private Gtk.Notebook tabs = null; - + ///////////////////////////////////////////////////////////////////// /// The main window. ///////////////////////////////////////////////////////////////////// - + private Gtk.Window window = null; - + ///////////////////////////////////////////////////////////////////// /// A little structure containing data for one icon in the icon_view. ///////////////////////////////////////////////////////////////////// @@ -109,19 +109,19 @@ public class IconSelectWindow : GLib.Object { public IconContext context; public Gdk.Pixbuf pixbuf; } - + ///////////////////////////////////////////////////////////////////// /// This queue is used for icon loading. A loading thread pushes /// icons into it --- the main thread updates the icon_view /// accordingly. ///////////////////////////////////////////////////////////////////// - + private GLib.AsyncQueue load_queue; - + ///////////////////////////////////////////////////////////////////// /// Possible icon types. ///////////////////////////////////////////////////////////////////// - + private enum IconContext { ALL, APPS, @@ -131,20 +131,20 @@ public class IconSelectWindow : GLib.Object { EMOTES, OTHER } - + ///////////////////////////////////////////////////////////////////// /// C'tor, creates a new IconSelectWindow. ///////////////////////////////////////////////////////////////////// - + public IconSelectWindow(Gtk.Window parent) { try { this.load_queue = new GLib.AsyncQueue(); - + if (IconSelectWindow.icon_list == null) { IconSelectWindow.icon_list = new Gtk.ListStore(3, typeof(string), // icon name typeof(IconContext), // icon type typeof(Gdk.Pixbuf)); // the icon itself - + // disable sorting until all icons are loaded // else loading becomes horribly slow IconSelectWindow.icon_list.set_default_sort_func(() => {return 0;}); @@ -155,10 +155,10 @@ public class IconSelectWindow : GLib.Object { else IconSelectWindow.need_reload = true; }); } - + // make the icon_view filterable this.icon_list_filtered = new Gtk.TreeModelFilter(IconSelectWindow.icon_list, null); - + Gtk.Builder builder = new Gtk.Builder(); builder.add_from_file (Paths.ui_files + "/icon_select.ui"); @@ -166,42 +166,38 @@ public class IconSelectWindow : GLib.Object { this.window = builder.get_object("window") as Gtk.Window; this.window.set_transient_for(parent); this.window.set_modal(true); - + this.tabs = builder.get_object("tabs") as Gtk.Notebook; - + this.spinner = builder.get_object("spinner") as Gtk.Spinner; this.spinner.start(); - + (builder.get_object("ok-button") as Gtk.Button).clicked.connect(on_ok_button_clicked); (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(on_cancel_button_clicked); - - var combo_box = builder.get_object("combo-box") as Gtk.VBox; - + + var combo_box = builder.get_object("combo-box") as Gtk.Box; + // context combo - #if HAVE_GTK_3 - var context_combo = new Gtk.ComboBoxText(); - #else - var context_combo = new Gtk.ComboBox.text(); - #endif - context_combo.append_text(_("All icons")); - context_combo.append_text(_("Applications")); - context_combo.append_text(_("Actions")); - context_combo.append_text(_("Places")); - context_combo.append_text(_("File types")); - context_combo.append_text(_("Emotes")); - context_combo.append_text(_("Miscellaneous")); - - context_combo.set_active(0); - - context_combo.changed.connect(() => { - this.icon_list_filtered.refilter(); - }); - + var context_combo = new Gtk.ComboBoxText(); + context_combo.append_text(_("All icons")); + context_combo.append_text(_("Applications")); + context_combo.append_text(_("Actions")); + context_combo.append_text(_("Places")); + context_combo.append_text(_("File types")); + context_combo.append_text(_("Emotes")); + context_combo.append_text(_("Miscellaneous")); + + context_combo.set_active(0); + + context_combo.changed.connect(() => { + this.icon_list_filtered.refilter(); + }); + combo_box.pack_start(context_combo, false, false); - + // string filter entry var filter = builder.get_object("filter-entry") as Gtk.Entry; - + // only display items which have the selected type // and whose name contains the text entered in the entry this.icon_list_filtered.set_visible_func((model, iter) => { @@ -209,25 +205,25 @@ public class IconSelectWindow : GLib.Object { IconContext context = IconContext.ALL; model.get(iter, 0, out name); model.get(iter, 1, out context); - + if (name == null) return false; - + return (context_combo.get_active() == context || context_combo.get_active() == IconContext.ALL) && name.down().contains(filter.text.down()); }); - + // clear when the users clicks on the "clear" icon filter.icon_release.connect((pos, event) => { if (pos == Gtk.EntryIconPosition.SECONDARY) filter.text = ""; }); - + // refilter on input filter.notify["text"].connect(() => { this.icon_list_filtered.refilter(); }); - + // container for the icon_view var scroll = builder.get_object("icon-scrolledwindow") as Gtk.ScrolledWindow; @@ -237,7 +233,7 @@ public class IconSelectWindow : GLib.Object { this.icon_view.item_padding = 2; this.icon_view.pixbuf_column = 2; this.icon_view.tooltip_column = 0; - + // set active_icon if selection changes this.icon_view.selection_changed.connect(() => { foreach (var path in this.icon_view.get_selected_items()) { @@ -246,7 +242,7 @@ public class IconSelectWindow : GLib.Object { this.icon_list_filtered.get(iter, 0, out this.active_icon); } }); - + // hide this window when the user activates an icon this.icon_view.item_activated.connect((path) => { Gtk.TreeIter iter; @@ -255,46 +251,40 @@ public class IconSelectWindow : GLib.Object { this.on_ok(this.active_icon); this.window.hide(); }); - + scroll.add(this.icon_view); - + // file chooser widget this.file_chooser = builder.get_object("filechooser") as Gtk.FileChooserWidget; var file_filter = new Gtk.FileFilter(); file_filter.add_pixbuf_formats(); - - #if HAVE_GTK_3 - file_filter.set_filter_name(_("All supported image formats")); - #else - file_filter.set_name(_("All supported image formats")); - #endif - + file_filter.set_filter_name(_("All supported image formats")); file_chooser.add_filter(file_filter); - + // set active_icon if the user selected a file file_chooser.selection_changed.connect(() => { if (file_chooser.get_filename() != null && GLib.FileUtils.test(file_chooser.get_filename(), GLib.FileTest.IS_REGULAR)) - + this.active_icon = file_chooser.get_filename(); }); - + // hide this window when the user activates a file file_chooser.file_activated.connect(() => { this.active_icon = file_chooser.get_filename(); this.on_ok(this.active_icon); this.window.hide(); }); - + this.window.set_focus(this.icon_view); this.window.delete_event.connect(this.window.hide_on_delete); - + } catch (GLib.Error e) { error("Could not load UI: %s\n", e.message); } } - + ///////////////////////////////////////////////////////////////////// /// Displays the window. The icons are reloaded if neccessary. ///////////////////////////////////////////////////////////////////// @@ -302,27 +292,27 @@ public class IconSelectWindow : GLib.Object { public void show() { this.window.show_all(); this.spinner.hide(); - + if (IconSelectWindow.need_reload) { IconSelectWindow.need_reload = false; this.load_icons(); } - } - + } + public static void clear_icons() { if (IconSelectWindow.icon_list != null) { IconSelectWindow.need_reload = true; IconSelectWindow.icon_list.clear(); } } - + ///////////////////////////////////////////////////////////////////// /// Makes the window select the icon of the given Pie. ///////////////////////////////////////////////////////////////////// - + public void set_icon(string icon) { this.active_icon = icon; - + if (icon.contains("/")) { this.file_chooser.set_filename(icon); this.tabs.set_current_page(1); @@ -330,7 +320,7 @@ public class IconSelectWindow : GLib.Object { this.icon_list_filtered.foreach((model, path, iter) => { string name = ""; model.get(iter, 0, out name); - + if (name == icon) { this.icon_view.select_path(path); this.icon_view.scroll_to_path(path, true, 0.5f, 0.0f); @@ -338,38 +328,38 @@ public class IconSelectWindow : GLib.Object { } return (name == icon); }); - + this.tabs.set_current_page(0); } - } - + } + ///////////////////////////////////////////////////////////////////// /// Called when the user clicks the ok button. ///////////////////////////////////////////////////////////////////// - + private void on_ok_button_clicked() { this.on_ok(this.active_icon); this.window.hide(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the user clicks the cancel button. ///////////////////////////////////////////////////////////////////// - + private void on_cancel_button_clicked() { this.window.hide(); } - + ///////////////////////////////////////////////////////////////////// /// (Re)load all icons. ///////////////////////////////////////////////////////////////////// - + private void load_icons() { // only if it's not loading currently if (!IconSelectWindow.loading) { IconSelectWindow.loading = true; IconSelectWindow.icon_list.clear(); - + // display the spinner if (spinner != null) this.spinner.visible = true; @@ -389,7 +379,7 @@ public class IconSelectWindow : GLib.Object { 1, new_entry.context, 2, new_entry.pixbuf); } - + // enable sorting of the icon_view if loading finished if (!IconSelectWindow.loading) { IconSelectWindow.icon_list.set_sort_column_id(0, Gtk.SortType.ASCENDING); @@ -399,19 +389,19 @@ public class IconSelectWindow : GLib.Object { }); } } - + ///////////////////////////////////////////////////////////////////// /// Loads all icons of an icon theme and pushes them into the /// load_queue. ///////////////////////////////////////////////////////////////////// - + private async void load_all() { var icon_theme = Gtk.IconTheme.get_default(); - + foreach (var context in icon_theme.list_contexts()) { if (!disabled_contexts.contains(context)) { foreach (var icon in icon_theme.list_icons(context)) { - + IconContext icon_context = IconContext.OTHER; switch(context) { case "Apps": case "Applications": @@ -426,31 +416,31 @@ public class IconSelectWindow : GLib.Object { icon_context = IconContext.ACTIONS; break; default: break; } - + Idle.add(load_all.callback); yield; - + try { // create a new entry for the queue var new_entry = new ListEntry(); new_entry.name = icon; new_entry.context = icon_context; new_entry.pixbuf = icon_theme.load_icon(icon, 32, 0); - + // some icons have only weird sizes... do not include them if (new_entry.pixbuf.width == 32) this.load_queue.push(new_entry); - + } catch (GLib.Error e) { warning("Failed to load image " + icon); } } } } - + // finished loading IconSelectWindow.loading = false; - + // hide the spinner if (spinner != null) spinner.visible = false; diff --git a/src/gui/indicator.vala b/src/gui/indicator.vala index 18d4e68..1277fb8 100644 --- a/src/gui/indicator.vala +++ b/src/gui/indicator.vala @@ -68,12 +68,9 @@ public class Indicator : GLib.Object { public Indicator() { string icon = ""; + var screen = (Gdk.X11.Screen)Gdk.Screen.get_default(); - #if HAVE_GTK_3 - if (Gdk.X11Screen.get_window_manager_name(Gdk.Screen.get_default()) == "Mutter") - #else - if (Gdk.x11_screen_get_window_manager_name(Gdk.Screen.get_default()) == "Mutter") - #endif + if (screen.get_window_manager_name() == "Mutter") icon = "gnome-pie"; else icon = "gnome-pie-symbolic"; @@ -114,7 +111,7 @@ public class Indicator : GLib.Object { this.prefs = new PreferencesWindow(); // preferences item - var item = new Gtk.ImageMenuItem.from_stock (Gtk.Stock.PREFERENCES, null); + var item = new Gtk.ImageMenuItem.with_mnemonic(_("_Preferences")); item.activate.connect(() => { this.prefs.show(); }); @@ -123,7 +120,7 @@ public class Indicator : GLib.Object { menu.append(item); // about item - item = new Gtk.ImageMenuItem.from_stock (Gtk.Stock.ABOUT, null); + item = new Gtk.ImageMenuItem.with_mnemonic(_("_About")); item.show(); item.activate.connect(() => { var about = new AboutWindow(); @@ -138,7 +135,7 @@ public class Indicator : GLib.Object { menu.append(sepa); // quit item - item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.QUIT, null); + item = new Gtk.ImageMenuItem.with_mnemonic(_("_Quit")); item.activate.connect(Gtk.main_quit); item.show(); menu.append(item); diff --git a/src/gui/newSliceWindow.vala b/src/gui/newSliceWindow.vala index ade6432..92c7701 100644 --- a/src/gui/newSliceWindow.vala +++ b/src/gui/newSliceWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A window which allows selection of a new Slice which is about to be /// added to a Pie. It can be also used to edit an existing Slice ///////////////////////////////////////////////////////////////////////// @@ -28,7 +28,7 @@ public class NewSliceWindow : GLib.Object { /// This signal gets emitted when the user confirms his selection. ///////////////////////////////////////////////////////////////////// - public signal void on_select(ActionGroup action, bool as_new_slice, int at_position); + public signal void on_select(ActionGroup action, bool as_new_slice, int at_position); ///////////////////////////////////////////////////////////////////// /// The contained list of slice types. It contains both: Groups and @@ -36,78 +36,78 @@ public class NewSliceWindow : GLib.Object { ///////////////////////////////////////////////////////////////////// private SliceTypeList slice_type_list = null; - + ///////////////////////////////////////////////////////////////////// /// The IconSelectWindow used for icon selection for a Slice. ///////////////////////////////////////////////////////////////////// - + private IconSelectWindow? icon_window = null; - + ///////////////////////////////////////////////////////////////////// /// Some widgets of this window. Loaded by a ui-builder and stored /// for later access. ///////////////////////////////////////////////////////////////////// - + private Gtk.Dialog window = null; - private Gtk.HBox name_box = null; - private Gtk.HBox command_box = null; + private Gtk.Box name_box = null; + private Gtk.Box command_box = null; private Gtk.Button icon_button = null; - private Gtk.VBox no_options_box = null; - private Gtk.HBox pie_box = null; - private Gtk.HBox hotkey_box = null; - private Gtk.HBox uri_box = null; - private Gtk.HBox quickaction_box = null; + private Gtk.Box no_options_box = null; + private Gtk.Box pie_box = null; + private Gtk.Box hotkey_box = null; + private Gtk.Box uri_box = null; + private Gtk.Box quickaction_box = null; private Gtk.Image icon = null; private Gtk.Entry name_entry = null; private Gtk.Entry command_entry = null; private Gtk.Entry uri_entry = null; private Gtk.CheckButton quickaction_checkbutton = null; - + ///////////////////////////////////////////////////////////////////// /// Two custom widgets. For Pie and hotkey selection respectively. ///////////////////////////////////////////////////////////////////// - + private PieComboList pie_select = null; private TriggerSelectButton key_select = null; - + ///////////////////////////////////////////////////////////////////// /// These members store information on the currently selected Slice. ///////////////////////////////////////////////////////////////////// - + private string current_type = ""; private string current_icon = ""; private string current_id = ""; private string current_custom_icon = ""; private string current_hotkey = ""; private string current_pie_to_open = ""; - + ///////////////////////////////////////////////////////////////////// /// The position of the edited Slice in its parent Pie. ///////////////////////////////////////////////////////////////////// - + private int slice_position = 0; - + ///////////////////////////////////////////////////////////////////// /// True, if the Slice i going to be added as a new Slice. Else it /// will edit the Slice at slice_position in its parent Pie. ///////////////////////////////////////////////////////////////////// - + private bool add_as_new_slice = true; - + ///////////////////////////////////////////////////////////////////// /// C'tor creates a new window. ///////////////////////////////////////////////////////////////////// - + public NewSliceWindow() { try { - + Gtk.Builder builder = new Gtk.Builder(); builder.add_from_file (Paths.ui_files + "/slice_select.ui"); - + this.slice_type_list = new SliceTypeList(); this.slice_type_list.on_select.connect((type, icon) => { - + this.name_box.hide(); this.command_box.hide(); this.icon_button.sensitive = false; @@ -116,9 +116,9 @@ public class NewSliceWindow : GLib.Object { this.hotkey_box.hide(); this.uri_box.hide(); this.quickaction_box.hide(); - + this.current_type = type; - + switch (type) { case "bookmarks": case "clipboard": case "devices": case "menu": case "session": case "window_list": @@ -156,101 +156,101 @@ public class NewSliceWindow : GLib.Object { break; } }); - - this.name_box = builder.get_object("name-box") as Gtk.HBox; - this.command_box = builder.get_object("command-box") as Gtk.HBox; + + this.name_box = builder.get_object("name-box") as Gtk.Box; + this.command_box = builder.get_object("command-box") as Gtk.Box; this.icon_button = builder.get_object("icon-button") as Gtk.Button; - this.no_options_box = builder.get_object("no-options-box") as Gtk.VBox; - this.pie_box = builder.get_object("pie-box") as Gtk.HBox; + this.no_options_box = builder.get_object("no-options-box") as Gtk.Box; + this.pie_box = builder.get_object("pie-box") as Gtk.Box; this.pie_select = new PieComboList(); this.pie_select.on_select.connect((id) => { this.current_pie_to_open = id; this.set_icon(PieManager.all_pies[id].icon); }); - + this.pie_box.pack_start(this.pie_select, true, true); - - this.hotkey_box = builder.get_object("hotkey-box") as Gtk.HBox; + + this.hotkey_box = builder.get_object("hotkey-box") as Gtk.Box; this.key_select = new TriggerSelectButton(false); this.hotkey_box.pack_start(this.key_select, false, true); this.key_select.on_select.connect((trigger) => { this.current_hotkey = trigger.name; }); - - this.uri_box = builder.get_object("uri-box") as Gtk.HBox; - + + this.uri_box = builder.get_object("uri-box") as Gtk.Box; + this.name_entry = builder.get_object("name-entry") as Gtk.Entry; this.uri_entry = builder.get_object("uri-entry") as Gtk.Entry; this.command_entry = builder.get_object("command-entry") as Gtk.Entry; this.quickaction_checkbutton = builder.get_object("quick-action-checkbutton") as Gtk.CheckButton; - - this.quickaction_box = builder.get_object("quickaction-box") as Gtk.HBox; - this.icon = builder.get_object("icon") as Gtk.Image; - + + this.quickaction_box = builder.get_object("quickaction-box") as Gtk.Box; + this.icon = builder.get_object("icon") as Gtk.Image; + this.icon_button.clicked.connect(on_icon_button_clicked); - + var scroll_area = builder.get_object("slice-scrolledwindow") as Gtk.ScrolledWindow; scroll_area.add(this.slice_type_list); this.window = builder.get_object("window") as Gtk.Dialog; - + (builder.get_object("ok-button") as Gtk.Button).clicked.connect(on_ok_button_clicked); (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(on_cancel_button_clicked); - + this.window.delete_event.connect(this.window.hide_on_delete); - + } catch (GLib.Error e) { error("Could not load UI: %s\n", e.message); } } - + ///////////////////////////////////////////////////////////////////// /// Sets the parent window, in order to make this window stay in /// front. ///////////////////////////////////////////////////////////////////// - + public void set_parent(Gtk.Window parent) { this.window.set_transient_for(parent); } - + ///////////////////////////////////////////////////////////////////// /// Sows the window on the screen. ///////////////////////////////////////////////////////////////////// - + public void show() { this.slice_type_list.select_first(); this.pie_select.select_first(); this.key_select.set_trigger(new Trigger()); this.window.show_all(); } - + ///////////////////////////////////////////////////////////////////// /// Reloads the window. ///////////////////////////////////////////////////////////////////// - + public void reload() { this.pie_select.reload(); } - + ///////////////////////////////////////////////////////////////////// /// Makes all widgets display stuff according to the given action. ///////////////////////////////////////////////////////////////////// - + public void set_action(ActionGroup group, int position) { this.set_default(group.parent_id, position); - + this.add_as_new_slice = false; string type = ""; - + if (group.get_type().depth() == 2) { var action = group.actions[0]; type = ActionRegistry.descriptions[action.get_type().name()].id; this.select_type(type); - + this.set_icon(action.icon); this.quickaction_checkbutton.active = action.is_quickaction; this.name_entry.text = action.name; - + switch (type) { case "app": this.current_custom_icon = action.icon; @@ -269,17 +269,17 @@ public class NewSliceWindow : GLib.Object { this.uri_entry.text = action.real_command; break; } - + } else { type = GroupRegistry.descriptions[group.get_type().name()].id; this.select_type(type); } } - + ///////////////////////////////////////////////////////////////////// /// Selects a default action. ///////////////////////////////////////////////////////////////////// - + public void set_default(string pie_id, int position) { this.slice_position = position; this.add_as_new_slice = true; @@ -292,25 +292,25 @@ public class NewSliceWindow : GLib.Object { this.command_entry.text = ""; this.uri_entry.text = ""; } - + ///////////////////////////////////////////////////////////////////// /// Selects a specific action type. ///////////////////////////////////////////////////////////////////// - + private void select_type(string type) { this.current_type = type; this.slice_type_list.select(type); } - + ///////////////////////////////////////////////////////////////////// /// Called, when the user presses the ok button. ///////////////////////////////////////////////////////////////////// - + private void on_ok_button_clicked() { this.window.hide(); - + ActionGroup group = null; - + switch (this.current_type) { case "bookmarks": group = new BookmarkGroup(this.current_id); break; case "clipboard": group = new ClipboardGroup(this.current_id); break; @@ -321,44 +321,44 @@ public class NewSliceWindow : GLib.Object { case "app": group = new ActionGroup(this.current_id); - group.add_action(new AppAction(this.name_entry.text, this.current_icon, - this.command_entry.text, + group.add_action(new AppAction(this.name_entry.text, this.current_icon, + this.command_entry.text, this.quickaction_checkbutton.active)); break; case "key": group = new ActionGroup(this.current_id); - group.add_action(new KeyAction(this.name_entry.text, this.current_icon, - this.current_hotkey, + group.add_action(new KeyAction(this.name_entry.text, this.current_icon, + this.current_hotkey, this.quickaction_checkbutton.active)); break; case "pie": group = new ActionGroup(this.current_id); - group.add_action(new PieAction(this.current_pie_to_open, + group.add_action(new PieAction(this.current_pie_to_open, this.quickaction_checkbutton.active)); break; case "uri": group = new ActionGroup(this.current_id); - group.add_action(new UriAction(this.name_entry.text, this.current_icon, - this.uri_entry.text, + group.add_action(new UriAction(this.name_entry.text, this.current_icon, + this.uri_entry.text, this.quickaction_checkbutton.active)); break; } - + this.on_select(group, this.add_as_new_slice, this.slice_position); } - + ///////////////////////////////////////////////////////////////////// /// Called when the user presses the cancel button. ///////////////////////////////////////////////////////////////////// - + private void on_cancel_button_clicked() { this.window.hide(); - } - + } + ///////////////////////////////////////////////////////////////////// /// Called when the user presses the icon select button. ///////////////////////////////////////////////////////////////////// - + private void on_icon_button_clicked(Gtk.Button button) { if (this.icon_window == null) { this.icon_window = new IconSelectWindow(this.window); @@ -367,30 +367,30 @@ public class NewSliceWindow : GLib.Object { this.set_icon(icon); }); } - + this.icon_window.show(); this.icon_window.set_icon(this.current_icon); } - + ///////////////////////////////////////////////////////////////////// /// Helper method which sets the icon of the icon select button. /// It assures that both can be displayed: A customly chosen image /// from or an icon from the current theme. ///////////////////////////////////////////////////////////////////// - + private void set_icon(string icon) { if (icon.contains("/")) try { - this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(icon, this.icon.get_pixel_size(), + this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(icon, this.icon.get_pixel_size(), this.icon.get_pixel_size(), true); } catch (GLib.Error error) { warning(error.message); } else this.icon.icon_name = icon; - + this.current_icon = icon; - } + } } } diff --git a/src/gui/newsWindow.vala b/src/gui/newsWindow.vala index 75de60e..373135f 100644 --- a/src/gui/newsWindow.vala +++ b/src/gui/newsWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,57 +12,57 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// -/// +///////////////////////////////////////////////////////////////////////// +/// ///////////////////////////////////////////////////////////////////////// public class NewsWindow: Gtk.Dialog { public static const int news_count = 2; - + ///////////////////////////////////////////////////////////////////// - /// + /// ///////////////////////////////////////////////////////////////////// public NewsWindow () { this.title = "Gnome-Pie"; - + this.set_border_width(5); - - var box = new Gtk.VBox(false, 12); - + + var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 12); + var image = new Gtk.Image.from_icon_name("gnome-pie", Gtk.IconSize.DIALOG); box.pack_start(image); - + var news = new Gtk.Label(""); news.wrap = true; news.set_width_chars(75); news.set_markup("Thank you!\n\n"); - + box.pack_start(news, false, false); - + var check = new Gtk.CheckButton.with_label("Don't show this window again."); check.toggled.connect((check_box) => { var checky = check_box as Gtk.CheckButton; - + if (checky.active) Config.global.showed_news = news_count; else Config.global.showed_news = news_count-1; - + Config.global.save(); }); - + box.pack_end(check); - + (this.get_content_area() as Gtk.VBox).pack_start(box); this.get_content_area().show_all(); - - this.add_button(Gtk.Stock.CLOSE, 0); - + + this.add_button(_("_Close"), 0); + this.response.connect((id) => { if (id == 0) this.hide(); diff --git a/src/gui/piePreview.vala b/src/gui/piePreview.vala index 3ddf6c8..0420d5e 100644 --- a/src/gui/piePreview.vala +++ b/src/gui/piePreview.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A custom widget displaying the preview of a Pie. It can be used to /// configure the displayed Pie in various aspects. ///////////////////////////////////////////////////////////////////////// @@ -31,42 +31,42 @@ class PiePreview : Gtk.DrawingArea { public signal void on_last_slice_removed(); public signal void on_first_slice_added(); - + ///////////////////////////////////////////////////////////////////// /// The internally used renderer to draw the Pie. ///////////////////////////////////////////////////////////////////// private PiePreviewRenderer renderer = null; - + ///////////////////////////////////////////////////////////////////// /// The window which pops up, when a Slice is added or edited. ///////////////////////////////////////////////////////////////////// - + private NewSliceWindow? new_slice_window = null; - + ///////////////////////////////////////////////////////////////////// /// A timer used for calculating the frame time. ///////////////////////////////////////////////////////////////////// - + private GLib.Timer timer; - + ///////////////////////////////////////////////////////////////////// /// True, when it is possible to drag a slice from this widget. /// False, when the user currently hovers over the add sign. ///////////////////////////////////////////////////////////////////// - + private bool drag_enabled = false; - + ///////////////////////////////////////////////////////////////////// /// The ID of the currently displayed Pie. ///////////////////////////////////////////////////////////////////// - + private string current_id = ""; - + ///////////////////////////////////////////////////////////////////// /// The position from where a Slice-drag started. ///////////////////////////////////////////////////////////////////// - + private int drag_start_index = -1; private string drag_start_id = ""; @@ -75,50 +75,45 @@ class PiePreview : Gtk.DrawingArea { ///////////////////////////////////////////////////////////////////// public PiePreview() { - this.renderer = new PiePreviewRenderer(); - - #if HAVE_GTK_3 - this.draw.connect(this.on_draw); - #else - this.expose_event.connect(this.on_draw); - #endif - + this.renderer = new PiePreviewRenderer(this); + + this.draw.connect(this.on_draw); this.timer = new GLib.Timer(); - this.set_events(Gdk.EventMask.POINTER_MOTION_MASK + this.set_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.ENTER_NOTIFY_MASK); - + // setup drag and drop this.enable_drag_source(); - + Gtk.TargetEntry uri_dest = {"text/uri-list", 0, 0}; Gtk.TargetEntry slice_dest = {"text/plain", Gtk.TargetFlags.SAME_WIDGET, 0}; Gtk.TargetEntry[] destinations = { uri_dest, slice_dest }; Gtk.drag_dest_set(this, Gtk.DestDefaults.ALL, destinations, Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK); - + this.drag_begin.connect(this.on_start_drag); this.drag_end.connect(this.on_end_drag); this.drag_data_received.connect(this.on_dnd_received); - + // connect mouse events this.drag_motion.connect(this.on_drag_move); this.leave_notify_event.connect(this.on_mouse_leave); - this.enter_notify_event.connect(this.on_mouse_enter); + this.enter_notify_event.connect(this.on_mouse_enter); this.motion_notify_event.connect_after(this.on_mouse_move); this.button_release_event.connect_after(this.on_button_release); this.button_press_event.connect_after(this.on_button_press); - + this.new_slice_window = new NewSliceWindow(); this.new_slice_window.on_select.connect((new_action, as_new_slice, at_position) => { var pie = PieManager.all_pies[this.current_id]; - + if (new_action.has_quickaction()) renderer.disable_quickactions(); - + if (as_new_slice) { pie.add_group(new_action, at_position+1); this.renderer.add_group(new_action, at_position+1); - + if (this.renderer.slice_count() == 1) this.on_first_slice_added(); } else { @@ -126,72 +121,74 @@ class PiePreview : Gtk.DrawingArea { this.renderer.update_group(new_action, at_position); } }); - + this.renderer.on_edit_slice.connect((pos) => { this.new_slice_window.reload(); - + this.new_slice_window.set_parent(this.get_toplevel() as Gtk.Window); this.new_slice_window.show(); - + var pie = PieManager.all_pies[this.current_id]; this.new_slice_window.set_action(pie.action_groups[pos], pos); }); - + this.renderer.on_add_slice.connect((pos) => { this.new_slice_window.reload(); - + this.new_slice_window.set_parent(this.get_toplevel() as Gtk.Window); this.new_slice_window.show(); - + this.new_slice_window.set_default(this.current_id, pos); }); - + this.renderer.on_remove_slice.connect((pos) => { - + var dialog = new Gtk.MessageDialog(this.get_toplevel() as Gtk.Window, Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Do you really want to delete this Slice?")); - + dialog.response.connect((response) => { if (response == Gtk.ResponseType.YES) { var pie = PieManager.all_pies[this.current_id]; - + pie.remove_group(pos); this.renderer.remove_group(pos); - + if (this.renderer.slice_count() == 0) this.on_last_slice_removed(); } }); - + dialog.run(); dialog.destroy(); }); } - + ///////////////////////////////////////////////////////////////////// /// Sets the currently displayed Pie to the Pie with the given ID. ///////////////////////////////////////////////////////////////////// - + public void set_pie(string id) { + var style = this.get_style_context(); + this.current_id = id; - this.modify_bg(Gtk.StateType.NORMAL, Gtk.rc_get_style(this).light[Gtk.StateType.NORMAL]); + this.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL)); this.renderer.load_pie(PieManager.all_pies[id]); - + if (id == this.drag_start_id) { this.renderer.hide_group(this.drag_start_index); } } - + ///////////////////////////////////////////////////////////////////// /// Begins the draw loop. It automatically ends, when the containing /// window becomes invisible. ///////////////////////////////////////////////////////////////////// - + public void draw_loop() { this.timer.start(); this.queue_draw(); - + GLib.Timeout.add((uint)(1000.0/Config.global.refresh_rate), () => { this.queue_draw(); return this.get_toplevel().visible; @@ -201,97 +198,92 @@ class PiePreview : Gtk.DrawingArea { ///////////////////////////////////////////////////////////////////// /// Called every frame. ///////////////////////////////////////////////////////////////////// - - #if HAVE_GTK_3 - private bool on_draw(Cairo.Context ctx) { - #else - private bool on_draw(Gtk.Widget da, Gdk.EventExpose event) { - var ctx = Gdk.cairo_create(this.get_window()); - #endif + + private bool on_draw(Cairo.Context ctx) { // store the frame time double frame_time = this.timer.elapsed(); this.timer.reset(); - + Gtk.Allocation allocation; this.get_allocation(out allocation); - + ctx.translate((int)(allocation.width*0.5), (int)(allocation.height*0.5)); - + this.renderer.draw(frame_time, ctx); - + return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse leaves the area of this widget. ///////////////////////////////////////////////////////////////////// - + public bool on_mouse_leave(Gdk.EventCrossing event) { this.renderer.on_mouse_leave(); return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse enters the area of this widget. ///////////////////////////////////////////////////////////////////// - + public bool on_mouse_enter(Gdk.EventCrossing event) { this.renderer.on_mouse_enter(); return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse moves in the area of this widget. ///////////////////////////////////////////////////////////////////// - + private bool on_mouse_move(Gdk.EventMotion event) { this.renderer.set_dnd_mode(false); Gtk.Allocation allocation; this.get_allocation(out allocation); this.renderer.on_mouse_move(event.x-allocation.width*0.5, event.y-allocation.height*0.5); - + if (this.renderer.get_active_slice() < 0) this.disable_drag_source(); else this.enable_drag_source(); - + return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when a mouse button is pressed. ///////////////////////////////////////////////////////////////////// - + private bool on_button_press() { this.renderer.on_button_press(); return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when a mouse button is released. ///////////////////////////////////////////////////////////////////// - + private bool on_button_release() { - if (!this.renderer.drag_n_drop_mode) + if (!this.renderer.drag_n_drop_mode) this.renderer.on_button_release(); return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse is moved over this widget. ///////////////////////////////////////////////////////////////////// - + private bool on_drag_move(Gdk.DragContext ctx, int x, int y, uint time) { this.renderer.set_dnd_mode(true); Gtk.Allocation allocation; this.get_allocation(out allocation); this.renderer.on_mouse_move(x-allocation.width*0.5, y-allocation.height*0.5); - + return true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the user tries to drag something from this widget. ///////////////////////////////////////////////////////////////////// - + private void on_start_drag(Gdk.DragContext ctx) { this.drag_start_index = this.renderer.get_active_slice(); this.drag_start_id = this.current_id; @@ -300,19 +292,19 @@ class PiePreview : Gtk.DrawingArea { this.renderer.hide_group(this.drag_start_index); Gtk.drag_set_icon_pixbuf(ctx, pixbuf, icon.size()/2, icon.size()/2); - + this.renderer.set_dnd_mode(true); } - + ///////////////////////////////////////////////////////////////////// /// Called when the user finishes a drag operation on this widget. /// Only used for Slice-movement. ///////////////////////////////////////////////////////////////////// - + private void on_end_drag(Gdk.DragContext context) { - + if (context.list_targets() != null) { - + int target_index = this.renderer.get_active_slice(); this.renderer.set_dnd_mode(false); @@ -328,48 +320,48 @@ class PiePreview : Gtk.DrawingArea { var dst_pie = PieManager.all_pies[this.current_id]; dst_pie.add_group(src_pie.action_groups[this.drag_start_index], target_index); this.renderer.add_group(dst_pie.action_groups[target_index], target_index); - + if (this.renderer.slices.size == 1) this.on_first_slice_added(); - + if ((context.get_actions() & Gdk.DragAction.COPY) == 0) src_pie.remove_group(this.drag_start_index); } - - + + } }); - + this.drag_start_index = -1; this.drag_start_id = ""; - } + } } - + ///////////////////////////////////////////////////////////////////// /// Called when the user finishes a drag operation on this widget. /// Only used for external drags. ///////////////////////////////////////////////////////////////////// - - private void on_dnd_received(Gdk.DragContext context, int x, int y, + + private void on_dnd_received(Gdk.DragContext context, int x, int y, Gtk.SelectionData selection_data, uint info, uint time_) { - + var pie = PieManager.all_pies[this.current_id]; int position = this.renderer.get_active_slice(); this.renderer.set_dnd_mode(false); - + foreach (var uri in selection_data.get_uris()) { pie.add_action(ActionRegistry.new_for_uri(uri), position); this.renderer.add_group(pie.action_groups[position], position); - + if (this.renderer.slices.size == 1) this.on_first_slice_added(); } } - + ///////////////////////////////////////////////////////////////////// /// Enables this widget to be a source for drag operations. ///////////////////////////////////////////////////////////////////// - + private void enable_drag_source() { if (!this.drag_enabled) { this.drag_enabled = true; @@ -378,18 +370,18 @@ class PiePreview : Gtk.DrawingArea { Gtk.drag_source_set(this, Gdk.ModifierType.BUTTON1_MASK, sources, Gdk.DragAction.MOVE | Gdk.DragAction.COPY); } } - + ///////////////////////////////////////////////////////////////////// /// Disables this widget to be a source for drag operations. - ///////////////////////////////////////////////////////////////////// - + ///////////////////////////////////////////////////////////////////// + private void disable_drag_source() { if (this.drag_enabled) { this.drag_enabled = false; Gtk.drag_source_unset(this); } } - + } } diff --git a/src/gui/piePreviewCenter.vala b/src/gui/piePreviewCenter.vala index 21bbd78..20527bc 100644 --- a/src/gui/piePreviewCenter.vala +++ b/src/gui/piePreviewCenter.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,79 +12,80 @@ 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 . +this program. If not, see . */ using GLib.Math; namespace GnomePie { -///////////////////////////////////////////////////////////////////////// -/// +///////////////////////////////////////////////////////////////////////// +/// ///////////////////////////////////////////////////////////////////////// public class PiePreviewCenter : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// THe Images displayed. When the displayed text changes the /// currently displayed text becomes the old_text. So it's possible /// to create a smooth transitions. ///////////////////////////////////////////////////////////////////// - + private RenderedText text = null; private RenderedText old_text = null; - + ///////////////////////////////////////////////////////////////////// /// Stores the currently displayed text in order to avoid frequent /// and useless updates. ///////////////////////////////////////////////////////////////////// - + private string current_text = null; - + ///////////////////////////////////////////////////////////////////// /// An AnimatedValue for smooth transitions. ///////////////////////////////////////////////////////////////////// - - private AnimatedValue blend; - + + private AnimatedValue blend; + ///////////////////////////////////////////////////////////////////// /// The parent renderer. ///////////////////////////////////////////////////////////////////// - - private unowned PiePreviewRenderer parent; - + + private unowned PiePreviewRenderer parent; + ///////////////////////////////////////////////////////////////////// /// C'tor, sets everything up. ///////////////////////////////////////////////////////////////////// - + public PiePreviewCenter(PiePreviewRenderer parent) { this.parent = parent; this.blend = new AnimatedValue.linear(0, 0, 0); - + this.text = new RenderedText("", 1, 1, "", new Color(), 1.0); this.old_text = text; } - + ///////////////////////////////////////////////////////////////////// /// Updates the currently displayed text. It will be smoothly - /// blended and may contain pango markup. + /// blended and may contain pango markup. ///////////////////////////////////////////////////////////////////// - + public void set_text(string text) { if (text != this.current_text) { - - var style = new Gtk.Style(); - + + var style = parent.parent.get_style_context(); + this.old_text = this.text; - this.text = new RenderedText.with_markup(text, 180, 180, style.font_desc.get_family()+" 10", - new Color.from_gdk(style.fg[0]), 1.0); + this.text = new RenderedText.with_markup( + text, 180, 180, style.get_font(Gtk.StateFlags.NORMAL).get_family()+" 10", + new Color.from_gdk(style.get_color(Gtk.StateFlags.NORMAL)), 1.0); this.current_text = text; - + this.blend.reset_target(0.0, 0.0); this.blend.reset_target(1.0, 0.1); } } - + ///////////////////////////////////////////////////////////////////// /// Draws the center to the given context. ///////////////////////////////////////////////////////////////////// @@ -92,15 +93,15 @@ public class PiePreviewCenter : GLib.Object { public void draw(double frame_time, Cairo.Context ctx) { this.blend.update(frame_time); - + ctx.save(); - - if (this.parent.slice_count() == 0) + + if (this.parent.slice_count() == 0) ctx.translate(0, 40); - + this.old_text.paint_on(ctx, 1-this.blend.val); this.text.paint_on(ctx, this.blend.val); - + ctx.restore(); } } diff --git a/src/gui/piePreviewRenderer.vala b/src/gui/piePreviewRenderer.vala index 6fff397..626ab73 100644 --- a/src/gui/piePreviewRenderer.vala +++ b/src/gui/piePreviewRenderer.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,110 +12,117 @@ 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 . +this program. If not, see . */ using GLib.Math; namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A complex class which is able to draw the preview of a Pie. It can /// manipulate the displayed Pie as well. ///////////////////////////////////////////////////////////////////////// public class PiePreviewRenderer : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// These signals get emitted when a slice is added, removed or /// manipulated. ///////////////////////////////////////////////////////////////////// - + public signal void on_add_slice(int position); public signal void on_remove_slice(int position); public signal void on_edit_slice(int position); - + ///////////////////////////////////////////////////////////////////// /// True, when there is currently a drag going on. ///////////////////////////////////////////////////////////////////// - + public bool drag_n_drop_mode { get; private set; default=false; } - + ///////////////////////////////////////////////////////////////////// /// A list containing all SliceRenderers of this Pie. ///////////////////////////////////////////////////////////////////// - + public Gee.ArrayList slices; - + ///////////////////////////////////////////////////////////////////// /// When a Slice is moved within a Pie it is temporarily removed. /// If so, it is stored in this member. ///////////////////////////////////////////////////////////////////// - + public PiePreviewSliceRenderer hidden_group { get; private set; default=null; } - + ///////////////////////////////////////////////////////////////////// /// The add sign which indicates that a new Slice could be added. ///////////////////////////////////////////////////////////////////// - + private PiePreviewAddSign add_sign = null; - + ///////////////////////////////////////////////////////////////////// /// The object which renders the name of the currently selected Slice /// in the middle. ///////////////////////////////////////////////////////////////////// - + private PiePreviewCenter center_renderer = null; private enum CenterDisplay { NONE, ACTIVE_SLICE, DROP, ADD, DELETE } - + ///////////////////////////////////////////////////////////////////// /// Some members storing some inter-frame-information. ///////////////////////////////////////////////////////////////////// private int active_slice = -1; - private double angle = 0.0; + private double angle = 0.0; private double mouse_x = 0.0; private double mouse_y = 0.0; - + + ///////////////////////////////////////////////////////////////////// + /// The parent DrawingArea. + ///////////////////////////////////////////////////////////////////// + + public unowned Gtk.DrawingArea parent; + ///////////////////////////////////////////////////////////////////// /// C'tor, initializes members. ///////////////////////////////////////////////////////////////////// - - public PiePreviewRenderer() { - this.slices = new Gee.ArrayList(); + + public PiePreviewRenderer(Gtk.DrawingArea parent) { + this.parent = parent; + this.slices = new Gee.ArrayList(); this.center_renderer = new PiePreviewCenter(this); this.add_sign = new PiePreviewAddSign(this); this.add_sign.load(); - + this.add_sign.on_clicked.connect((pos) => { this.on_add_slice(pos); }); } - + ///////////////////////////////////////////////////////////////////// /// Loads an Pie. All members are initialized accordingly. ///////////////////////////////////////////////////////////////////// - + public void load_pie(Pie pie) { this.slices.clear(); - + foreach (var group in pie.action_groups) { var renderer = new PiePreviewSliceRenderer(this); renderer.load(group); - + this.add_slice_renderer(renderer); this.connect_siganls(renderer); } - + this.active_slice = -1; this.update_sizes(); this.update_positions(false); } - + ///////////////////////////////////////////////////////////////////// /// Enables or disables the drag n dropn mode. ///////////////////////////////////////////////////////////////////// - + public void set_dnd_mode(bool dnd) { if (this.drag_n_drop_mode != dnd) { this.drag_n_drop_mode = dnd; @@ -123,144 +130,144 @@ public class PiePreviewRenderer : GLib.Object { this.update_sizes(); } } - + ///////////////////////////////////////////////////////////////////// /// Returns the number of Slices. ///////////////////////////////////////////////////////////////////// - + public int slice_count() { - if (this.drag_n_drop_mode && !(this.slices.size == 0)) + if (this.drag_n_drop_mode && !(this.slices.size == 0)) return slices.size+1; - + return slices.size; } - + ///////////////////////////////////////////////////////////////////// /// Returns the index of the currently hovered Slice. ///////////////////////////////////////////////////////////////////// - + public int get_active_slice() { if (this.slices.size == 0) return 0; - + if (this.drag_n_drop_mode) return (int)(this.angle/(2*PI)*this.slice_count() + 0.5) % this.slice_count(); - + return this.active_slice; } - + ///////////////////////////////////////////////////////////////////// /// Returns the Icon of the currently hovered Slice. ///////////////////////////////////////////////////////////////////// - + public Icon get_active_icon() { if (this.active_slice >= 0 && this.active_slice < this.slices.size) return this.slices[this.active_slice].icon; else return new Icon("", 24); } - + ///////////////////////////////////////////////////////////////////// /// Draws the entire Pie to the given context. ///////////////////////////////////////////////////////////////////// - + public void draw(double frame_time, Cairo.Context ctx) { this.add_sign.draw(frame_time, ctx); this.center_renderer.draw(frame_time, ctx); - + foreach (var slice in this.slices) slice.draw(frame_time, ctx); } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse leaves the drawing area of this renderer. ///////////////////////////////////////////////////////////////////// - + public void on_mouse_leave() { this.add_sign.hide(); this.update_positions(); this.update_center(CenterDisplay.NONE); - + foreach (var slice in this.slices) slice.on_mouse_leave(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse enters the drawing area of this renderer. ///////////////////////////////////////////////////////////////////// - + public void on_mouse_enter() { this.add_sign.show(); this.update_positions(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the mouse moves in the drawing area of this renderer. ///////////////////////////////////////////////////////////////////// - + public void on_mouse_move(double x, double y) { this.mouse_x = x; this.mouse_y = y; - + this.angle = acos(x/sqrt(x*x + y*y)); if (y < 0) this.angle = 2*PI - this.angle; - + if (!this.drag_n_drop_mode) this.active_slice = -1; - + bool delete_hovered = false; - + for (int i=0; i index) { this.slices.remove_at(index); @@ -268,22 +275,22 @@ public class PiePreviewRenderer : GLib.Object { this.update_sizes(); } } - + ///////////////////////////////////////////////////////////////////// /// Hides the Slice at the given position temporarily. ///////////////////////////////////////////////////////////////////// - + public void hide_group(int index) { if (this.slices.size > index) { this.hidden_group = this.slices[index]; this.remove_group(index); } } - + ///////////////////////////////////////////////////////////////////// /// Re-shows a Slice which has been hidden before. ///////////////////////////////////////////////////////////////////// - + public void show_hidden_group_at(int index) { if (this.slices.size >= index && this.hidden_group != null) { this.hidden_group.set_position(index, false); @@ -291,78 +298,78 @@ public class PiePreviewRenderer : GLib.Object { this.hidden_group = null; } } - + ///////////////////////////////////////////////////////////////////// /// Updates a Slice at the given position. ///////////////////////////////////////////////////////////////////// - + public void update_group(ActionGroup group, int index) { if (this.slices.size > index) { var renderer = new PiePreviewSliceRenderer(this); this.slices.set(index, renderer); renderer.load(group); - + this.connect_siganls(renderer); - + this.update_positions(false); this.update_sizes(); } } - + ///////////////////////////////////////////////////////////////////// /// Disables all quickactions of this pie preview. ///////////////////////////////////////////////////////////////////// - + public void disable_quickactions() { foreach (var slice in this.slices) slice.disable_quickactions(); } - + ///////////////////////////////////////////////////////////////////// /// Helper method which adds a new Slice to the given position. ///////////////////////////////////////////////////////////////////// - + private void add_slice_renderer(PiePreviewSliceRenderer renderer, int at_position = -1) { if (at_position < 0 || at_position >= this.slices.size) this.slices.add(renderer); else this.slices.insert(at_position, renderer); - + this.update_positions(false); this.update_sizes(); } - + ///////////////////////////////////////////////////////////////////// /// Helper method which connects all neccessary signals of a newly /// added Slice. ///////////////////////////////////////////////////////////////////// - + private void connect_siganls(PiePreviewSliceRenderer renderer) { renderer.on_clicked.connect((pos) => { this.on_edit_slice(pos); }); - + renderer.on_remove.connect((pos) => { this.on_remove_slice(pos); }); } - + ///////////////////////////////////////////////////////////////////// /// Moves all slices to their positions. This may happen smoothly if /// desired. ///////////////////////////////////////////////////////////////////// - + private void update_positions(bool smoothly = true) { if (this.slices.size > 0) { if (this.add_sign.visible) { int add_position = 0; add_position = (int)(this.angle/(2*PI)*this.slice_count()) % this.slice_count(); this.add_sign.set_position(add_position); - + for (int i=0; i= add_position ? i+1 : i, smoothly); } - + this.update_center(CenterDisplay.DROP); - + } else { for (int i=0; i 20) size = 0.5; else if (this.slice_count() > 8) size = 1.0 - (double)(this.slice_count() - 8)/24.0; - + this.add_sign.set_size(size); - - for (int i=0; i= 0 && this.active_slice < this.slices.size) - this.center_renderer.set_text("" + GLib.Markup.escape_text(slices[this.active_slice].name) + "\n" + this.center_renderer.set_text("" + GLib.Markup.escape_text(slices[this.active_slice].name) + "\n" + _("Click to edit") + "\n" + _("Drag to move") + ""); break; case CenterDisplay.ADD: @@ -423,7 +430,7 @@ public class PiePreviewRenderer : GLib.Object { break; case CenterDisplay.DELETE: if (this.active_slice >= 0 && this.active_slice < this.slices.size) - this.center_renderer.set_text("" + GLib.Markup.escape_text(slices[this.active_slice].name) + "\n" + this.center_renderer.set_text("" + GLib.Markup.escape_text(slices[this.active_slice].name) + "\n" + _("Click to delete") + "\n" + _("Drag to move") + ""); break; default: diff --git a/src/gui/preferencesWindow.vala b/src/gui/preferencesWindow.vala index 3055bc5..8cdc853 100644 --- a/src/gui/preferencesWindow.vala +++ b/src/gui/preferencesWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,164 +12,155 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// The settings menu of Gnome-Pie. ///////////////////////////////////////////////////////////////////////// public class PreferencesWindow : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// The ID of the currently selected Pie. ///////////////////////////////////////////////////////////////////// - + private string selected_id = ""; - + ///////////////////////////////////////////////////////////////////// /// Some Gtk widgets used by this window. ///////////////////////////////////////////////////////////////////// - + private Gtk.Window? window = null; private Gtk.Label? id_label = null; private Gtk.Label? name_label = null; private Gtk.Label? hotkey_label = null; private Gtk.Label? no_pie_label = null; private Gtk.Label? no_slice_label = null; - private Gtk.VBox? preview_box = null; + private Gtk.Box? preview_box = null; private Gtk.Image? icon = null; private Gtk.EventBox? preview_background = null; private Gtk.Button? icon_button = null; private Gtk.Button? name_button = null; private Gtk.Button? hotkey_button = null; private Gtk.ToolButton? remove_pie_button = null; - + ///////////////////////////////////////////////////////////////////// /// Some custom widgets and dialogs used by this window. ///////////////////////////////////////////////////////////////////// - + private PiePreview? preview = null; private PieList? pie_list = null; private SettingsWindow? settings_window = null; private TriggerSelectWindow? trigger_window = null; private IconSelectWindow? icon_window = null; private RenameWindow? rename_window = null; - + ///////////////////////////////////////////////////////////////////// /// C'tor, creates the window. ///////////////////////////////////////////////////////////////////// - + public PreferencesWindow() { - try { - var builder = new Gtk.Builder(); - - builder.add_from_file (Paths.ui_files + "/preferences.ui"); - - this.window = builder.get_object("window") as Gtk.Window; - - this.window.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK | - Gdk.EventMask.KEY_RELEASE_MASK | - Gdk.EventMask.KEY_PRESS_MASK | - Gdk.EventMask.POINTER_MOTION_MASK); - - #if HAVE_GTK_3 - var toolbar = builder.get_object ("toolbar") as Gtk.Widget; - toolbar.get_style_context().add_class("primary-toolbar"); - - var inline_toolbar = builder.get_object ("pies-toolbar") as Gtk.Widget; - inline_toolbar.get_style_context().add_class("inline-toolbar"); - #endif - - this.pie_list = new PieList(); - this.pie_list.on_select.connect(this.on_pie_select); - - var scroll_area = builder.get_object("pies-scrolledwindow") as Gtk.ScrolledWindow; - scroll_area.add(this.pie_list); - - this.preview = new PiePreview(); - this.preview.on_first_slice_added.connect(() => { - this.no_slice_label.hide(); - }); - - this.preview.on_last_slice_removed.connect(() => { - this.no_slice_label.show(); - }); - - preview_box = builder.get_object("preview-box") as Gtk.VBox; - this.preview_box.pack_start(preview, true, true); - - this.id_label = builder.get_object("id-label") as Gtk.Label; - this.name_label = builder.get_object("pie-name-label") as Gtk.Label; - this.hotkey_label = builder.get_object("hotkey-label") as Gtk.Label; - this.no_pie_label = builder.get_object("no-pie-label") as Gtk.Label; - this.no_slice_label = builder.get_object("no-slice-label") as Gtk.Label; - this.icon = builder.get_object("icon") as Gtk.Image; - this.preview_background = builder.get_object("preview-background") as Gtk.EventBox; - - (builder.get_object("settings-button") as Gtk.ToolButton).clicked.connect(on_settings_button_clicked); - - this.hotkey_button = builder.get_object("key-button") as Gtk.Button; - this.hotkey_button.clicked.connect(on_key_button_clicked); - - this.icon_button = builder.get_object("icon-button") as Gtk.Button; - this.icon_button.clicked.connect(on_icon_button_clicked); - - this.name_button = builder.get_object("rename-button") as Gtk.Button; - this.name_button.clicked.connect(on_rename_button_clicked); - - this.remove_pie_button = builder.get_object("remove-pie-button") as Gtk.ToolButton; - this.remove_pie_button.clicked.connect(on_remove_pie_button_clicked); - - (builder.get_object("add-pie-button") as Gtk.ToolButton).clicked.connect(on_add_pie_button_clicked); - - this.window.hide.connect(() => { - // save settings on close - Config.global.save(); - Pies.save(); - - Timeout.add(100, () => { - IconSelectWindow.clear_icons(); - return false; - }); + var builder = new Gtk.Builder.from_file(Paths.ui_files + "/preferences.ui"); + + this.window = builder.get_object("window") as Gtk.Window; + this.window.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK | + Gdk.EventMask.KEY_RELEASE_MASK | + Gdk.EventMask.KEY_PRESS_MASK | + Gdk.EventMask.POINTER_MOTION_MASK); + + var toolbar = builder.get_object ("toolbar") as Gtk.Widget; + toolbar.get_style_context().add_class("primary-toolbar"); + + var inline_toolbar = builder.get_object ("pies-toolbar") as Gtk.Widget; + inline_toolbar.get_style_context().add_class("inline-toolbar"); + + this.pie_list = new PieList(); + this.pie_list.on_select.connect(this.on_pie_select); + + var scroll_area = builder.get_object("pies-scrolledwindow") as Gtk.ScrolledWindow; + scroll_area.add(this.pie_list); + + this.preview = new PiePreview(); + this.preview.on_first_slice_added.connect(() => { + this.no_slice_label.hide(); + }); + + this.preview.on_last_slice_removed.connect(() => { + this.no_slice_label.show(); + }); + + preview_box = builder.get_object("preview-box") as Gtk.Box; + this.preview_box.pack_start(preview, true, true); + this.id_label = builder.get_object("id-label") as Gtk.Label; + this.name_label = builder.get_object("pie-name-label") as Gtk.Label; + this.hotkey_label = builder.get_object("hotkey-label") as Gtk.Label; + this.no_pie_label = builder.get_object("no-pie-label") as Gtk.Label; + this.no_slice_label = builder.get_object("no-slice-label") as Gtk.Label; + this.icon = builder.get_object("icon") as Gtk.Image; + this.preview_background = builder.get_object("preview-background") as Gtk.EventBox; + + (builder.get_object("settings-button") as Gtk.ToolButton).clicked.connect(on_settings_button_clicked); + + this.hotkey_button = builder.get_object("key-button") as Gtk.Button; + this.hotkey_button.clicked.connect(on_key_button_clicked); + + this.icon_button = builder.get_object("icon-button") as Gtk.Button; + this.icon_button.clicked.connect(on_icon_button_clicked); + + this.name_button = builder.get_object("rename-button") as Gtk.Button; + this.name_button.clicked.connect(on_rename_button_clicked); + + this.remove_pie_button = builder.get_object("remove-pie-button") as Gtk.ToolButton; + this.remove_pie_button.clicked.connect(on_remove_pie_button_clicked); + + (builder.get_object("add-pie-button") as Gtk.ToolButton).clicked.connect(on_add_pie_button_clicked); + + this.window.hide.connect(() => { + // save settings on close + Config.global.save(); + Pies.save(); + + Timeout.add(100, () => { + IconSelectWindow.clear_icons(); + return false; }); - - this.window.delete_event.connect(this.window.hide_on_delete); - - } catch (GLib.Error e) { - error("Could not load UI: %s\n", e.message); - } + }); + + this.window.delete_event.connect(this.window.hide_on_delete); } - + ///////////////////////////////////////////////////////////////////// /// Shows the window. ///////////////////////////////////////////////////////////////////// - + public void show() { this.preview.draw_loop(); this.window.show_all(); this.pie_list.select_first(); - this.preview_background.modify_bg(Gtk.StateType.NORMAL, Gtk.rc_get_style(this.window).light[0]); + + var style = this.preview_background.get_style_context(); + this.preview_background.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL)); } - + ///////////////////////////////////////////////////////////////////// /// Called when a new Pie is selected in the PieList. ///////////////////////////////////////////////////////////////////// - + private void on_pie_select(string id) { selected_id = id; - + this.no_slice_label.hide(); this.no_pie_label.hide(); this.preview_box.hide(); - + this.name_button.sensitive = false; this.hotkey_button.sensitive = false; this.icon_button.sensitive = false; this.remove_pie_button.sensitive = false; - + if (id == "") { this.id_label.label = ""; this.name_label.label = _("No Pie selected."); @@ -182,51 +173,51 @@ public class PreferencesWindow : GLib.Object { this.id_label.label = ("ID: %s").printf(pie.id); this.name_label.label = PieManager.get_name_of(pie.id); this.hotkey_label.set_markup(PieManager.get_accelerator_label_of(pie.id)); - + if (pie.icon.contains("/")) try { - this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(pie.icon, + this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(pie.icon, this.icon.get_pixel_size(), this.icon.get_pixel_size(), true); } catch (GLib.Error error) { warning(error.message); } else this.icon.icon_name = pie.icon; - + this.preview.set_pie(id); this.preview_box.show(); - + if (pie.action_groups.size == 0) { this.no_slice_label.show(); } - + this.name_button.sensitive = true; this.hotkey_button.sensitive = true; this.icon_button.sensitive = true; this.remove_pie_button.sensitive = true; } } - + ///////////////////////////////////////////////////////////////////// /// Called when the add Pie button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_add_pie_button_clicked(Gtk.ToolButton button) { var new_pie = PieManager.create_persistent_pie(_("New Pie"), "stock_unknown", null); this.pie_list.reload_all(); this.pie_list.select(new_pie.id); } - + ///////////////////////////////////////////////////////////////////// /// Called when the remove Pie button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_remove_pie_button_clicked(Gtk.ToolButton button) { if (this.selected_id != "") { var dialog = new Gtk.MessageDialog((Gtk.Window)this.window.get_toplevel(), Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Do you really want to delete the selected Pie with all contained Slices?")); - + dialog.response.connect((response) => { if (response == Gtk.ResponseType.YES) { PieManager.remove_pie(selected_id); @@ -234,16 +225,16 @@ public class PreferencesWindow : GLib.Object { this.pie_list.select_first(); } }); - + dialog.run(); dialog.destroy(); } } - + ///////////////////////////////////////////////////////////////////// /// Called when rename Pie button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_rename_button_clicked(Gtk.Button button) { if (this.rename_window == null) { this.rename_window = new RenameWindow(); @@ -256,15 +247,15 @@ public class PreferencesWindow : GLib.Object { this.pie_list.reload_all(); }); } - + this.rename_window.set_pie(selected_id); this.rename_window.show(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the hotkey button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_key_button_clicked(Gtk.Button button) { if (this.trigger_window == null) { this.trigger_window = new TriggerSelectWindow(); @@ -274,28 +265,28 @@ public class PreferencesWindow : GLib.Object { this.hotkey_label.set_markup(trigger.label_with_specials); }); } - + this.trigger_window.set_pie(selected_id); this.trigger_window.show(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the general settings button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_settings_button_clicked(Gtk.ToolButton button) { if (this.settings_window == null) { this.settings_window = new SettingsWindow(); this.settings_window.set_parent(this.window.get_toplevel() as Gtk.Window); } - + this.settings_window.show(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the icon button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_icon_button_clicked(Gtk.Button button) { if (this.icon_window == null) { this.icon_window = new IconSelectWindow(this.window); @@ -306,7 +297,7 @@ public class PreferencesWindow : GLib.Object { this.pie_list.reload_all(); }); } - + this.icon_window.show(); this.icon_window.set_icon(PieManager.all_pies[selected_id].icon); } diff --git a/src/gui/settingsWindow.vala b/src/gui/settingsWindow.vala index 81f8f7e..b03ae2f 100644 --- a/src/gui/settingsWindow.vala +++ b/src/gui/settingsWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,41 +12,41 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// The settings menu of Gnome-Pie, with options for theme switching and /// some general options. ///////////////////////////////////////////////////////////////////////// public class SettingsWindow : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// Some widgets. ///////////////////////////////////////////////////////////////////// - + private Gtk.Dialog? window = null; private ThemeList? theme_list = null; private Gtk.ToggleButton? indicator = null; private Gtk.ToggleButton? autostart = null; private Gtk.ToggleButton? captions = null; - + ///////////////////////////////////////////////////////////////////// /// C'tor creates, the dialog. ///////////////////////////////////////////////////////////////////// - + public SettingsWindow() { try { - + Gtk.Builder builder = new Gtk.Builder(); builder.add_from_file (Paths.ui_files + "/settings.ui"); this.window = builder.get_object("window") as Gtk.Dialog; - + this.theme_list = new ThemeList(); this.theme_list.on_select_new.connect(() => { this.captions.active = Config.global.show_captions; @@ -56,26 +56,26 @@ public class SettingsWindow : GLib.Object { this.captions.sensitive = false; } }); - + var scroll_area = builder.get_object("theme-scrolledwindow") as Gtk.ScrolledWindow; scroll_area.add(this.theme_list); - + (builder.get_object("close-button") as Gtk.Button).clicked.connect(on_close_button_clicked); - + this.autostart = (builder.get_object("autostart-checkbox") as Gtk.ToggleButton); this.autostart.toggled.connect(on_autostart_toggled); - + this.indicator = (builder.get_object("indicator-checkbox") as Gtk.ToggleButton); this.indicator.toggled.connect(on_indicator_toggled); - + this.captions = (builder.get_object("captions-checkbox") as Gtk.ToggleButton); this.captions.toggled.connect(on_captions_toggled); - - var scale_slider = (builder.get_object("scale-hscale") as Gtk.HScale); + + var scale_slider = (builder.get_object("scale-hscale") as Gtk.Scale); scale_slider.set_range(0.5, 2.0); scale_slider.set_increments(0.05, 0.25); scale_slider.set_value(Config.global.global_scale); - + bool changing = false; bool changed_again = false; @@ -97,56 +97,64 @@ public class SettingsWindow : GLib.Object { changed_again = true; } }); - + + var range_slider = (builder.get_object("range-hscale") as Gtk.Scale); + range_slider.set_range(100, 2000); + range_slider.set_increments(10, 100); + range_slider.set_value(Config.global.activation_range); + range_slider.value_changed.connect(() => { + Config.global.activation_range = (int)range_slider.get_value(); + }); + this.window.delete_event.connect(this.window.hide_on_delete); - + } catch (GLib.Error e) { error("Could not load UI: %s\n", e.message); } } - + ///////////////////////////////////////////////////////////////////// /// Sets the parent window, in order to make this window stay in /// front. ///////////////////////////////////////////////////////////////////// - + public void set_parent(Gtk.Window parent) { this.window.set_transient_for(parent); } - + ///////////////////////////////////////////////////////////////////// /// Displays the window on the screen. ///////////////////////////////////////////////////////////////////// - + public void show() { this.indicator.active = Config.global.show_indicator; - this.autostart.active = Config.global.auto_start; + this.autostart.active = Config.global.auto_start; this.captions.active = Config.global.show_captions; - + if (Config.global.theme.has_slice_captions) { this.captions.sensitive = true; } else { this.captions.sensitive = false; } - - this.window.show_all(); + + this.window.show_all(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the close button is clicked. ///////////////////////////////////////////////////////////////////// - + private void on_close_button_clicked() { this.window.hide(); } - + ///////////////////////////////////////////////////////////////////// /// Creates or deletes the autostart file. This code is inspired /// by project synapse as well. ///////////////////////////////////////////////////////////////////// - + private void on_autostart_toggled(Gtk.ToggleButton check_box) { - + bool active = check_box.active; if (!active && FileUtils.test(Paths.autostart, FileTest.EXISTS)) { Config.global.auto_start = false; @@ -155,9 +163,9 @@ public class SettingsWindow : GLib.Object { } else if (active && !FileUtils.test(Paths.autostart, FileTest.EXISTS)) { Config.global.auto_start = true; - - string autostart_entry = - "#!/usr/bin/env xdg-open\n" + + + string autostart_entry = + "#!/usr/bin/env xdg-open\n" + "[Desktop Entry]\n" + "Name=Gnome-Pie\n" + "Exec=" + Paths.executable + "\n" + @@ -171,7 +179,7 @@ public class SettingsWindow : GLib.Object { if (!FileUtils.test(autostart_dir, FileTest.EXISTS | FileTest.IS_DIR)) { DirUtils.create_with_parents(autostart_dir, 0755); } - + try { FileUtils.set_contents(Paths.autostart, autostart_entry); FileUtils.chmod(Paths.autostart, 0755); @@ -183,20 +191,20 @@ public class SettingsWindow : GLib.Object { } } } - + ///////////////////////////////////////////////////////////////////// /// Shows or hides the indicator. ///////////////////////////////////////////////////////////////////// - + private void on_indicator_toggled(Gtk.ToggleButton check_box) { var check = check_box as Gtk.CheckButton; Config.global.show_indicator = check.active; } - + ///////////////////////////////////////////////////////////////////// /// Shows or hides the captions of Slices. ///////////////////////////////////////////////////////////////////// - + private void on_captions_toggled(Gtk.ToggleButton check_box) { var check = check_box as Gtk.CheckButton; Config.global.show_captions = check.active; diff --git a/src/gui/triggerSelectWindow.vala b/src/gui/triggerSelectWindow.vala index 23eea3c..611c179 100644 --- a/src/gui/triggerSelectWindow.vala +++ b/src/gui/triggerSelectWindow.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,56 +12,56 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// This window allows the selection of a hotkey. It is returned in form /// of a Trigger. Therefore it can be either a keyboard driven hotkey or /// a mouse based hotkey. ///////////////////////////////////////////////////////////////////////// public class TriggerSelectWindow : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// This signal is emitted when the user selects a new hot key. ///////////////////////////////////////////////////////////////////// - + public signal void on_ok(Trigger trigger); - + ///////////////////////////////////////////////////////////////////// /// Some private members which are needed by other methods. ///////////////////////////////////////////////////////////////////// - + private Gtk.Dialog window; private Gtk.CheckButton turbo; private Gtk.CheckButton delayed; private Gtk.CheckButton centered; private TriggerSelectButton button; - + ///////////////////////////////////////////////////////////////////// /// The currently configured trigger. ///////////////////////////////////////////////////////////////////// - + private Trigger trigger = null; - + ///////////////////////////////////////////////////////////////////// /// The trigger which was active when this window was opened. It is /// stored in order to check whether anything has changed when the /// user clicks on OK. ///////////////////////////////////////////////////////////////////// - + private Trigger original_trigger = null; - + ///////////////////////////////////////////////////////////////////// /// C'tor, constructs a new TriggerSelectWindow. ///////////////////////////////////////////////////////////////////// - + public TriggerSelectWindow() { try { - + Gtk.Builder builder = new Gtk.Builder(); builder.add_from_file (Paths.ui_files + "/trigger_select.ui"); @@ -69,7 +69,7 @@ public class TriggerSelectWindow : GLib.Object { this.window = builder.get_object("window") as Gtk.Dialog; this.button = new TriggerSelectButton(true); this.button.show(); - + this.button.on_select.connect((trigger) => { this.trigger = new Trigger.from_values(trigger.key_sym, trigger.modifiers, @@ -78,80 +78,80 @@ public class TriggerSelectWindow : GLib.Object { this.delayed.active, this.centered.active); }); - - (builder.get_object("trigger-box") as Gtk.VBox).pack_start(this.button, true, true); - + + (builder.get_object("trigger-box") as Gtk.Box).pack_start(this.button, true, true); + (builder.get_object("ok-button") as Gtk.Button).clicked.connect(this.on_ok_button_clicked); (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(this.on_cancel_button_clicked); - + this.turbo = builder.get_object("turbo-check") as Gtk.CheckButton; this.turbo.toggled.connect(this.on_check_toggled); - + this.delayed = builder.get_object("delay-check") as Gtk.CheckButton; this.delayed.toggled.connect(this.on_check_toggled); - + this.centered = builder.get_object("center-check") as Gtk.CheckButton; this.centered.toggled.connect(this.on_check_toggled); - + this.window.delete_event.connect(this.window.hide_on_delete); - + } catch (GLib.Error e) { error("Could not load UI: %s\n", e.message); } } - + ///////////////////////////////////////////////////////////////////// /// Sets the parent window, in order to make this window stay in /// front. ///////////////////////////////////////////////////////////////////// - + public void set_parent(Gtk.Window parent) { this.window.set_transient_for(parent); } - + ///////////////////////////////////////////////////////////////////// /// Displays the window on the screen. ///////////////////////////////////////////////////////////////////// - + public void show() { this.window.show_all(); } - + ///////////////////////////////////////////////////////////////////// /// Initilizes all members to match the Trigger of the Pie with the /// given ID. ///////////////////////////////////////////////////////////////////// - + public void set_pie(string id) { var trigger = new Trigger.from_string(PieManager.get_accelerator_of(id)); - + this.turbo.active = trigger.turbo; this.delayed.active = trigger.delayed; this.centered.active = trigger.centered; this.original_trigger = trigger; this.trigger = trigger; - + this.button.set_trigger(trigger); } - + ///////////////////////////////////////////////////////////////////// /// Called when one of the three checkoxes is toggled. ///////////////////////////////////////////////////////////////////// - + private void on_check_toggled() { if (this.trigger != null) this.trigger = new Trigger.from_values(this.trigger.key_sym, this.trigger.modifiers, this.trigger.with_mouse, this.turbo.active, this.delayed.active, this.centered.active); } - + ///////////////////////////////////////////////////////////////////// /// Called when the OK-button is pressed. ///////////////////////////////////////////////////////////////////// - + private void on_ok_button_clicked() { var assigned_id = PieManager.get_assigned_id(this.trigger); - + if (this.trigger == this.original_trigger) { // nothing did change this.window.hide(); @@ -175,14 +175,14 @@ public class TriggerSelectWindow : GLib.Object { this.window.hide(); } } - + ///////////////////////////////////////////////////////////////////// /// Called when the cancel button is pressed. ///////////////////////////////////////////////////////////////////// - + private void on_cancel_button_clicked() { this.window.hide(); - } + } } } diff --git a/src/images/image.vala b/src/images/image.vala index 197523b..e65e34a 100644 --- a/src/images/image.vala +++ b/src/images/image.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,78 +12,73 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A class which loads image files. It can load image files in various -/// formats, including jpeg, png and svg. +/// formats, including jpeg, png and svg. ///////////////////////////////////////////////////////////////////////// public class Image : GLib.Object { - + ///////////////////////////////////////////////////////////////////// /// The internally used surface. ///////////////////////////////////////////////////////////////////// - + public Cairo.ImageSurface surface { public get; protected set; default=null; } - + ///////////////////////////////////////////////////////////////////// /// Creates an empty Image. ///////////////////////////////////////////////////////////////////// - + public Image.empty(int width, int height, Color? color = null) { this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height); - + if (color != null) { var ctx = this.context(); ctx.set_source_rgb(color.r, color.g, color.b); ctx.paint(); } } - + ///////////////////////////////////////////////////////////////////// /// Creates an image from the the given filename. ///////////////////////////////////////////////////////////////////// - + public Image.from_file(string filename) { this.load_file(filename); } - + ///////////////////////////////////////////////////////////////////// /// Creates an image from the the given filename at a given size. ///////////////////////////////////////////////////////////////////// - + public Image.from_file_at_size(string filename, int width, int height) { this.load_file_at_size(filename, width, height); } - + ///////////////////////////////////////////////////////////////////// /// Creates an image from the the given Gdk.Pixbuf. ///////////////////////////////////////////////////////////////////// - + public Image.from_pixbuf(Gdk.Pixbuf pixbuf) { if (pixbuf != null) this.load_pixbuf(pixbuf); else this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, 1, 1); } - + ///////////////////////////////////////////////////////////////////// /// Captures a part of the screen. ///////////////////////////////////////////////////////////////////// - + public Image.capture_screen(int posx, int posy, int width, int height, bool hide_pies = true) { Gdk.Window root = Gdk.get_default_root_window(); - #if HAVE_GTK_3 - Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_window(root, posx, posy, width, height); - #else - Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_drawable(null, root, null, posx, posy, 0, 0, width, height); - #endif - + Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_window(root, posx, posy, width, height); this.load_pixbuf(pixbuf); - + if (hide_pies) { // check for opened pies foreach (var window in PieManager.opened_windows) { @@ -93,21 +88,21 @@ public class Image : GLib.Object { window.get_size(out dx, out dy); var ctx = this.context(); - ctx.translate((int)(x-posx + (dx+3)/2), (int)(y-posy + (dy+3)/2)); + ctx.translate((int)(x-posx + (dx+3)/2), (int)(y-posy + (dy+3)/2)); window.background.paint_on(ctx); } } } } - + ///////////////////////////////////////////////////////////////////// /// Loads an image from the the given filename. ///////////////////////////////////////////////////////////////////// - + public void load_file(string filename) { try { var pixbuf = new Gdk.Pixbuf.from_file(filename); - + if (pixbuf != null) { this.load_pixbuf(pixbuf); } else { @@ -119,64 +114,64 @@ public class Image : GLib.Object { this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, 1, 1); } } - + ///////////////////////////////////////////////////////////////////// /// Loads an image from the the given filename at a given size. ///////////////////////////////////////////////////////////////////// - + public void load_file_at_size(string filename, int width, int height) { try { var pixbuf = new Gdk.Pixbuf.from_file_at_size(filename, width, height); - + if (pixbuf != null) { this.load_pixbuf(pixbuf); } else { warning("Failed to load " + filename + "!"); this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height); } - + } catch (GLib.Error e) { message("Error loading image file: %s", e.message); this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height); } } - + ///////////////////////////////////////////////////////////////////// /// Loads an image from the the given Gdk.Pixbuf. ///////////////////////////////////////////////////////////////////// - + public void load_pixbuf(Gdk.Pixbuf pixbuf) { this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, pixbuf.width, pixbuf.height); - + var ctx = this.context(); Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 1.0, 1.0); ctx.paint(); } - + ///////////////////////////////////////////////////////////////////// /// Paints the image onto the given Cairo.Context ///////////////////////////////////////////////////////////////////// - + public void paint_on(Cairo.Context ctx, double alpha = 1.0) { ctx.set_source_surface(this.surface, (int)(-0.5*this.width()-1), (int)(-0.5*this.height()-1)); if (alpha >= 1.0) ctx.paint(); else ctx.paint_with_alpha(alpha); } - + ///////////////////////////////////////////////////////////////////// /// Converts the image to a Gdk.Pixbuf. ///////////////////////////////////////////////////////////////////// - + public Gdk.Pixbuf to_pixbuf() { if (this.surface == null || this.surface.get_data().length <= 0) return new Gdk.Pixbuf(Gdk.Colorspace.RGB, true, 8, 1, 1); - - var pixbuf = new Gdk.Pixbuf.from_data(this.surface.get_data(), Gdk.Colorspace.RGB, true, 8, + + var pixbuf = new Gdk.Pixbuf.from_data(this.surface.get_data(), Gdk.Colorspace.RGB, true, 8, width(), height(), this.surface.get_stride(), null); - + pixbuf = pixbuf.copy(); - - // funny stuff here --- need to swap Red end Blue because Cairo + + // funny stuff here --- need to swap Red end Blue because Cairo // and Gdk are different... uint8* p = pixbuf.pixels; for (int i=0; i. +this program. If not, see . */ using GLib.Math; namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// This class renders a Pie. In order to accomplish that, it owns a /// CenterRenderer and some SliceRenderers. ///////////////////////////////////////////////////////////////////////// @@ -35,14 +35,14 @@ public class PieRenderer : GLib.Object { ///////////////////////////////////////////////////////////////////// /// The index of the currently active slice. - ///////////////////////////////////////////////////////////////////// - + ///////////////////////////////////////////////////////////////////// + public int active_slice { get; private set; } ///////////////////////////////////////////////////////////////////// /// True, if the hot keys are currently displayed. ///////////////////////////////////////////////////////////////////// - + public bool show_hotkeys { get; set; } ///////////////////////////////////////////////////////////////////// @@ -50,195 +50,195 @@ public class PieRenderer : GLib.Object { ///////////////////////////////////////////////////////////////////// public int size { get; private set; } - + ///////////////////////////////////////////////////////////////////// /// True if the pie should close when it's trigger is released. ///////////////////////////////////////////////////////////////////// - + public bool turbo_mode { get; private set; default=false; } - + ///////////////////////////////////////////////////////////////////// /// True if the pie is currently navigated with the keyboard. This is /// set to false as soon as the mouse moves. ///////////////////////////////////////////////////////////////////// - + public bool key_board_control { get; set; default=false; } - + ///////////////////////////////////////////////////////////////////// /// All SliceRenderers used to draw this Pie. ///////////////////////////////////////////////////////////////////// - + private Gee.ArrayList slices; - + ///////////////////////////////////////////////////////////////////// /// The renderer for the center of this pie. ///////////////////////////////////////////////////////////////////// - + private CenterRenderer center; - + ///////////////////////////////////////////////////////////////////// /// C'tor, initializes members. ///////////////////////////////////////////////////////////////////// - + public PieRenderer() { - this.slices = new Gee.ArrayList(); + this.slices = new Gee.ArrayList(); this.center = new CenterRenderer(this); this.quickaction = -1; this.active_slice = -2; this.size = 0; } - + ///////////////////////////////////////////////////////////////////// /// Loads a Pie. All members are initialized accordingly. ///////////////////////////////////////////////////////////////////// - + public void load_pie(Pie pie) { this.slices.clear(); - + int count = 0; foreach (var group in pie.action_groups) { foreach (var action in group.actions) { var renderer = new SliceRenderer(this); this.slices.add(renderer); renderer.load(action, slices.size-1); - + if (action.is_quickaction) { this.quickaction = count; } - + ++count; } } - + this.turbo_mode = PieManager.get_is_turbo(pie.id); - + this.set_highlighted_slice(this.quickaction); - + this.size = (int)fmax(2*Config.global.theme.radius + 2*Config.global.theme.slice_radius*Config.global.theme.max_zoom, 2*Config.global.theme.center_radius); - + // increase size if there are many slices if (slices.size > 0) { this.size = (int)fmax(this.size, - (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/slices.size)) + (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/slices.size)) + Config.global.theme.slice_radius)*2*Config.global.theme.max_zoom); } } - + ///////////////////////////////////////////////////////////////////// /// Activates the currently active slice. ///////////////////////////////////////////////////////////////////// - + public void activate() { if (this.active_slice >= 0 && this.active_slice < this.slices.size) { slices[active_slice].activate(); } - + foreach (var slice in this.slices) slice.fade_out(); - + center.fade_out(); } - + ///////////////////////////////////////////////////////////////////// /// Asks all renders to fade out. ///////////////////////////////////////////////////////////////////// - + public void cancel() { foreach (var slice in this.slices) slice.fade_out(); - + center.fade_out(); } - + ///////////////////////////////////////////////////////////////////// /// Called when the up-key is pressed. Selects the next slice towards - /// the top. + /// the top. ///////////////////////////////////////////////////////////////////// - + public void select_up() { int bottom = this.slice_count()/4; int top = this.slice_count()*3/4; - + if (this.active_slice == -1 || this.active_slice == bottom) this.set_highlighted_slice(top); else if (this.active_slice > bottom && this.active_slice < top) this.set_highlighted_slice(this.active_slice+1); else if (this.active_slice != top) this.set_highlighted_slice((this.active_slice-1+this.slice_count())%this.slice_count()); - + this.key_board_control = true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the down-key is pressed. Selects the next slice - /// towards the bottom. + /// towards the bottom. ///////////////////////////////////////////////////////////////////// - + public void select_down() { int bottom = this.slice_count()/4; int top = this.slice_count()*3/4; - + if (this.active_slice == -1 || this.active_slice == top) this.set_highlighted_slice(bottom); else if (this.active_slice > bottom && this.active_slice < top) this.set_highlighted_slice(this.active_slice-1); else if (this.active_slice != bottom) this.set_highlighted_slice((this.active_slice+1)%this.slice_count()); - + this.key_board_control = true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the left-key is pressed. Selects the next slice - /// towards the left. + /// towards the left. ///////////////////////////////////////////////////////////////////// - + public void select_left() { int left = this.slice_count()/2; int right = 0; - + if (this.active_slice == -1 || this.active_slice == right) this.set_highlighted_slice(left); else if (this.active_slice > left) this.set_highlighted_slice(this.active_slice-1); else if (this.active_slice < left) this.set_highlighted_slice(this.active_slice+1); - + this.key_board_control = true; } - + ///////////////////////////////////////////////////////////////////// /// Called when the right-key is pressed. Selects the next slice - /// towards the right. + /// towards the right. ///////////////////////////////////////////////////////////////////// - + public void select_right() { int left = this.slice_count()/2; int right = 0; - + if (this.active_slice == -1 || this.active_slice == left) this.set_highlighted_slice(right); else if (this.active_slice > left) this.set_highlighted_slice((this.active_slice+1)%this.slice_count()); else if (this.active_slice < left && this.active_slice != right) this.set_highlighted_slice((this.active_slice-1+this.slice_count())%this.slice_count()); - + this.key_board_control = true; } - + ///////////////////////////////////////////////////////////////////// /// Returns the amount of slices in this pie. ///////////////////////////////////////////////////////////////////// - + public int slice_count() { return slices.size; } - + ///////////////////////////////////////////////////////////////////// /// Draws the entire pie. ///////////////////////////////////////////////////////////////////// - + public void draw(double frame_time, Cairo.Context ctx, int mouse_x, int mouse_y) { if (this.size > 0) { double distance = sqrt(mouse_x*mouse_x + mouse_y*mouse_y); @@ -247,62 +247,62 @@ public class PieRenderer : GLib.Object { if (this.key_board_control) { angle = 2.0*PI*this.active_slice/(double)slice_count(); } else { - + if (distance > 0) { angle = acos(mouse_x/distance); - if (mouse_y < 0) + if (mouse_y < 0) angle = 2*PI - angle; } - + int next_active_slice = this.active_slice; - + if (distance < Config.global.theme.active_radius && this.quickaction >= 0 && this.quickaction < this.slices.size) { - - next_active_slice = this.quickaction; + + next_active_slice = this.quickaction; angle = 2.0*PI*quickaction/(double)slice_count(); - } else if (distance > Config.global.theme.active_radius && this.slice_count() > 0) { + } else if (distance > Config.global.theme.active_radius && this.slice_count() > 0 && distance < Config.global.activation_range) { next_active_slice = (int)(angle*slices.size/(2*PI) + 0.5) % this.slice_count(); } else { next_active_slice = -1; } - + this.set_highlighted_slice(next_active_slice); } center.draw(frame_time, ctx, angle, distance); - + foreach (var slice in this.slices) slice.draw(frame_time, ctx, angle, distance); } } - + ///////////////////////////////////////////////////////////////////// /// Called when the user moves the mouse. ///////////////////////////////////////////////////////////////////// - + public void on_mouse_move() { this.key_board_control = false; } - + ///////////////////////////////////////////////////////////////////// /// Called when the currently active slice changes. ///////////////////////////////////////////////////////////////////// - + public void set_highlighted_slice(int index) { if (index != this.active_slice) { - if (index >= 0 && index < this.slice_count()) + if (index >= 0 && index < this.slice_count()) this.active_slice = index; else if (this.quickaction >= 0) this.active_slice = this.quickaction; else this.active_slice = -1; - + SliceRenderer? active = (this.active_slice >= 0 && this.active_slice < this.slice_count()) ? this.slices[this.active_slice] : null; - + center.set_active_slice(active); - + foreach (var slice in this.slices) slice.set_active_slice(active); } diff --git a/src/renderers/pieWindow.vala b/src/renderers/pieWindow.vala index a95b3e3..da346dd 100644 --- a/src/renderers/pieWindow.vala +++ b/src/renderers/pieWindow.vala @@ -89,11 +89,7 @@ public class PieWindow : Gtk.Window { // check for compositing if (this.screen.is_composited()) { - #if HAVE_GTK_3 - this.set_visual(this.screen.get_rgba_visual()); - #else - this.set_colormap(this.screen.get_rgba_colormap()); - #endif + this.set_visual(this.screen.get_rgba_visual()); this.has_compositing = true; } @@ -147,11 +143,7 @@ public class PieWindow : Gtk.Window { }); // draw the pie on expose - #if HAVE_GTK_3 - this.draw.connect(this.draw_window); - #else - this.expose_event.connect(this.draw_window); - #endif + this.draw.connect(this.draw_window); } ///////////////////////////////////////////////////////////////////// @@ -214,13 +206,7 @@ public class PieWindow : Gtk.Window { /// Draw the Pie. ///////////////////////////////////////////////////////////////////// - #if HAVE_GTK_3 - private bool draw_window(Cairo.Context ctx) { - #else - private bool draw_window(Gtk.Widget da, Gdk.EventExpose event) { - // clear the window - var ctx = Gdk.cairo_create(this.get_window()); - #endif + private bool draw_window(Cairo.Context ctx) { // paint the background image if there is no compositing if (this.has_compositing) { ctx.set_operator (Cairo.Operator.CLEAR); @@ -237,7 +223,17 @@ public class PieWindow : Gtk.Window { // get the mouse position double mouse_x = 0.0, mouse_y = 0.0; - this.get_pointer(out mouse_x, out mouse_y); + Gdk.ModifierType mask; + + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); + GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); + + foreach(var device in list) { + if (device.input_source != Gdk.InputSource.KEYBOARD) { + this.get_window().get_device_position_double(device, out mouse_x, out mouse_y, out mask); + } + } // store the frame time double frame_time = this.timer.elapsed(); @@ -260,7 +256,11 @@ public class PieWindow : Gtk.Window { this.on_closing(); Gtk.grab_remove(this); FocusGrabber.ungrab(); - this.renderer.activate(); + + GLib.Timeout.add(10, () => { + this.renderer.activate(); + return false; + }); GLib.Timeout.add((uint)(Config.global.theme.fade_out_time*1000), () => { this.closed = true; diff --git a/src/utilities/color.vala b/src/utilities/color.vala index 836411e..bf60e3f 100644 --- a/src/utilities/color.vala +++ b/src/utilities/color.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,14 +12,14 @@ 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 . +this program. If not, see . */ using GLib.Math; namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A Color class with full rgb/hsv support /// and some useful utility methods. ///////////////////////////////////////////////////////////////////////// @@ -35,15 +35,15 @@ public class Color: GLib.Object { private float _g; private float _b; private float _a; - + ///////////////////////////////////////////////////////////////////// /// Creates a white Color. ///////////////////////////////////////////////////////////////////// - + public Color() { Color.from_rgb(1.0f, 1.0f, 1.0f); } - + ///////////////////////////////////////////////////////////////////// /// Creates a solid color with the given RGB values. ///////////////////////////////////////////////////////////////////// @@ -51,47 +51,48 @@ public class Color: GLib.Object { public Color.from_rgb(float red, float green, float blue) { Color.from_rgba(red, green, blue, 1.0f); } - + ///////////////////////////////////////////////////////////////////// /// Creates a translucient color with the given RGBA values. ///////////////////////////////////////////////////////////////////// - + public Color.from_rgba(float red, float green, float blue, float alpha) { r = red; g = green; b = blue; a = alpha; } - + ///////////////////////////////////////////////////////////////////// /// Creates a color from the given Gdk.Color ///////////////////////////////////////////////////////////////////// - - public Color.from_gdk(Gdk.Color color) { - Color.from_rgb( - (float)color.red/65535.0f, - (float)color.green/65535.0f, - (float)color.blue/65535.0f + + public Color.from_gdk(Gdk.RGBA color) { + Color.from_rgba( + (float)color.red, + (float)color.green, + (float)color.blue, + (float)color.alpha ); } - + ///////////////////////////////////////////////////////////////////// /// Creates a color, parsed from a string, such as #22EE33 ///////////////////////////////////////////////////////////////////// - + public Color.from_string(string hex_string) { - Gdk.Color color; - Gdk.Color.parse(hex_string, out color); + var color = Gdk.RGBA(); + color.parse(hex_string); Color.from_gdk(color); } - + ///////////////////////////////////////////////////////////////////// /// Gets the main color from an Image. Code from Unity. ///////////////////////////////////////////////////////////////////// - + public Color.from_icon(Image icon) { unowned uchar[] data = icon.surface.get_data(); - + uint width = icon.surface.get_width(); uint height = icon.surface.get_height(); uint row_bytes = icon.surface.get_stride(); @@ -99,7 +100,7 @@ public class Color: GLib.Object { double total = 0.0; double rtotal = 0.0; double gtotal = 0.0; - double btotal = 0.0; + double btotal = 0.0; for (uint i = 0; i < width; ++i) { for (uint j = 0; j < height; ++j) { @@ -126,7 +127,7 @@ public class Color: GLib.Object { v = 1.0f; } - + ///////////////////////////////////////////////////////////////////// /// The reddish part of the color. ///////////////////////////////////////////////////////////////////// @@ -138,14 +139,14 @@ public class Color: GLib.Object { set { if (value > 1.0f) _r = 1.0f; else if (value < 0.0f) _r = 0.0f; - else _r = value; + else _r = value; } } - + ///////////////////////////////////////////////////////////////////// /// The greenish part of the color. ///////////////////////////////////////////////////////////////////// - + public float g { get { return _g; @@ -153,14 +154,14 @@ public class Color: GLib.Object { set { if (value > 1.0f) _g = 1.0f; else if (value < 0.0f) _g = 0.0f; - else _g = value; + else _g = value; } } - + ///////////////////////////////////////////////////////////////////// /// The blueish part of the color. ///////////////////////////////////////////////////////////////////// - + public float b { get { return _b; @@ -168,14 +169,14 @@ public class Color: GLib.Object { set { if (value > 1.0f) _b = 1.0f; else if (value < 0.0f) _b = 0.0f; - else _b = value; + else _b = value; } } - + ///////////////////////////////////////////////////////////////////// /// The transparency of the color. ///////////////////////////////////////////////////////////////////// - + public float a { get { return _a; @@ -183,14 +184,14 @@ public class Color: GLib.Object { set { if (value > 1.0f) _a = 1.0f; else if (value < 0.0f) _a = 0.0f; - else _a = value; + else _a = value; } } - + ///////////////////////////////////////////////////////////////////// /// The hue of the color. ///////////////////////////////////////////////////////////////////// - + public float h { get { if (s > 0.0f) { @@ -210,11 +211,11 @@ public class Color: GLib.Object { setHSV(value, s, v); } } - + ///////////////////////////////////////////////////////////////////// /// The saturation of the color. ///////////////////////////////////////////////////////////////////// - + public float s { get { if (v == 0.0f) return 0.0f; @@ -226,11 +227,11 @@ public class Color: GLib.Object { else setHSV(h, value, v); } } - + ///////////////////////////////////////////////////////////////////// /// The value of the color. ///////////////////////////////////////////////////////////////////// - + public float v { get { return fmaxf(fmaxf(r, g), b); @@ -241,16 +242,16 @@ public class Color: GLib.Object { else setHSV(h, s, value); } } - + ///////////////////////////////////////////////////////////////////// /// Inverts the color. ///////////////////////////////////////////////////////////////////// - + public void invert() { h += 180.0f; v = 1.0f - v; } - + ///////////////////////////////////////////////////////////////////// /// Private member, used to apply color changes. ///////////////////////////////////////////////////////////////////// diff --git a/src/utilities/config.vala b/src/utilities/config.vala index 1d8b714..2ec2788 100644 --- a/src/utilities/config.vala +++ b/src/utilities/config.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// A singleton class for storing global settings. These settings can /// be loaded from and saved to an XML file. ///////////////////////////////////////////////////////////////////////// @@ -29,11 +29,11 @@ public class Config : GLib.Object { ///////////////////////////////////////////////////////////////////// private static Config _instance = null; - + ///////////////////////////////////////////////////////////////////// /// Returns the singleton instance. ///////////////////////////////////////////////////////////////////// - + public static Config global { get { if (_instance == null) { @@ -46,7 +46,7 @@ public class Config : GLib.Object { _instance = value; } } - + ///////////////////////////////////////////////////////////////////// /// All settings variables. ///////////////////////////////////////////////////////////////////// @@ -54,16 +54,17 @@ public class Config : GLib.Object { public Theme theme { get; set; } public double refresh_rate { get; set; default = 60.0; } public double global_scale { get; set; default = 1.0; } + public int activation_range { get; set; default = 300; } public bool show_indicator { get; set; default = true; } public bool show_captions { get; set; default = true; } public bool auto_start { get; set; default = false; } public int showed_news { get; set; default = 0; } public Gee.ArrayList themes { get; private set; } - + ///////////////////////////////////////////////////////////////////// /// Saves all above variables to a file. ///////////////////////////////////////////////////////////////////// - + public void save() { var writer = new Xml.TextWriter.filename(Paths.settings); writer.start_document("1.0"); @@ -71,28 +72,29 @@ public class Config : GLib.Object { writer.write_attribute("theme", theme.name); writer.write_attribute("refresh_rate", refresh_rate.to_string()); writer.write_attribute("global_scale", global_scale.to_string()); + writer.write_attribute("activation_range", activation_range.to_string()); writer.write_attribute("show_indicator", show_indicator ? "true" : "false"); writer.write_attribute("show_captions", show_captions ? "true" : "false"); writer.write_attribute("showed_news", showed_news.to_string()); writer.end_element(); writer.end_document(); } - + ///////////////////////////////////////////////////////////////////// /// Loads all settings variables from a file. ///////////////////////////////////////////////////////////////////// - + private void load() { - + // check for auto_start filename this.auto_start = FileUtils.test(Paths.autostart, FileTest.EXISTS); - + // parse the settings file Xml.Parser.init(); Xml.Doc* settingsXML = Xml.Parser.parse_file(Paths.settings); bool error_occrured = false; string theme_name = ""; - + if (settingsXML != null) { Xml.Node* root = settingsXML->get_root_element(); @@ -101,7 +103,7 @@ public class Config : GLib.Object { for (Xml.Attr* attribute = root->properties; attribute != null; attribute = attribute->next) { string attr_name = attribute->name.down(); string attr_content = attribute->children->content; - + switch (attr_name) { case "theme": theme_name = attr_content; @@ -113,6 +115,10 @@ public class Config : GLib.Object { global_scale = double.parse(attr_content); global_scale.clamp(0.5, 2.0); break; + case "activation_range": + activation_range = int.parse(attr_content); + activation_range.clamp(100, 2000); + break; case "show_indicator": show_indicator = bool.parse(attr_content); break; @@ -127,45 +133,45 @@ public class Config : GLib.Object { break; } } - + Xml.Parser.cleanup(); - + } else { warning("Error loading settings: gnome-pie.conf is empty! Using defaults..."); error_occrured = true; } - + delete settingsXML; - + } else { warning("Error loading settings: gnome-pie.conf not found! Using defaults..."); error_occrured = true; } - + load_themes(theme_name); if (error_occrured) save(); } - + ///////////////////////////////////////////////////////////////////// /// Registers all themes in the user's and in the global /// theme directory. ///////////////////////////////////////////////////////////////////// - + public void load_themes(string current) { themes = new Gee.ArrayList(); try { string name; - + // load global themes var d = Dir.open(Paths.global_themes); while ((name = d.read_name()) != null) { var theme = new Theme(Paths.global_themes + "/" + name); - + if (theme.load()) themes.add(theme); } - + // load local themes d = Dir.open(Paths.local_themes); while ((name = d.read_name()) != null) { @@ -173,11 +179,11 @@ public class Config : GLib.Object { if (theme.load()) themes.add(theme); } - + } catch (Error e) { warning (e.message); - } - + } + if (themes.size > 0) { if (current == "") { current = "Unity"; @@ -197,7 +203,7 @@ public class Config : GLib.Object { } else error("No theme found!"); } - + } } diff --git a/src/utilities/focusGrabber.vala b/src/utilities/focusGrabber.vala index e5900d6..b551def 100644 --- a/src/utilities/focusGrabber.vala +++ b/src/utilities/focusGrabber.vala @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2011 by Simon Schneegans This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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 . +this program. If not, see . */ namespace GnomePie { -///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// /// Some helper methods which focus the input on a given Gtk.Window. ///////////////////////////////////////////////////////////////////////// @@ -27,7 +27,7 @@ public class FocusGrabber : GLib.Object { /// Utilities for grabbing focus. /// Code roughly from Gnome-Do/Synapse. ///////////////////////////////////////////////////////////////////// - + public static void grab(Gdk.Window window, bool keyboard = true, bool pointer = true, bool owner_events = true) { if (keyboard || pointer) { window.raise(); @@ -42,90 +42,56 @@ public class FocusGrabber : GLib.Object { } } } - + ///////////////////////////////////////////////////////////////////// /// Code roughly from Gnome-Do/Synapse. ///////////////////////////////////////////////////////////////////// - + public static void ungrab(bool keyboard = true, bool pointer = true) { - #if HAVE_GTK_3 - - var display = Gdk.Display.get_default(); - var manager = display.get_device_manager(); - - #if VALA_0_16 || VALA_0_17 - GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); - #else - unowned GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); - #endif - - foreach(var device in list) { - if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) - || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) - - device.ungrab(Gdk.CURRENT_TIME); - } - - #else - - if (pointer) Gdk.pointer_ungrab(Gdk.CURRENT_TIME); - if (keyboard) Gdk.keyboard_ungrab(Gdk.CURRENT_TIME); - - #endif + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); + + GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); + + foreach(var device in list) { + if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) + || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) + + device.ungrab(Gdk.CURRENT_TIME); + } } - + ///////////////////////////////////////////////////////////////////// /// Code roughly from Gnome-Do/Synapse. ///////////////////////////////////////////////////////////////////// - + private static bool try_grab_window(Gdk.Window window, bool keyboard, bool pointer, bool owner_events) { - #if HAVE_GTK_3 - - var display = Gdk.Display.get_default(); - var manager = display.get_device_manager(); - - bool grabbed_all = true; - - #if VALA_0_16 - GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); - #else - unowned GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); - #endif - - foreach(var device in list) { - if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) - || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) { - - var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, owner_events, - Gdk.EventMask.ALL_EVENTS_MASK, null, Gdk.CURRENT_TIME); - - if (status != Gdk.GrabStatus.SUCCESS) - grabbed_all = false; - } - } - - if (grabbed_all) - return true; - - ungrab(keyboard, pointer); - - #else - - if (!pointer || Gdk.pointer_grab(window, owner_events, Gdk.EventMask.BUTTON_PRESS_MASK | - Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK, - null, null, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { - - if (!keyboard || Gdk.keyboard_grab(window, owner_events, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { - return true; - } else if (pointer) { - ungrab(false, true); - return false; - } + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); + + bool grabbed_all = true; + + GLib.List list = manager.list_devices(Gdk.DeviceType.MASTER); + + foreach(var device in list) { + if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) + || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) { + + var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, owner_events, + Gdk.EventMask.ALL_EVENTS_MASK, null, Gdk.CURRENT_TIME); + + if (status != Gdk.GrabStatus.SUCCESS) + grabbed_all = false; } - #endif - + } + + if (grabbed_all) + return true; + + ungrab(keyboard, pointer); + return false; - } + } } } -- cgit v1.2.3