diff options
| author | Moritz Eberl <moritz@semiodesk.com> | 2016-04-13 14:05:30 +0000 |
|---|---|---|
| committer | Moritz Eberl <moritz@semiodesk.com> | 2016-04-13 14:05:30 +0000 |
| commit | 3a1aa63dc5df1aaebe89226e484f49289cae5f7c (patch) | |
| tree | 4afa9d90d2650f27f0411bc52ef608dca5e5a88b | |
| parent | Merge (diff) | |
| parent | gimpcolorwheel: Fix deprecated gtk_widget_style_attach #Hackfest2016 (diff) | |
| download | inkscape-3a1aa63dc5df1aaebe89226e484f49289cae5f7c.tar.gz inkscape-3a1aa63dc5df1aaebe89226e484f49289cae5f7c.zip | |
Merge and fixed CMake build
(bzr r14761.1.5)
25 files changed, 1583 insertions, 849 deletions
diff --git a/CMakeScripts/DefineDependsandFlags.cmake b/CMakeScripts/DefineDependsandFlags.cmake index 054c08a74..61500fe97 100644 --- a/CMakeScripts/DefineDependsandFlags.cmake +++ b/CMakeScripts/DefineDependsandFlags.cmake @@ -19,7 +19,7 @@ if(WIN32) link_directories($ENV{DEVLIBS_PATH}/lib) endif() -pkg_check_modules(INKSCAPE_DEP REQUIRED pangocairo pangoft2 fontconfig gthread-2.0 gsl) +pkg_check_modules(INKSCAPE_DEP REQUIRED pangocairo pangoft2 fontconfig gthread-2.0 gsl gmodule-2.0) list(APPEND INKSCAPE_LIBS ${INKSCAPE_DEP_LDFLAGS}) list(APPEND INKSCAPE_INCS_SYS ${INKSCAPE_DEP_INCLUDE_DIRS}) list(APPEND INKSCAPE_LIBS ${INKSCAPE_DEP_LIBRARIES}) @@ -210,7 +210,7 @@ set(TRY_GTKSPELL 1) # use patched version until GTK2_CAIROMMCONFIG_INCLUDE_DIR is added if("${WITH_GTK3_EXPERIMENTAL}") pkg_check_modules( - GTK + GTK3 REQUIRED gtkmm-3.0>=3.8 gdkmm-3.0>=3.8 @@ -219,7 +219,7 @@ if("${WITH_GTK3_EXPERIMENTAL}") gdl-3.0>=3.4 ) message("Using EXPERIMENTAL Gtkmm 3 build") - list(APPEND INKSCAPE_CXX_FLAGS ${GTK_CFLAGS_OTHER}) + list(APPEND INKSCAPE_CXX_FLAGS ${GTK3_CFLAGS_OTHER}) set(WITH_GTKMM_3_0 1) message("Using external GDL") set(WITH_EXT_GDL 1) @@ -251,12 +251,12 @@ if("${WITH_GTK3_EXPERIMENTAL}") set (WITH_GTKSPELL 1) endif() list(APPEND INKSCAPE_INCS_SYS - ${GTK_INCLUDE_DIRS} + ${GTK3_INCLUDE_DIRS} ${GTKSPELL3_INCLUDE_DIRS} ) list(APPEND INKSCAPE_LIBS - ${GTK_LIBRARIES} + ${GTK3_LIBRARIES} ${GTKSPELL3_LIBRARIES} ) else() diff --git a/CMakeScripts/Modules/FindGTK2.cmake b/CMakeScripts/Modules/FindGTK2.cmake deleted file mode 100644 index e986fddfd..000000000 --- a/CMakeScripts/Modules/FindGTK2.cmake +++ /dev/null @@ -1,597 +0,0 @@ -# *NOTE*, this file include 1 line modification from 2.8.5's module -# this adds GTK2_CAIROMM_INCLUDE_DIR which we need! -# - ideasman42 -# ------------ - -# - FindGTK2.cmake -# This module can find the GTK2 widget libraries and several of its other -# optional components like gtkmm, glade, and glademm. -# -# NOTE: If you intend to use version checking, CMake 2.6.2 or later is -# required. -# -# Specify one or more of the following components -# as you call this find module. See example below. -# -# gtk -# gtkmm -# glade -# glademm -# -# The following variables will be defined for your use -# -# GTK2_FOUND - Were all of your specified components found? -# GTK2_INCLUDE_DIRS - All include directories -# GTK2_LIBRARIES - All libraries -# -# GTK2_VERSION - The version of GTK2 found (x.y.z) -# GTK2_MAJOR_VERSION - The major version of GTK2 -# GTK2_MINOR_VERSION - The minor version of GTK2 -# GTK2_PATCH_VERSION - The patch version of GTK2 -# -# Optional variables you can define prior to calling this module: -# -# GTK2_DEBUG - Enables verbose debugging of the module -# GTK2_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced -# GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to -# search for include files -# -#================= -# Example Usage: -# -# Call find_package() once, here are some examples to pick from: -# -# Require GTK 2.6 or later -# find_package(GTK2 2.6 REQUIRED gtk) -# -# Require GTK 2.10 or later and Glade -# find_package(GTK2 2.10 REQUIRED gtk glade) -# -# Search for GTK/GTKMM 2.8 or later -# find_package(GTK2 2.8 COMPONENTS gtk gtkmm) -# -# if(GTK2_FOUND) -# include_directories(${GTK2_INCLUDE_DIRS}) -# add_executable(mygui mygui.cc) -# target_link_libraries(mygui ${GTK2_LIBRARIES}) -# endif() -# - -#============================================================================= -# Copyright 2009 Kitware, Inc. -# Copyright 2008-2009 Philip Lowman <philip@yhbt.com> -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -# Version 1.3 (11/9/2010) (CMake 2.8.4) -# * 11429: Add support for detecting GTK2 built with Visual Studio 10. -# Thanks to Vincent Levesque for the patch. - -# Version 1.2 (8/30/2010) (CMake 2.8.3) -# * Merge patch for detecting gdk-pixbuf library (split off -# from core GTK in 2.21). Thanks to Vincent Untz for the patch -# and Ricardo Cruz for the heads up. -# Version 1.1 (8/19/2010) (CMake 2.8.3) -# * Add support for detecting GTK2 under macports (thanks to Gary Kramlich) -# Version 1.0 (8/12/2010) (CMake 2.8.3) -# * Add support for detecting new pangommconfig.h header file -# (Thanks to Sune Vuorela & the Debian Project for the patch) -# * Add support for detecting fontconfig.h header -# * Call find_package(Freetype) since it's required -# * Add support for allowing users to add additional library directories -# via the GTK2_ADDITIONAL_SUFFIXES variable (kind of a future-kludge in -# case the GTK developers change versions on any of the directories in the -# future). -# Version 0.8 (1/4/2010) -# * Get module working under MacOSX fink by adding /sw/include, /sw/lib -# to PATHS and the gobject library -# Version 0.7 (3/22/09) -# * Checked into CMake CVS -# * Added versioning support -# * Module now defaults to searching for GTK if COMPONENTS not specified. -# * Added HKCU prior to HKLM registry key and GTKMM specific environment -# variable as per mailing list discussion. -# * Added lib64 to include search path and a few other search paths where GTK -# may be installed on Unix systems. -# * Switched to lowercase CMake commands -# * Prefaced internal variables with _GTK2 to prevent collision -# * Changed internal macros to functions -# * Enhanced documentation -# Version 0.6 (1/8/08) -# Added GTK2_SKIP_MARK_AS_ADVANCED option -# Version 0.5 (12/19/08) -# Second release to cmake mailing list - -#============================================================= -# _GTK2_GET_VERSION -# Internal function to parse the version number in gtkversion.h -# _OUT_major = Major version number -# _OUT_minor = Minor version number -# _OUT_micro = Micro version number -# _gtkversion_hdr = Header file to parse -#============================================================= -function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr) - file(READ ${_gtkversion_hdr} _contents) - if(_contents) - string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}") - string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}") - string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}") - - if(NOT ${_OUT_major} MATCHES "[0-9]+") - message(FATAL_ERROR "Version parsing failed for GTK2_MAJOR_VERSION!") - endif() - if(NOT ${_OUT_minor} MATCHES "[0-9]+") - message(FATAL_ERROR "Version parsing failed for GTK2_MINOR_VERSION!") - endif() - if(NOT ${_OUT_micro} MATCHES "[0-9]+") - message(FATAL_ERROR "Version parsing failed for GTK2_MICRO_VERSION!") - endif() - - set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE) - set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE) - set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE) - else() - message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist") - endif() -endfunction() - -#============================================================= -# _GTK2_FIND_INCLUDE_DIR -# Internal function to find the GTK include directories -# _var = variable to set -# _hdr = header file to look for -#============================================================= -function(_GTK2_FIND_INCLUDE_DIR _var _hdr) - - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )") - endif() - - set(_relatives - # If these ever change, things will break. - ${GTK2_ADDITIONAL_SUFFIXES} - glibmm-2.4 - glib-2.0 - atk-1.0 - atkmm-1.6 - cairo - cairomm-1.0 - gdk-pixbuf-2.0 - gdkmm-2.4 - giomm-2.4 - gtk-2.0 - gtkmm-2.4 - libglade-2.0 - libglademm-2.4 - pango-1.0 - pangomm-1.4 - sigc++-2.0 - ) - - set(_suffixes) - foreach(_d ${_relatives}) - list(APPEND _suffixes ${_d}) - list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include - endforeach() - - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "include suffixes = ${_suffixes}") - endif() - - find_path(${_var} ${_hdr} - PATHS - /usr/local/lib64 - /usr/local/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib - /opt/gnome/include - /opt/gnome/lib - /opt/openwin/include - /usr/openwin/lib - /sw/include - /sw/lib - /opt/local/include - /opt/local/lib - $ENV{GTKMM_BASEPATH}/include - $ENV{GTKMM_BASEPATH}/lib - [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include - [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib - [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include - [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib - PATH_SUFFIXES - ${_suffixes} - ) - - if(${_var}) - set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE) - if(NOT GTK2_SKIP_MARK_AS_ADVANCED) - mark_as_advanced(${_var}) - endif() - endif() - -endfunction(_GTK2_FIND_INCLUDE_DIR) - -#============================================================= -# _GTK2_FIND_LIBRARY -# Internal function to find libraries packaged with GTK2 -# _var = library variable to create -#============================================================= -function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version) - - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )") - endif() - - # Not GTK versions per se but the versions encoded into Windows - # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example) - # Also the MSVC libraries use _ for . (this is handled below) - set(_versions 2.20 2.18 2.16 2.14 2.12 - 2.10 2.8 2.6 2.4 2.2 2.0 - 1.20 1.18 1.16 1.14 1.12 - 1.10 1.8 1.6 1.4 1.2 1.0) - - set(_library) - set(_library_d) - - set(_library ${_lib}) - - if(_expand_vc AND MSVC) - # Add vc80/vc90/vc100 midfixes - if(MSVC80) - set(_library ${_library}-vc80) - elseif(MSVC90) - set(_library ${_library}-vc90) - elseif(MSVC10) - set(_library ${_library}-vc100) - endif() - set(_library_d ${_library}-d) - endif() - - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "After midfix addition = ${_library} and ${_library_d}") - endif() - - set(_lib_list) - set(_libd_list) - if(_append_version) - foreach(_ver ${_versions}) - list(APPEND _lib_list "${_library}-${_ver}") - list(APPEND _libd_list "${_library_d}-${_ver}") - endforeach() - else() - set(_lib_list ${_library}) - set(_libd_list ${_library_d}) - endif() - - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "library list = ${_lib_list} and library debug list = ${_libd_list}") - endif() - - # For some silly reason the MSVC libraries use _ instead of . - # in the version fields - if(_expand_vc AND MSVC) - set(_no_dots_lib_list) - set(_no_dots_libd_list) - foreach(_l ${_lib_list}) - string(REPLACE "." "_" _no_dots_library ${_l}) - list(APPEND _no_dots_lib_list ${_no_dots_library}) - endforeach() - # And for debug - set(_no_dots_libsd_list) - foreach(_l ${_libd_list}) - string(REPLACE "." "_" _no_dots_libraryd ${_l}) - list(APPEND _no_dots_libd_list ${_no_dots_libraryd}) - endforeach() - - # Copy list back to original names - set(_lib_list ${_no_dots_lib_list}) - set(_libd_list ${_no_dots_libd_list}) - endif() - - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "While searching for ${_var}, our proposed library list is ${_lib_list}") - endif() - - find_library(${_var} - NAMES ${_lib_list} - PATHS - /opt/gnome/lib - /opt/gnome/lib64 - /usr/openwin/lib - /usr/openwin/lib64 - /sw/lib - $ENV{GTKMM_BASEPATH}/lib - [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib - [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib - ) - - if(_expand_vc AND MSVC) - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}") - endif() - - find_library(${_var}_DEBUG - NAMES ${_libd_list} - PATHS - $ENV{GTKMM_BASEPATH}/lib - [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib - [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib - ) - - if(${_var} AND ${_var}_DEBUG) - if(NOT GTK2_SKIP_MARK_AS_ADVANCED) - mark_as_advanced(${_var}_DEBUG) - endif() - set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG}) - set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE) - endif() - else() - if(NOT GTK2_SKIP_MARK_AS_ADVANCED) - mark_as_advanced(${_var}) - endif() - set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}}) - set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE) - # Set debug to release - set(${_var}_DEBUG ${${_var}}) - set(${_var}_DEBUG ${${_var}} PARENT_SCOPE) - endif() -endfunction(_GTK2_FIND_LIBRARY) - -#============================================================= - -# -# main() -# - -set(GTK2_FOUND) -set(GTK2_INCLUDE_DIRS) -set(GTK2_LIBRARIES) - -if(NOT GTK2_FIND_COMPONENTS) - # Assume they only want GTK - set(GTK2_FIND_COMPONENTS gtk) -endif() - -# -# If specified, enforce version number -# -if(GTK2_FIND_VERSION) - cmake_minimum_required(VERSION 2.6.2) - set(GTK2_FAILED_VERSION_CHECK true) - if(GTK2_DEBUG) - message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] " - "Searching for version ${GTK2_FIND_VERSION}") - endif() - _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h) - if(GTK2_GTK_INCLUDE_DIR) - _GTK2_GET_VERSION(GTK2_MAJOR_VERSION - GTK2_MINOR_VERSION - GTK2_PATCH_VERSION - ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h) - set(GTK2_VERSION - ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION}) - if(GTK2_FIND_VERSION_EXACT) - if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION) - set(GTK2_FAILED_VERSION_CHECK false) - endif() - else() - if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION OR - GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION) - set(GTK2_FAILED_VERSION_CHECK false) - endif() - endif() - else() - # If we can't find the GTK include dir, we can't do version checking - if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY) - message(FATAL_ERROR "Could not find GTK2 include directory") - endif() - return() - endif() - - if(GTK2_FAILED_VERSION_CHECK) - if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY) - if(GTK2_FIND_VERSION_EXACT) - message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.") - else() - message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required") - endif() - endif() - - # If the version check fails, exit out of the module here - return() - endif() -endif() - -# -# Find all components -# - -find_package(Freetype) -list(APPEND GTK2_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS}) -list(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES}) - -foreach(_GTK2_component ${GTK2_FIND_COMPONENTS}) - if(_GTK2_component STREQUAL "gtk") - _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h) - _GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h) - _GTK2_FIND_LIBRARY (GTK2_GOBJECT_LIBRARY gobject false true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h) - _GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h) - - if(UNIX) - _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true) - _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true) - else() - _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true) - _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true) - endif() - - _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h) - _GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false) - - _GTK2_FIND_INCLUDE_DIR(GTK2_FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h) - - _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h) - _GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h) - _GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true) - - - elseif(_GTK2_component STREQUAL "gtkmm") - - _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h) - _GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h) - _GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h) - _GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG_INCLUDE_DIR cairommconfig.h) - _GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h) - _GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h) - _GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h) - _GTK2_FIND_LIBRARY (GTK2_GIOMM_LIBRARY giomm true true) - - _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h) - _GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true) - - elseif(_GTK2_component STREQUAL "glade") - - _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h) - _GTK2_FIND_LIBRARY (GTK2_GLADE_LIBRARY glade false true) - - elseif(_GTK2_component STREQUAL "glademm") - - _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h) - _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h) - _GTK2_FIND_LIBRARY (GTK2_GLADEMM_LIBRARY glademm true true) - - else() - message(FATAL_ERROR "Unknown GTK2 component ${_component}") - endif() -endforeach() - -# -# Solve for the GTK2 version if we haven't already -# -if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR) - _GTK2_GET_VERSION(GTK2_MAJOR_VERSION - GTK2_MINOR_VERSION - GTK2_PATCH_VERSION - ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h) - set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION}) -endif() - -# -# Try to enforce components -# - -set(_GTK2_did_we_find_everything true) # This gets set to GTK2_FOUND - -include(FindPackageHandleStandardArgs) - -foreach(_GTK2_component ${GTK2_FIND_COMPONENTS}) - string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER) - - if(_GTK2_component STREQUAL "gtk") - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found." - GTK2_GTK_LIBRARY - GTK2_GTK_INCLUDE_DIR - - GTK2_GLIB_INCLUDE_DIR - GTK2_GLIBCONFIG_INCLUDE_DIR - GTK2_GLIB_LIBRARY - - GTK2_GDK_INCLUDE_DIR - GTK2_GDKCONFIG_INCLUDE_DIR - GTK2_GDK_LIBRARY - ) - elseif(_GTK2_component STREQUAL "gtkmm") - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found." - GTK2_GTKMM_LIBRARY - GTK2_GTKMM_INCLUDE_DIR - GTK2_GTKMMCONFIG_INCLUDE_DIR - - GTK2_GLIBMM_INCLUDE_DIR - GTK2_GLIBMMCONFIG_INCLUDE_DIR - GTK2_GLIBMM_LIBRARY - - GTK2_GDKMM_INCLUDE_DIR - GTK2_GDKMMCONFIG_INCLUDE_DIR - GTK2_GDKMM_LIBRARY - ) - elseif(_GTK2_component STREQUAL "glade") - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found." - GTK2_GLADE_LIBRARY - GTK2_GLADE_INCLUDE_DIR - ) - elseif(_GTK2_component STREQUAL "glademm") - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glademm library was not found." - GTK2_GLADEMM_LIBRARY - GTK2_GLADEMM_INCLUDE_DIR - GTK2_GLADEMMCONFIG_INCLUDE_DIR - ) - endif() - - if(NOT GTK2_${_COMPONENT_UPPER}_FOUND) - set(_GTK2_did_we_find_everything false) - endif() -endforeach() - -if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED) - set(GTK2_FOUND true) -else() - # Unset our variables. - set(GTK2_FOUND false) - set(GTK2_VERSION) - set(GTK2_VERSION_MAJOR) - set(GTK2_VERSION_MINOR) - set(GTK2_VERSION_PATCH) - set(GTK2_INCLUDE_DIRS) - set(GTK2_LIBRARIES) -endif() - -if(GTK2_INCLUDE_DIRS) - list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS) -endif() - diff --git a/CMakeScripts/inkscape-version.cmake b/CMakeScripts/inkscape-version.cmake index adfb3ddd8..2155e0013 100644 --- a/CMakeScripts/inkscape-version.cmake +++ b/CMakeScripts/inkscape-version.cmake @@ -17,4 +17,4 @@ if(EXISTS ${INKSCAPE_SOURCE_DIR}/.bzr/) endif() message("revision is " ${INKSCAPE_REVISION}) -configure_file(${INKSCAPE_BINARY_DIR}/src/inkscape-version.cpp.in ${INKSCAPE_BINARY_DIR}/src/inkscape-version.cpp) +configure_file(${INKSCAPE_SOURCE_DIR}/src/inkscape-version.cpp.in ${INKSCAPE_BINARY_DIR}/src/inkscape-version.cpp) diff --git a/configure.ac b/configure.ac index 2385ee850..395dd2605 100644 --- a/configure.ac +++ b/configure.ac @@ -852,6 +852,7 @@ else CPPFLAGS="-DGDK_DISABLE_DEPRECATED $CPPFLAGS" fi fi +AM_CONDITIONAL(WITH_GTKMM_3_0, test "x$with_gtkmm_3_0" = "xyes") INKSCAPE_CFLAGS="$GTK_CFLAGS $INKSCAPE_CFLAGS" INKSCAPE_CXX_DEPS_CFLAGS="$GTKMM_CFLAGS $INKSCAPE_CXX_DEPS_CFLAGS" diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt index 9261765c6..9e6b56f64 100644 --- a/po/CMakeLists.txt +++ b/po/CMakeLists.txt @@ -9,8 +9,19 @@ endforeach(language) #translates inkscape.desktop add_custom_target(inkscape_desktop DEPENDS ${CMAKE_BINARY_DIR}/inkscape.desktop) -add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/inkscape.desktop -DEPENDS ${LANGUAGES} -COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --desktop --template ${CMAKE_SOURCE_DIR}/inkscape.desktop.template -d ${CMAKE_CURRENT_SOURCE_DIR} -o ${CMAKE_BINARY_DIR}/inkscape.desktop.template.in --keyword=Name --keyword=GenericName --keyword=X-GNOME-FullName --keyword=Comment --keyword=Keywords -COMMAND ${CMAKE_COMMAND} -DINKSCAPE_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DINKSCAPE_BINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_SOURCE_DIR}/CMakeScripts/inkscape-desktop.cmake) + +if(${GETTEXT_VERSION_STRING} VERSION_GREATER "0.19") + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/inkscape.desktop + DEPENDS ${LANGUAGES} + COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --desktop --template ${CMAKE_SOURCE_DIR}/inkscape.desktop.template -d ${CMAKE_CURRENT_SOURCE_DIR} -o ${CMAKE_BINARY_DIR}/inkscape.desktop.template.in --keyword=Name --keyword=GenericName --keyword=X-GNOME-FullName --keyword=Comment --keyword=Keywords + COMMAND ${CMAKE_COMMAND} -DINKSCAPE_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DINKSCAPE_BINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_SOURCE_DIR}/CMakeScripts/inkscape-desktop.cmake + ) +else() + message("Old gettext version, not translating inkscape.desktop") + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/inkscape.desktop + COMMAND cp ${CMAKE_SOURCE_DIR}/inkscape.desktop.template ${CMAKE_BINARY_DIR}/inkscape.desktop.template.in + COMMAND ${CMAKE_COMMAND} -DINKSCAPE_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DINKSCAPE_BINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_SOURCE_DIR}/CMakeScripts/inkscape-desktop.cmake + ) +endif() + add_dependencies(inkscape inkscape_desktop) diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index df84e379c..644da8d5a 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -8,9 +8,11 @@ * fred * bbyak * Jon A. Cruz <jon@joncruz.org> + * Krzysztof KosiĆski <tweenk.pl@gmail.com> * * Copyright (C) 1998 The Free Software Foundation * Copyright (C) 2002-2006 authors + * Copyright (C) 2016 Google Inc. * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -122,7 +124,7 @@ struct SPCanvasClass { namespace { -gint const UPDATE_PRIORITY = G_PRIORITY_HIGH_IDLE; +gint const UPDATE_PRIORITY = G_PRIORITY_DEFAULT_IDLE; GdkWindow *getWindow(SPCanvas *canvas) { @@ -935,7 +937,6 @@ void sp_canvas_class_init(SPCanvasClass *klass) static void sp_canvas_init(SPCanvas *canvas) { gtk_widget_set_has_window (GTK_WIDGET (canvas), TRUE); - gtk_widget_set_double_buffered (GTK_WIDGET (canvas), FALSE); gtk_widget_set_can_focus (GTK_WIDGET (canvas), TRUE); canvas->_pick_event.type = GDK_LEAVE_NOTIFY; @@ -956,9 +957,8 @@ static void sp_canvas_init(SPCanvas *canvas) canvas->_drawing_disabled = false; - canvas->_tiles=NULL; - canvas->_tLeft=canvas->_tTop=canvas->_tRight=canvas->_tBottom=0; - canvas->_tile_h=canvas->_tile_h=0; + canvas->_backing_store = NULL; + canvas->_clean_region = cairo_region_create(); canvas->_forced_redraw_count = 0; canvas->_forced_redraw_limit = -1; @@ -967,22 +967,15 @@ static void sp_canvas_init(SPCanvas *canvas) canvas->_enable_cms_display_adj = false; new (&canvas->_cms_key) Glib::ustring(""); #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - canvas->_is_scrolling = false; } void SPCanvas::shutdownTransients() { - // We turn off the need_redraw flag, since if the canvas is mapped again - // it will request a redraw anyways. We do not turn off the need_update - // flag, though, because updates are not queued when the canvas remaps - // itself. - // - _need_redraw = FALSE; - if (_tiles) g_free(_tiles); - _tiles = NULL; - _tLeft = _tTop = _tRight = _tBottom = 0; - _tile_h = _tile_h = 0; + // Reset the clean region + if (_clean_region && !cairo_region_is_empty(_clean_region)) { + cairo_region_destroy(_clean_region); + _clean_region = cairo_region_create(); + } if (_grabbed_item) { _grabbed_item = NULL; @@ -1005,6 +998,14 @@ void SPCanvas::dispose(GObject *object) g_object_unref (canvas->_root); canvas->_root = NULL; } + if (canvas->_backing_store) { + cairo_surface_destroy(canvas->_backing_store); + canvas->_backing_store = NULL; + } + if (canvas->_clean_region) { + cairo_region_destroy(canvas->_clean_region); + canvas->_clean_region = NULL; + } canvas->shutdownTransients(); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -1138,41 +1139,41 @@ void SPCanvas::handle_size_request(GtkWidget *widget, GtkRequisition *req) void SPCanvas::handle_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { SPCanvas *canvas = SP_CANVAS (widget); - GtkAllocation widg_allocation; + GtkAllocation old_allocation; - gtk_widget_get_allocation (widget, &widg_allocation); + gtk_widget_get_allocation(widget, &old_allocation); -// Geom::IntRect old_area = Geom::IntRect::from_xywh(canvas->x0, canvas->y0, -// widg_allocation.width, widg_allocation.height); +// Geom::IntRect old_area = Geom::IntRect::from_xywh(canvas->_x0, canvas->_y0, +// old_allocation.width, old_allocation.height); Geom::IntRect new_area = Geom::IntRect::from_xywh(canvas->_x0, canvas->_y0, allocation->width, allocation->height); - // Schedule redraw of new region - canvas->resizeTiles(canvas->_x0, canvas->_y0, canvas->_x0 + allocation->width, canvas->_y0 + allocation->height); - if (SP_CANVAS_ITEM_GET_CLASS (canvas->_root)->viewbox_changed) - SP_CANVAS_ITEM_GET_CLASS (canvas->_root)->viewbox_changed (canvas->_root, new_area); - - if (allocation->width > widg_allocation.width) { - canvas->requestRedraw(canvas->_x0 + widg_allocation.width, - 0, - canvas->_x0 + allocation->width, - canvas->_y0 + allocation->height); - } - if (allocation->height > widg_allocation.height) { - canvas->requestRedraw(0, - canvas->_y0 + widg_allocation.height, - canvas->_x0 + allocation->width, - canvas->_y0 + allocation->height); + // resize backing store; the clean region does not change + cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + allocation->width, allocation->height); + if (canvas->_backing_store) { + cairo_t *cr = cairo_create(new_backing_store); + cairo_set_source_surface(cr, canvas->_backing_store, 0, 0); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_paint(cr); + cairo_destroy(cr); + cairo_surface_destroy(canvas->_backing_store); } + canvas->_backing_store = new_backing_store; gtk_widget_set_allocation (widget, allocation); + // Schedule redraw of new region + if (SP_CANVAS_ITEM_GET_CLASS (canvas->_root)->viewbox_changed) + SP_CANVAS_ITEM_GET_CLASS (canvas->_root)->viewbox_changed (canvas->_root, new_area); + if (gtk_widget_get_realized (widget)) { gdk_window_move_resize (gtk_widget_get_window (widget), allocation->x, allocation->y, allocation->width, allocation->height); } + canvas->addIdle(); } int SPCanvas::emitEvent(GdkEvent *event) @@ -1554,11 +1555,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context(widget); - GdkRGBA color; - gtk_style_context_get_background_color(context, - gtk_widget_get_state_flags(widget), - &color); - gdk_cairo_set_source_rgba(buf.ct, &color); + gtk_render_background(context, buf.ct, 0, 0, paint_rect.width(), paint_rect.height()); #else GtkStyle *style = gtk_widget_get_style (widget); gdk_cairo_set_source_color(buf.ct, &style->bg[GTK_STATE_NORMAL]); @@ -1600,7 +1597,8 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - cairo_t *xct = gdk_cairo_create(gtk_widget_get_window (widget)); + //cairo_t *xct = gdk_cairo_create(gtk_widget_get_window (widget)); + cairo_t *xct = cairo_create(_backing_store); cairo_translate(xct, paint_rect.left() - _x0, paint_rect.top() - _y0); cairo_rectangle(xct, 0, 0, paint_rect.width(), paint_rect.height()); cairo_clip(xct); @@ -1609,6 +1607,12 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect cairo_paint(xct); cairo_destroy(xct); cairo_surface_destroy(imgs); + + cairo_rectangle_int_t crect = { paint_rect.left(), paint_rect.right(), paint_rect.width(), paint_rect.height() }; + cairo_region_union_rectangle(_clean_region, &crect); + + gtk_widget_queue_draw_area(GTK_WIDGET(this), paint_rect.left() -_x0, paint_rect.top() - _y0, + paint_rect.width(), paint_rect.height()); } struct PaintRectSetup { @@ -1792,52 +1796,63 @@ void SPCanvas::endForcedFullRedraws() _forced_redraw_limit = -1; } -#if GTK_CHECK_VERSION(3,0,0) gboolean SPCanvas::handle_draw(GtkWidget *widget, cairo_t *cr) { SPCanvas *canvas = SP_CANVAS(widget); cairo_rectangle_list_t *rects = cairo_copy_clip_rectangle_list(cr); + cairo_region_t *draw_region = cairo_region_create(); for (int i = 0; i < rects->num_rectangles; i++) { cairo_rectangle_t rectangle = rects->rectangles[i]; + Geom::Rect dr = Geom::Rect::from_xywh(rectangle.x + canvas->_x0, rectangle.y + canvas->_y0, + rectangle.width, rectangle.height); + Geom::IntRect ir = dr.roundOutwards(); + cairo_rectangle_int_t irect = { ir.left(), ir.top(), ir.width(), ir.height() }; + cairo_region_union_rectangle(draw_region, &irect); + } + cairo_rectangle_list_destroy(rects); - Geom::IntRect r = Geom::IntRect::from_xywh(rectangle.x + canvas->_x0, rectangle.y + canvas->_y0, - rectangle.width, rectangle.height); - - canvas->requestRedraw(r.left(), r.top(), r.right(), r.bottom()); + cairo_region_t *draw_dirty = cairo_region_copy(draw_region); + cairo_region_subtract(draw_dirty, canvas->_clean_region); + cairo_region_intersect(draw_region, canvas->_clean_region); + + // Draw the clean portion + if (!cairo_region_is_empty(draw_region)) { + cairo_region_translate(draw_region, -canvas->_x0, -canvas->_y0); + cairo_save(cr); + int n_rects = cairo_region_num_rectangles(draw_region); + for (int i = 0; i < n_rects; ++i) { + cairo_rectangle_int_t crect; + cairo_region_get_rectangle(draw_region, i, &crect); + cairo_rectangle(cr, crect.x, crect.y, crect.width, crect.height); + } + cairo_clip(cr); + cairo_set_source_surface(cr, canvas->_backing_store, 0, 0); + cairo_paint(cr); + cairo_restore(cr); } - cairo_rectangle_list_destroy(rects); + // Render the dirty portion in the background + if (!cairo_region_is_empty(draw_dirty)) { + canvas->addIdle(); + } + cairo_region_destroy(draw_region); + cairo_region_destroy(draw_dirty); - return FALSE; + return TRUE; } -#else +#if !GTK_CHECK_VERSION(3,0,0) gboolean SPCanvas::handle_expose(GtkWidget *widget, GdkEventExpose *event) { - SPCanvas *canvas = SP_CANVAS(widget); + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - if (!gtk_widget_is_drawable (widget) || - (event->window != getWindow(canvas))) { - return FALSE; - } - - int n_rects = 0; - GdkRectangle *rects = NULL; - gdk_region_get_rectangles(event->region, &rects, &n_rects); + gdk_cairo_region (cr, event->region); + cairo_clip (cr); + gboolean result = SPCanvas::handle_draw(widget, cr); - if(rects == NULL) - return FALSE; - - for (int i = 0; i < n_rects; i++) { - GdkRectangle rectangle = rects[i]; + cairo_destroy (cr); - Geom::IntRect r = Geom::IntRect::from_xywh(rectangle.x + canvas->_x0, rectangle.y + canvas->_y0, - rectangle.width, rectangle.height); - - canvas->requestRedraw(r.left(), r.top(), r.right(), r.bottom()); - } - - return FALSE; + return result; } #endif @@ -1890,42 +1905,22 @@ int SPCanvas::paint() _need_update = FALSE; } - if (!_need_redraw) { - return TRUE; - } - - Cairo::RefPtr<Cairo::Region> to_paint = Cairo::Region::create(); - - for (int j = _tTop; j < _tBottom; ++j) { - for (int i = _tLeft; i < _tRight; ++i) { - int tile_index = (i - _tLeft) + (j - _tTop) * _tile_h; - - if (_tiles[tile_index]) { // if this tile is dirtied (nonzero) - Cairo::RectangleInt rect = {i*TILE_SIZE, j*TILE_SIZE, - TILE_SIZE, TILE_SIZE}; - to_paint->do_union(rect); - } - } - } - - int n_rect = to_paint->get_num_rectangles(); + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(this), &allocation); + cairo_rectangle_int_t crect = { _x0, _y0, allocation.width, allocation.height }; + cairo_region_t *to_draw = cairo_region_create_rectangle(&crect); + cairo_region_subtract(to_draw, _clean_region); - if (n_rect > 0) { - for (int i=0; i < n_rect; i++) { - Cairo::RectangleInt rect = to_paint->get_rectangle(i); - int x0 = rect.x; - int y0 = rect.y; - int x1 = x0 + rect.width; - int y1 = y0 + rect.height; - if (!paintRect(x0, y0, x1, y1)) { - // Aborted - return FALSE; - }; - } + int n_rects = cairo_region_num_rectangles(to_draw); + for (int i = 0; i < n_rects; ++i) { + cairo_rectangle_int_t crect; + cairo_region_get_rectangle(to_draw, i, &crect); + if (!paintRect(crect.x, crect.y, crect.x + crect.width, crect.y + crect.height)) { + // Aborted + return FALSE; + }; } - _need_redraw = FALSE; - // we've had a full unaborted redraw, reset the full redraw counter if (_forced_redraw_limit != -1) { _forced_redraw_count = 0; @@ -2012,7 +2007,27 @@ void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scroll gtk_widget_get_allocation(&_widget, &allocation); - resizeTiles(_x0, _y0, _x0 + allocation.width, _y0 + allocation.height); + assert(_backing_store); + cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + allocation.width, allocation.height); + cairo_t *cr = cairo_create(new_backing_store); + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_paint(cr); + cairo_set_source_surface(cr, _backing_store, -dx, -dy); + cairo_paint(cr); + cairo_destroy(cr); + cairo_surface_destroy(_backing_store); + _backing_store = new_backing_store; + + if (clear) { + cairo_region_destroy(_clean_region); + _clean_region = cairo_region_create(); + } else { + cairo_rectangle_int_t crect = { _x0, _y0, allocation.width, allocation.height }; + cairo_region_intersect_rectangle(_clean_region, &crect); + } + if (SP_CANVAS_ITEM_GET_CLASS(_root)->viewbox_changed) { SP_CANVAS_ITEM_GET_CLASS(_root)->viewbox_changed(_root, new_area); } @@ -2020,19 +2035,17 @@ void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scroll if (!clear) { // scrolling without zoom; redraw only the newly exposed areas if ((dx != 0) || (dy != 0)) { - this->_is_scrolling = is_scrolling; if (gtk_widget_get_realized(GTK_WIDGET(this))) { gdk_window_scroll(getWindow(this), -dx, -dy); } } - } else { - // scrolling as part of zoom; do nothing here - the next do_update will perform full redraw } + addIdle(); } void SPCanvas::updateNow() { - if (_need_update || _need_redraw) { + if (_need_update) { doUpdate(); } } @@ -2045,26 +2058,16 @@ void SPCanvas::requestUpdate() void SPCanvas::requestRedraw(int x0, int y0, int x1, int y1) { - GtkAllocation allocation; - if (!gtk_widget_is_drawable( GTK_WIDGET(this) )) { return; } - if ((x0 >= x1) || (y0 >= y1)) { + if (x0 >= x1 || y0 >= y1) { return; } Geom::IntRect bbox(x0, y0, x1, y1); - gtk_widget_get_allocation(GTK_WIDGET(this), &allocation); - - Geom::IntRect canvas_rect = Geom::IntRect::from_xywh(this->_x0, this->_y0, - allocation.width, allocation.height); - - Geom::OptIntRect clip = bbox & canvas_rect; - if (clip) { - dirtyRect(*clip); - addIdle(); - } + dirtyRect(bbox); + addIdle(); } /** @@ -2168,63 +2171,17 @@ inline int sp_canvas_tile_ceil(int x) return ((x + (TILE_SIZE - 1)) & (~(TILE_SIZE - 1))) / TILE_SIZE; } -void SPCanvas::resizeTiles(int nl, int nt, int nr, int nb) -{ - if ( nl >= nr || nt >= nb ) { - if (_tiles) g_free(_tiles); - _tLeft = _tTop = _tRight = _tBottom = 0; - _tile_h = _tile_h = 0; - _tiles = NULL; - return; - } - int tl = sp_canvas_tile_floor(nl); - int tt = sp_canvas_tile_floor(nt); - int tr = sp_canvas_tile_ceil(nr); - int tb = sp_canvas_tile_ceil(nb); - - int nh = tr-tl, nv = tb-tt; - uint8_t *ntiles = (uint8_t*) g_malloc(nh * nv * sizeof(uint8_t)); - for (int i = tl; i < tr; i++) { - for (int j = tt; j < tb; j++) { - int ind = (i-tl) + (j-tt)*nh; - if ( i >= _tLeft && i < _tRight && j >= _tTop && j < _tBottom ) { - ntiles[ind] = _tiles[(i - _tLeft) + (j - _tTop) * _tile_h]; // copy from the old tile - } else { - ntiles[ind] = 0; // newly exposed areas get 0 - } - } - } - if (_tiles) g_free(_tiles); - _tiles = ntiles; - _tLeft = tl; - _tTop = tt; - _tRight = tr; - _tBottom = tb; - _tile_h = nh; - _tile_h = nv; -} - void SPCanvas::dirtyRect(Geom::IntRect const &area) { - _need_redraw = TRUE; markRect(area, 1); } void SPCanvas::markRect(Geom::IntRect const &area, uint8_t val) { - int tl = sp_canvas_tile_floor(area.left()); - int tt = sp_canvas_tile_floor(area.top()); - int tr = sp_canvas_tile_ceil(area.right()); - int tb = sp_canvas_tile_ceil(area.bottom()); - if ( tl >= _tRight || tr <= _tLeft || tt >= _tBottom || tb <= _tTop ) return; - if ( tl < _tLeft ) tl = _tLeft; - if ( tr > _tRight ) tr = _tRight; - if ( tt < _tTop ) tt = _tTop; - if ( tb > _tBottom ) tb = _tBottom; - - for (int i=tl; i<tr; i++) { - for (int j=tt; j<tb; j++) { - _tiles[(i - _tLeft) + (j - _tTop) * _tile_h] = val; - } + cairo_rectangle_int_t crect = { area.left(), area.top(), area.width(), area.height() }; + if (val) { + cairo_region_subtract_rectangle(_clean_region, &crect); + } else { + cairo_region_union_rectangle(_clean_region, &crect); } } diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 1a13250b3..a1f8d0a1a 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -11,9 +11,11 @@ * Raph Levien <raph@gimp.org> * Lauris Kaplinski <lauris@kaplinski.com> * Jon A. Cruz <jon@joncruz.org> + * Krzysztof KosiĆski <tweenk.pl@gmail.com> * * Copyright (C) 1998 The Free Software Foundation * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2016 Google Inc. * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -155,9 +157,8 @@ public: */ static gint handle_scroll(GtkWidget *widget, GdkEventScroll *event); static gint handle_motion(GtkWidget *widget, GdkEventMotion *event); -#if GTK_CHECK_VERSION(3,0,0) static gboolean handle_draw(GtkWidget *widget, cairo_t *cr); -#else +#if !GTK_CHECK_VERSION(3,0,0) static gboolean handle_expose(GtkWidget *widget, GdkEventExpose *event); #endif static gint handle_key_event(GtkWidget *widget, GdkEventKey *event); @@ -180,9 +181,8 @@ public: int _y0; /* Area that needs redrawing, stored as a microtile array */ - int _tLeft, _tTop, _tRight, _tBottom; - int _tile_w, _tile_h; - uint8_t *_tiles; + cairo_surface_t *_backing_store; + cairo_region_t *_clean_region; /** Last known modifier state, for deferred repick when a button is down. */ int _state; @@ -208,7 +208,6 @@ public: int _close_enough; unsigned int _need_update : 1; - unsigned int _need_redraw : 1; unsigned int _need_repick : 1; int _forced_redraw_count; diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index fbd050f8e..9656878e0 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1061,7 +1061,11 @@ CloneTiler::CloneTiler () : { GtkWidget *l = gtk_label_new (""); gtk_label_set_markup (GTK_LABEL(l), "×"); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(l, GTK_ALIGN_END); +#else gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); +#endif gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); } @@ -1135,7 +1139,11 @@ CloneTiler::CloneTiler () : { GtkWidget *l = gtk_label_new (""); gtk_label_set_markup (GTK_LABEL(l), "×"); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(l, GTK_ALIGN_END); +#else gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); +#endif gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); } @@ -2777,7 +2785,12 @@ GtkWidget * CloneTiler::clonetiler_spinbox(const char *tip, const char *attr, do { GtkWidget *l = gtk_label_new (""); gtk_label_set_markup (GTK_LABEL(l), suffix); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(l, GTK_ALIGN_END); + gtk_widget_set_valign(l, GTK_ALIGN_START); +#else gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0); +#endif gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); } @@ -2853,14 +2866,13 @@ void CloneTiler::clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg) void CloneTiler::clonetiler_table_attach(GtkWidget *table, GtkWidget *widget, float align, int row, int col) { - GtkWidget *a = gtk_alignment_new (align, 0, 0, 0); - gtk_container_add(GTK_CONTAINER(a), widget); - #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_halign(table, GTK_ALIGN_FILL); - gtk_widget_set_valign(table, GTK_ALIGN_CENTER); - gtk_grid_attach(GTK_GRID(table), a, col, row, 1, 1); + gtk_widget_set_halign(widget, GTK_ALIGN_FILL); + gtk_widget_set_valign(widget, GTK_ALIGN_START); + gtk_grid_attach(GTK_GRID(table), widget, col, row, 1, 1); #else + GtkWidget *a = gtk_alignment_new (align, 0, 0, 0); + gtk_container_add(GTK_CONTAINER(a), widget); gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, GTK_FILL, (GtkAttachOptions)0, 0, 0 ); #endif } diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 8639861f8..a16bbc472 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -79,6 +79,10 @@ #include "message-stack.h" #include "ui/dialog/layer-properties.h" +#if GTK_CHECK_VERSION(3,0,0) + #include "widgets/image-menu-item.h" +#endif + #include <gdk/gdkkeysyms.h> #include <glibmm/miscutils.h> @@ -413,7 +417,11 @@ sp_ui_menuitem_add_icon( GtkWidget *item, gchar *icon_name ) icon = sp_icon_new( Inkscape::ICON_SIZE_MENU, icon_name ); gtk_widget_show(icon); +#if GTK_CHECK_VERSION(3,0,0) + image_menu_item_set_image((ImageMenuItem *) item, icon); +#else gtk_image_menu_item_set_image((GtkImageMenuItem *) item, icon); +#endif } // end of sp_ui_menu_add_icon void @@ -467,7 +475,11 @@ static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb if (radio) { item = gtk_radio_menu_item_new_with_mnemonic(group, action->name); } else { +#if GTK_CHECK_VERSION(3,0,0) + item = image_menu_item_new_with_mnemonic(action->name); +#else item = gtk_image_menu_item_new_with_mnemonic(action->name); +#endif } gtk_label_set_markup_with_mnemonic( GTK_LABEL(gtk_bin_get_child(GTK_BIN (item))), action->name); diff --git a/src/ui/widget/color-icc-selector.cpp b/src/ui/widget/color-icc-selector.cpp index 2fe4a0704..ec2e69fb3 100644 --- a/src/ui/widget/color-icc-selector.cpp +++ b/src/ui/widget/color-icc-selector.cpp @@ -377,7 +377,6 @@ void ColorICCSelector::init() (gpointer)_impl); gtk_widget_set_sensitive(_impl->_fixupBtn, FALSE); gtk_widget_set_tooltip_text(_impl->_fixupBtn, _("Fix RGB fallback to match icc-color() value.")); - // gtk_misc_set_alignment( GTK_MISC (_impl->_fixupBtn), 1.0, 0.5 ); gtk_widget_show(_impl->_fixupBtn); attachToGridOrTable(t, _impl->_fixupBtn, 0, row, 1, 1); @@ -431,7 +430,13 @@ void ColorICCSelector::init() #endif _impl->_compUI[i]._label = gtk_label_new_with_mnemonic(labelStr.c_str()); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(_impl->_compUI[i]._label, GTK_ALIGN_END); +#else gtk_misc_set_alignment(GTK_MISC(_impl->_compUI[i]._label), 1.0, 0.5); +#endif + gtk_widget_show(_impl->_compUI[i]._label); gtk_widget_set_no_show_all(_impl->_compUI[i]._label, TRUE); @@ -489,7 +494,13 @@ void ColorICCSelector::init() // Label _impl->_label = gtk_label_new_with_mnemonic(_("_A:")); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(_impl->_label, GTK_ALIGN_END); +#else gtk_misc_set_alignment(GTK_MISC(_impl->_label), 1.0, 0.5); +#endif + gtk_widget_show(_impl->_label); attachToGridOrTable(t, _impl->_label, 0, row, 1, 1); diff --git a/src/ui/widget/color-notebook.cpp b/src/ui/widget/color-notebook.cpp index 60abf43bf..6d7ada734 100644 --- a/src/ui/widget/color-notebook.cpp +++ b/src/ui/widget/color-notebook.cpp @@ -210,7 +210,11 @@ void ColorNotebook::_initUI() /* Create RGBA entry and color preview */ _rgbal = gtk_label_new_with_mnemonic(_("RGBA_:")); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(_rgbal, GTK_ALIGN_END); +#else gtk_misc_set_alignment(GTK_MISC(_rgbal), 1.0, 0.5); +#endif gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2); ColorEntry *rgba_entry = Gtk::manage(new ColorEntry(_selected_color)); diff --git a/src/ui/widget/color-scales.cpp b/src/ui/widget/color-scales.cpp index 170f83887..48a2693bc 100644 --- a/src/ui/widget/color-scales.cpp +++ b/src/ui/widget/color-scales.cpp @@ -92,7 +92,13 @@ void ColorScales::_initUI(SPColorScalesMode mode) for (i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) { /* Label */ _l[i] = gtk_label_new(""); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(_l[i], GTK_ALIGN_END); +#else gtk_misc_set_alignment(GTK_MISC(_l[i]), 1.0, 0.5); +#endif + gtk_widget_show(_l[i]); #if GTK_CHECK_VERSION(3, 0, 0) diff --git a/src/ui/widget/gimpcolorwheel.c b/src/ui/widget/gimpcolorwheel.c index 3642848df..d54486505 100644 --- a/src/ui/widget/gimpcolorwheel.c +++ b/src/ui/widget/gimpcolorwheel.c @@ -303,7 +303,9 @@ gimp_color_wheel_realize (GtkWidget *widget) priv->window = gdk_window_new (parent_window, &attr, attr_mask); gdk_window_set_user_data (priv->window, wheel); +#if !GTK_CHECK_VERSION(3,0,0) gtk_widget_style_attach (widget); +#endif } static void diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index c38bde5cf..8cb6e947f 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -110,6 +110,11 @@ set(widgets_SRC widget-sizes.h ) +if(${WITH_GTK3_EXPERIMENTAL}) + set(image_menu_item_SRC image-menu-item.h image-menu-item.c) + add_inkscape_source("${image_menu_item_SRC}") +endif() + # add_inkscape_lib(widgets_LIB "${widgets_SRC}") add_inkscape_source("${widgets_SRC}") @@ -121,3 +126,6 @@ set ( widgets_paintbucket_SRC if ("${HAVE_POTRACE}") add_inkscape_source("${widgets_paintbucket_SRC}") endif() + + + diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert index 6913f4a58..2ee0f7002 100644 --- a/src/widgets/Makefile_insert +++ b/src/widgets/Makefile_insert @@ -1,5 +1,11 @@ ## Makefile.am fragment sourced by src/Makefile.am. +if WITH_GTKMM_3_0 +ink_common_sources += \ + widgets/image-menu-item.c \ + widgets/image-menu-item.h +endif + ink_common_sources += \ widgets/arc-toolbar.cpp \ widgets/arc-toolbar.h \ diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 3fa607820..759be551f 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -572,10 +572,18 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) sp_ruler_add_track_widget (SP_RULER(dtw->vruler), GTK_WIDGET(dtw->canvas)); #if GTK_CHECK_VERSION(3,0,0) - GdkRGBA white = {1,1,1,1}; - gtk_widget_override_background_color(GTK_WIDGET(dtw->canvas), - GTK_STATE_FLAG_NORMAL, - &white); + GtkCssProvider *css_provider = gtk_css_provider_new(); + GtkStyleContext *style_context = gtk_widget_get_style_context(GTK_WIDGET(dtw->canvas)); + + gtk_css_provider_load_from_data(css_provider, + "SPCanvas {\n" + " background-color: white;\n" + "}\n", + -1, NULL); + + gtk_style_context_add_provider(style_context, + GTK_STYLE_PROVIDER(css_provider), + GTK_STYLE_PROVIDER_PRIORITY_USER); #else GtkStyle *style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(dtw->canvas))); style->bg[GTK_STATE_NORMAL] = style->white; @@ -692,38 +700,37 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_container_add (GTK_CONTAINER (eventbox), dtw->coord_status); gtk_widget_set_tooltip_text (eventbox, _("Cursor coordinates")); GtkWidget *label_x = gtk_label_new(_("X:")); - gtk_misc_set_alignment (GTK_MISC(label_x), 0.0, 0.5); - -#if GTK_CHECK_VERSION(3,0,0) - gtk_grid_attach(GTK_GRID(dtw->coord_status), - label_x, 1, 0, 1, 1); -#else - gtk_table_attach(GTK_TABLE(dtw->coord_status), label_x, 1,2, 0,1, GTK_FILL, GTK_FILL, 0, 0); -#endif - GtkWidget *label_y = gtk_label_new(_("Y:")); - gtk_misc_set_alignment (GTK_MISC(label_y), 0.0, 0.5); #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(label_x, GTK_ALIGN_START); + gtk_widget_set_halign(label_y, GTK_ALIGN_START); + gtk_grid_attach(GTK_GRID(dtw->coord_status), label_x, 1, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), label_y, 1, 1, 1, 1); #else + gtk_misc_set_alignment (GTK_MISC(label_x), 0.0, 0.5); + gtk_misc_set_alignment (GTK_MISC(label_y), 0.0, 0.5); + gtk_table_attach(GTK_TABLE(dtw->coord_status), label_x, 1,2, 0,1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach(GTK_TABLE(dtw->coord_status), label_y, 1,2, 1,2, GTK_FILL, GTK_FILL, 0, 0); #endif dtw->coord_status_x = gtk_label_new(NULL); - gtk_label_set_markup( GTK_LABEL(dtw->coord_status_x), "<tt> 0.00 </tt>" ); - gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_x), 1.0, 0.5); dtw->coord_status_y = gtk_label_new(NULL); + gtk_label_set_markup( GTK_LABEL(dtw->coord_status_x), "<tt> 0.00 </tt>" ); gtk_label_set_markup( GTK_LABEL(dtw->coord_status_y), "<tt> 0.00 </tt>" ); - gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_y), 1.0, 0.5); + GtkWidget* label_z = gtk_label_new(_("Z:")); #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(dtw->coord_status_x, GTK_ALIGN_END); + gtk_widget_set_halign(dtw->coord_status_y, GTK_ALIGN_END); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_x, 2, 0, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->coord_status_y, 2, 1, 1, 1); gtk_grid_attach(GTK_GRID(dtw->coord_status), label_z, 3, 0, 1, 2); gtk_grid_attach(GTK_GRID(dtw->coord_status), dtw->zoom_status, 4, 0, 1, 2); #else + gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_x), 1.0, 0.5); + gtk_misc_set_alignment (GTK_MISC(dtw->coord_status_y), 1.0, 0.5); gtk_table_attach(GTK_TABLE(dtw->coord_status), dtw->coord_status_x, 2,3, 0,1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach(GTK_TABLE(dtw->coord_status), dtw->coord_status_y, 2,3, 1,2, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach(GTK_TABLE(dtw->coord_status), label_z, 3,4, 0,2, GTK_FILL, GTK_FILL, 0, 0); @@ -756,7 +763,13 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) dtw->select_status_eventbox = gtk_event_box_new (); dtw->select_status = gtk_label_new (NULL); gtk_label_set_ellipsize (GTK_LABEL(dtw->select_status), PANGO_ELLIPSIZE_END); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(dtw->select_status, GTK_ALIGN_START); +#else gtk_misc_set_alignment (GTK_MISC (dtw->select_status), 0.0, 0.5); +#endif + gtk_widget_set_size_request (dtw->select_status, 1, -1); // display the initial welcome message in the statusbar gtk_label_set_markup (GTK_LABEL (dtw->select_status), _("<b>Welcome to Inkscape!</b> Use shape or freehand tools to create objects; use selector (arrow) to move or transform them.")); @@ -1685,7 +1698,8 @@ void SPDesktopWidget::setToolboxPosition(Glib::ustring const& id, GtkPositionTyp case GTK_POS_TOP: case GTK_POS_BOTTOM: if ( gtk_widget_is_ancestor(toolbox, hbox) ) { - gtk_widget_reparent( toolbox, vbox ); + gtk_container_remove(GTK_CONTAINER(hbox), toolbox); + gtk_container_add(GTK_CONTAINER(vbox), toolbox); gtk_box_set_child_packing(GTK_BOX(vbox), toolbox, FALSE, TRUE, 0, GTK_PACK_START); } ToolboxFactory::setOrientation(toolbox, GTK_ORIENTATION_HORIZONTAL); @@ -1693,7 +1707,8 @@ void SPDesktopWidget::setToolboxPosition(Glib::ustring const& id, GtkPositionTyp case GTK_POS_LEFT: case GTK_POS_RIGHT: if ( !gtk_widget_is_ancestor(toolbox, hbox) ) { - gtk_widget_reparent( toolbox, hbox ); + gtk_container_remove(GTK_CONTAINER(vbox), toolbox); + gtk_container_add(GTK_CONTAINER(hbox), toolbox); gtk_box_set_child_packing(GTK_BOX(hbox), toolbox, FALSE, TRUE, 0, GTK_PACK_START); if (pos == GTK_POS_LEFT) { gtk_box_reorder_child( GTK_BOX(hbox), toolbox, 0 ); diff --git a/src/widgets/ege-adjustment-action.cpp b/src/widgets/ege-adjustment-action.cpp index a91149f4c..272217aa4 100644 --- a/src/widgets/ege-adjustment-action.cpp +++ b/src/widgets/ege-adjustment-action.cpp @@ -865,7 +865,13 @@ static GtkWidget* create_tool_item( GtkAction* action ) gtk_box_pack_start( GTK_BOX(hb), icon, FALSE, FALSE, 0 ); } else { GtkWidget* lbl = gtk_label_new( g_value_get_string( &value ) ? g_value_get_string( &value ) : "wwww" ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(lbl, GTK_ALIGN_END); +#else gtk_misc_set_alignment( GTK_MISC(lbl), 1.0, 0.5 ); +#endif + gtk_box_pack_start( GTK_BOX(hb), lbl, FALSE, FALSE, 0 ); } } diff --git a/src/widgets/ege-select-one-action.cpp b/src/widgets/ege-select-one-action.cpp index ab86c49f8..2e106154e 100644 --- a/src/widgets/ege-select-one-action.cpp +++ b/src/widgets/ege-select-one-action.cpp @@ -818,9 +818,14 @@ GtkWidget* create_tool_item( GtkAction* action ) gtk_box_pack_start( GTK_BOX(holder), normal, FALSE, FALSE, 0 ); { +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(holder, GTK_ALIGN_START); + gtk_container_add(GTK_CONTAINER(item), holder); +#else GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0); gtk_container_add( GTK_CONTAINER(align), holder); gtk_container_add( GTK_CONTAINER(item), align ); +#endif } } @@ -855,10 +860,14 @@ void resync_active( EgeSelectOneAction* act, gint active, gboolean override ) GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) ); if ( children && children->data ) { gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" ); + +#if !GTK_CHECK_VERSION(3,0,0) if (!combodata && GTK_IS_ALIGNMENT(children->data)) { GList *other = gtk_container_get_children( GTK_CONTAINER(children->data) ); combodata = g_object_get_data( G_OBJECT(other->data), "ege-combo-box" ); } +#endif + if ( GTK_IS_COMBO_BOX(combodata) ) { GtkComboBox* combo = GTK_COMBO_BOX(combodata); if ((active == -1) && (gtk_combo_box_get_has_entry(combo))) { @@ -915,10 +924,14 @@ void resync_sensitive( EgeSelectOneAction* act ) GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) ); if ( children && children->data ) { gpointer combodata = g_object_get_data( G_OBJECT(children->data), "ege-combo-box" ); + +#if !GTK_CHECK_VERSION(3,0,0) if (!combodata && GTK_IS_ALIGNMENT(children->data)) { GList *other = gtk_container_get_children( GTK_CONTAINER(children->data) ); combodata = g_object_get_data( G_OBJECT(other->data), "ege-combo-box" ); } +#endif + if ( GTK_IS_COMBO_BOX(combodata) ) { /* Not implemented */ } else if ( GTK_IS_BOX(children->data) ) { diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 35c1e4a8d..3aa44c90a 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -914,7 +914,13 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s /* Label */ GtkWidget *l = gtk_label_new(C_("Gradient","Offset:")); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(l, GTK_ALIGN_END); +#else gtk_misc_set_alignment(GTK_MISC(l), 1.0, 0.5); +#endif + gtk_box_pack_start(GTK_BOX(hb),l, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS); gtk_widget_show(l); diff --git a/src/widgets/image-menu-item.c b/src/widgets/image-menu-item.c new file mode 100644 index 000000000..2b9500ba0 --- /dev/null +++ b/src/widgets/image-menu-item.c @@ -0,0 +1,1071 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. + * Forked by . Icons in menus are important to us. + */ + +#include "config.h" + +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> + +#include "widgets/image-menu-item.h" + +/** + * SECTION:gtkimagemenuitem + * @Short_description: A menu item with an icon + * @Title: ImageMenuItem + * + * A ImageMenuItem is a menu item which has an icon next to the text label. + * + * Note that the user can disable display of menu icons, so make sure to still + * fill in the text label. + */ + + +struct _ImageMenuItemPrivate +{ + GtkWidget *image; + + gchar *label; + guint use_stock : 1; + guint toggle_size; +}; + +enum { + PROP_0, + PROP_IMAGE, + PROP_USE_STOCK, + PROP_ACCEL_GROUP, +}; + +static GtkActivatableIface *parent_activatable_iface; + +static void image_menu_item_destroy (GtkWidget *widget); +static void image_menu_item_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural); +static void image_menu_item_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural); +static void image_menu_item_get_preferred_height_for_width (GtkWidget *widget, + gint width, + gint *minimum, + gint *natural); +static void image_menu_item_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void image_menu_item_map (GtkWidget *widget); +static void image_menu_item_remove (GtkContainer *container, + GtkWidget *child); +static void image_menu_item_toggle_size_request (GtkMenuItem *menu_item, + gint *requisition); +static void image_menu_item_set_label (GtkMenuItem *menu_item, + const gchar *label); +static const gchar * image_menu_item_get_label (GtkMenuItem *menu_item); + +static void image_menu_item_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); + +static void image_menu_item_finalize (GObject *object); +static void image_menu_item_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void image_menu_item_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void image_menu_item_screen_changed (GtkWidget *widget, + GdkScreen *previous_screen); + +static void image_menu_item_recalculate (ImageMenuItem *image_menu_item); + +static void image_menu_item_activatable_interface_init (GtkActivatableIface *iface); +static void image_menu_item_update (GtkActivatable *activatable, + GtkAction *action, + const gchar *property_name); +static void image_menu_item_sync_action_properties (GtkActivatable *activatable, + GtkAction *action); + + +G_DEFINE_TYPE_WITH_CODE (ImageMenuItem, image_menu_item, GTK_TYPE_MENU_ITEM, + G_ADD_PRIVATE (ImageMenuItem) + G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE, + image_menu_item_activatable_interface_init)) + + +static void +image_menu_item_class_init (ImageMenuItemClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + GtkWidgetClass *widget_class = (GtkWidgetClass*) klass; + GtkMenuItemClass *menu_item_class = (GtkMenuItemClass*) klass; + GtkContainerClass *container_class = (GtkContainerClass*) klass; + + widget_class->destroy = image_menu_item_destroy; + widget_class->screen_changed = image_menu_item_screen_changed; + widget_class->get_preferred_width = image_menu_item_get_preferred_width; + widget_class->get_preferred_height = image_menu_item_get_preferred_height; + widget_class->get_preferred_height_for_width = image_menu_item_get_preferred_height_for_width; + widget_class->size_allocate = image_menu_item_size_allocate; + widget_class->map = image_menu_item_map; + + container_class->forall = image_menu_item_forall; + container_class->remove = image_menu_item_remove; + + menu_item_class->toggle_size_request = image_menu_item_toggle_size_request; + menu_item_class->set_label = image_menu_item_set_label; + menu_item_class->get_label = image_menu_item_get_label; + + gobject_class->finalize = image_menu_item_finalize; + gobject_class->set_property = image_menu_item_set_property; + gobject_class->get_property = image_menu_item_get_property; + + /** + * ImageMenuItem:image: + * + * Child widget to appear next to the menu text. + * + */ + g_object_class_install_property (gobject_class, + PROP_IMAGE, + g_param_spec_object ("image", + _("Image widget"), + _("Child widget to appear next to the menu text"), + GTK_TYPE_WIDGET, + GTK_PARAM_READWRITE | G_PARAM_DEPRECATED)); + /** + * ImageMenuItem:use-stock: + * + * If %TRUE, the label set in the menuitem is used as a + * stock id to select the stock item for the item. + * + * Since: 2.16 + * + */ + g_object_class_install_property (gobject_class, + PROP_USE_STOCK, + g_param_spec_boolean ("use-stock", + _("Use stock"), + _("Whether to use the label text to create a stock menu item"), + FALSE, + GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_DEPRECATED)); + + /** + * ImageMenuItem:accel-group: + * + * The Accel Group to use for stock accelerator keys + * + * Since: 2.16 + * + */ + g_object_class_install_property (gobject_class, + PROP_ACCEL_GROUP, + g_param_spec_object ("accel-group", + _("Accel Group"), + _("The Accel Group to use for stock accelerator keys"), + GTK_TYPE_ACCEL_GROUP, + GTK_PARAM_WRITABLE | G_PARAM_DEPRECATED)); + +} + +static void +image_menu_item_init (ImageMenuItem *image_menu_item) +{ + ImageMenuItemPrivate *priv; + + image_menu_item->priv = image_menu_item_get_instance_private (image_menu_item); + priv = image_menu_item->priv; + + priv->image = NULL; + priv->use_stock = FALSE; + priv->label = NULL; +} + +static void +image_menu_item_finalize (GObject *object) +{ + ImageMenuItemPrivate *priv = IMAGE_MENU_ITEM (object)->priv; + + g_free (priv->label); + priv->label = NULL; + + G_OBJECT_CLASS (image_menu_item_parent_class)->finalize (object); +} + +static void +image_menu_item_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (object); + + switch (prop_id) + { + case PROP_IMAGE: + image_menu_item_set_image (image_menu_item, (GtkWidget *) g_value_get_object (value)); + break; + case PROP_USE_STOCK: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + image_menu_item_set_use_stock (image_menu_item, g_value_get_boolean (value)); + G_GNUC_END_IGNORE_DEPRECATIONS; + break; + case PROP_ACCEL_GROUP: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + image_menu_item_set_accel_group (image_menu_item, g_value_get_object (value)); + G_GNUC_END_IGNORE_DEPRECATIONS; + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +image_menu_item_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (object); + + switch (prop_id) + { + case PROP_IMAGE: + g_value_set_object (value, image_menu_item_get_image (image_menu_item)); + break; + case PROP_USE_STOCK: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + g_value_set_boolean (value, image_menu_item_get_use_stock (image_menu_item)); + G_GNUC_END_IGNORE_DEPRECATIONS; + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +image_menu_item_map (GtkWidget *widget) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); + ImageMenuItemPrivate *priv = image_menu_item->priv; + + GTK_WIDGET_CLASS (image_menu_item_parent_class)->map (widget); + + if (priv->image) + g_object_set (priv->image, "visible", TRUE, NULL); +} + +static void +image_menu_item_destroy (GtkWidget *widget) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); + ImageMenuItemPrivate *priv = image_menu_item->priv; + + if (priv->image) + gtk_container_remove (GTK_CONTAINER (image_menu_item), + priv->image); + + GTK_WIDGET_CLASS (image_menu_item_parent_class)->destroy (widget); +} + +static void +image_menu_item_toggle_size_request (GtkMenuItem *menu_item, + gint *requisition) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (menu_item); + ImageMenuItemPrivate *priv = image_menu_item->priv; + GtkPackDirection pack_dir; + GtkWidget *parent; + GtkWidget *widget = GTK_WIDGET (menu_item); + + parent = gtk_widget_get_parent (widget); + + if (GTK_IS_MENU_BAR (parent)) + pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); + else + pack_dir = GTK_PACK_DIRECTION_LTR; + + *requisition = 0; + + if (priv->image && gtk_widget_get_visible (priv->image)) + { + GtkRequisition image_requisition; + guint toggle_spacing; + + gtk_widget_get_preferred_size (priv->image, &image_requisition, NULL); + + gtk_widget_style_get (GTK_WIDGET (menu_item), + "toggle-spacing", &toggle_spacing, + NULL); + + if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL) + { + if (image_requisition.width > 0) + *requisition = image_requisition.width + toggle_spacing; + } + else + { + if (image_requisition.height > 0) + *requisition = image_requisition.height + toggle_spacing; + } + } +} + +static void +image_menu_item_recalculate (ImageMenuItem *image_menu_item) +{ + ImageMenuItemPrivate *priv = image_menu_item->priv; + GtkStockItem stock_item; + GtkWidget *image; + const gchar *resolved_label = priv->label; + + if (priv->use_stock && priv->label) + { + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + + if (!priv->image) + { + image = gtk_image_new_from_stock (priv->label, GTK_ICON_SIZE_MENU); + image_menu_item_set_image (image_menu_item, image); + } + + if (gtk_stock_lookup (priv->label, &stock_item)) + resolved_label = stock_item.label; + + gtk_menu_item_set_use_underline (GTK_MENU_ITEM (image_menu_item), TRUE); + + G_GNUC_END_IGNORE_DEPRECATIONS; + } + + GTK_MENU_ITEM_CLASS + (image_menu_item_parent_class)->set_label (GTK_MENU_ITEM (image_menu_item), resolved_label); + +} + +static void +image_menu_item_set_label (GtkMenuItem *menu_item, + const gchar *label) +{ + ImageMenuItemPrivate *priv = IMAGE_MENU_ITEM (menu_item)->priv; + + if (priv->label != label) + { + g_free (priv->label); + priv->label = g_strdup (label); + + image_menu_item_recalculate (IMAGE_MENU_ITEM (menu_item)); + + g_object_notify (G_OBJECT (menu_item), "label"); + + } +} + +static const gchar * +image_menu_item_get_label (GtkMenuItem *menu_item) +{ + ImageMenuItemPrivate *priv = IMAGE_MENU_ITEM (menu_item)->priv; + + return priv->label; +} + +static void +image_menu_item_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); + ImageMenuItemPrivate *priv = image_menu_item->priv; + GtkPackDirection pack_dir; + GtkWidget *parent; + + parent = gtk_widget_get_parent (widget); + + if (GTK_IS_MENU_BAR (parent)) + pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); + else + pack_dir = GTK_PACK_DIRECTION_LTR; + + GTK_WIDGET_CLASS (image_menu_item_parent_class)->get_preferred_width (widget, minimum, natural); + + if ((pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT) && + priv->image && + gtk_widget_get_visible (priv->image)) + { + gint child_minimum, child_natural; + + gtk_widget_get_preferred_width (priv->image, &child_minimum, &child_natural); + + *minimum = MAX (*minimum, child_minimum); + *natural = MAX (*natural, child_natural); + } +} + +static void +image_menu_item_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); + ImageMenuItemPrivate *priv = image_menu_item->priv; + gint child_height = 0; + GtkPackDirection pack_dir; + GtkWidget *parent; + + parent = gtk_widget_get_parent (widget); + + if (GTK_IS_MENU_BAR (parent)) + pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); + else + pack_dir = GTK_PACK_DIRECTION_LTR; + + if (priv->image && gtk_widget_get_visible (priv->image)) + { + GtkRequisition child_requisition; + + gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL); + + child_height = child_requisition.height; + } + + GTK_WIDGET_CLASS (image_menu_item_parent_class)->get_preferred_height (widget, minimum, natural); + + if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR) + { + *minimum = MAX (*minimum, child_height); + *natural = MAX (*natural, child_height); + } +} + +static void +image_menu_item_get_preferred_height_for_width (GtkWidget *widget, + gint width, + gint *minimum, + gint *natural) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); + ImageMenuItemPrivate *priv = image_menu_item->priv; + gint child_height = 0; + GtkPackDirection pack_dir; + GtkWidget *parent; + + parent = gtk_widget_get_parent (widget); + + if (GTK_IS_MENU_BAR (parent)) + pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); + else + pack_dir = GTK_PACK_DIRECTION_LTR; + + if (priv->image && gtk_widget_get_visible (priv->image)) + { + GtkRequisition child_requisition; + + gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL); + + child_height = child_requisition.height; + } + + GTK_WIDGET_CLASS + (image_menu_item_parent_class)->get_preferred_height_for_width (widget, width, minimum, natural); + + if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR) + { + *minimum = MAX (*minimum, child_height); + *natural = MAX (*natural, child_height); + } +} + + +static void +image_menu_item_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (widget); + ImageMenuItemPrivate *priv = image_menu_item->priv; + GtkAllocation widget_allocation; + GtkPackDirection pack_dir; + GtkWidget *parent; + + parent = gtk_widget_get_parent (widget); + + if (GTK_IS_MENU_BAR (parent)) + pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent)); + else + pack_dir = GTK_PACK_DIRECTION_LTR; + + GTK_WIDGET_CLASS (image_menu_item_parent_class)->size_allocate (widget, allocation); + + if (priv->image && gtk_widget_get_visible (priv->image)) + { + gint x, y, offset; + GtkStyleContext *context; + GtkStateFlags state; + GtkBorder padding; + GtkRequisition child_requisition; + GtkAllocation child_allocation; + guint horizontal_padding, toggle_spacing; + gint toggle_size; + + toggle_size = image_menu_item->priv->toggle_size; + gtk_widget_style_get (widget, + "horizontal-padding", &horizontal_padding, + "toggle-spacing", &toggle_spacing, + NULL); + + /* Man this is lame hardcoding action, but I can't + * come up with a solution that's really better. + */ + + gtk_widget_get_preferred_size (priv->image, &child_requisition, NULL); + + gtk_widget_get_allocation (widget, &widget_allocation); + + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + gtk_style_context_get_padding (context, state, &padding); + offset = gtk_container_get_border_width (GTK_CONTAINER (image_menu_item)); + + if (pack_dir == GTK_PACK_DIRECTION_LTR || + pack_dir == GTK_PACK_DIRECTION_RTL) + { + if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) == + (pack_dir == GTK_PACK_DIRECTION_LTR)) + x = offset + horizontal_padding + padding.left + + (toggle_size - toggle_spacing - child_requisition.width) / 2; + else + x = widget_allocation.width - offset - horizontal_padding - padding.right - + toggle_size + toggle_spacing + + (toggle_size - toggle_spacing - child_requisition.width) / 2; + + y = (widget_allocation.height - child_requisition.height) / 2; + } + else + { + if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) == + (pack_dir == GTK_PACK_DIRECTION_TTB)) + y = offset + horizontal_padding + padding.top + + (toggle_size - toggle_spacing - child_requisition.height) / 2; + else + y = widget_allocation.height - offset - horizontal_padding - padding.bottom - + toggle_size + toggle_spacing + + (toggle_size - toggle_spacing - child_requisition.height) / 2; + + x = (widget_allocation.width - child_requisition.width) / 2; + } + + child_allocation.width = child_requisition.width; + child_allocation.height = child_requisition.height; + child_allocation.x = widget_allocation.x + MAX (x, 0); + child_allocation.y = widget_allocation.y + MAX (y, 0); + + gtk_widget_size_allocate (priv->image, &child_allocation); + } +} + +static void +image_menu_item_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (container); + ImageMenuItemPrivate *priv = image_menu_item->priv; + + GTK_CONTAINER_CLASS (image_menu_item_parent_class)->forall (container, + include_internals, + callback, + callback_data); + + if (include_internals && priv->image) + (* callback) (priv->image, callback_data); +} + + +static void +image_menu_item_activatable_interface_init (GtkActivatableIface *iface) +{ + parent_activatable_iface = g_type_interface_peek_parent (iface); + iface->update = image_menu_item_update; + iface->sync_action_properties = image_menu_item_sync_action_properties; +} + +static gboolean +activatable_update_stock_id (ImageMenuItem *image_menu_item, GtkAction *action) +{ + GtkWidget *image; + const gchar *stock_id = gtk_action_get_stock_id (action); + + image = image_menu_item_get_image (image_menu_item); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + + if (GTK_IS_IMAGE (image) && + stock_id && gtk_icon_factory_lookup_default (stock_id)) + { + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + gtk_image_set_from_stock (GTK_IMAGE (image), stock_id, GTK_ICON_SIZE_MENU); + G_GNUC_END_IGNORE_DEPRECATIONS; + return TRUE; + } + + G_GNUC_END_IGNORE_DEPRECATIONS; + + return FALSE; +} + +static gboolean +activatable_update_gicon (ImageMenuItem *image_menu_item, GtkAction *action) +{ + GtkWidget *image; + GIcon *icon = gtk_action_get_gicon (action); + const gchar *stock_id; + gboolean ret = FALSE; + + stock_id = gtk_action_get_stock_id (action); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + + image = image_menu_item_get_image (image_menu_item); + + if (icon && GTK_IS_IMAGE (image) && + !(stock_id && gtk_icon_factory_lookup_default (stock_id))) + { + gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU); + ret = TRUE; + } + + G_GNUC_END_IGNORE_DEPRECATIONS; + + return ret; +} + +static void +activatable_update_icon_name (ImageMenuItem *image_menu_item, GtkAction *action) +{ + GtkWidget *image; + const gchar *icon_name = gtk_action_get_icon_name (action); + + image = image_menu_item_get_image (image_menu_item); + + if (GTK_IS_IMAGE (image) && + (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY || + gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME)) + { + gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU); + } +} + +static void +image_menu_item_update (GtkActivatable *activatable, + GtkAction *action, + const gchar *property_name) +{ + ImageMenuItem *image_menu_item; + gboolean use_appearance; + + image_menu_item = IMAGE_MENU_ITEM (activatable); + + parent_activatable_iface->update (activatable, action, property_name); + + use_appearance = gtk_activatable_get_use_action_appearance (activatable); + if (!use_appearance) + return; + + if (strcmp (property_name, "stock-id") == 0) + activatable_update_stock_id (image_menu_item, action); + else if (strcmp (property_name, "gicon") == 0) + activatable_update_gicon (image_menu_item, action); + else if (strcmp (property_name, "icon-name") == 0) + activatable_update_icon_name (image_menu_item, action); +} + +static void +image_menu_item_sync_action_properties (GtkActivatable *activatable, + GtkAction *action) +{ + ImageMenuItem *image_menu_item; + GtkWidget *image; + gboolean use_appearance; + + image_menu_item = IMAGE_MENU_ITEM (activatable); + + parent_activatable_iface->sync_action_properties (activatable, action); + + if (!action) + return; + + use_appearance = gtk_activatable_get_use_action_appearance (activatable); + if (!use_appearance) + return; + + image = image_menu_item_get_image (image_menu_item); + if (image && !GTK_IS_IMAGE (image)) + { + image_menu_item_set_image (image_menu_item, NULL); + image = NULL; + } + + if (!image) + { + image = gtk_image_new (); + gtk_widget_show (image); + image_menu_item_set_image (IMAGE_MENU_ITEM (activatable), + image); + } + + if (!activatable_update_stock_id (image_menu_item, action) && + !activatable_update_gicon (image_menu_item, action)) + activatable_update_icon_name (image_menu_item, action); + +} + + +/** + * image_menu_item_new: + * + * Creates a new #ImageMenuItem with an empty label. + * + * Returns: a new #ImageMenuItem + * + */ +GtkWidget* +image_menu_item_new (void) +{ + return g_object_new (TYPE_IMAGE_MENU_ITEM, NULL); +} + +/** + * image_menu_item_new_with_label: + * @label: the text of the menu item. + * + * Creates a new #ImageMenuItem containing a label. + * + * Returns: a new #ImageMenuItem. + * + */ +GtkWidget* +image_menu_item_new_with_label (const gchar *label) +{ + return g_object_new (TYPE_IMAGE_MENU_ITEM, + "label", label, + NULL); +} + +/** + * image_menu_item_new_with_mnemonic: + * @label: the text of the menu item, with an underscore in front of the + * mnemonic character + * + * Creates a new #ImageMenuItem containing a label. The label + * will be created using gtk_label_new_with_mnemonic(), so underscores + * in @label indicate the mnemonic for the menu item. + * + * Returns: a new #ImageMenuItem + * + */ +GtkWidget* +image_menu_item_new_with_mnemonic (const gchar *label) +{ + return g_object_new (TYPE_IMAGE_MENU_ITEM, + "use-underline", TRUE, + "label", label, + NULL); +} + +/** + * image_menu_item_new_from_stock: + * @stock_id: the name of the stock item. + * @accel_group: (allow-none): the #GtkAccelGroup to add the menu items + * accelerator to, or %NULL. + * + * Creates a new #ImageMenuItem containing the image and text from a + * stock item. Some stock ids have preprocessor macros like #STOCK_OK + * and #STOCK_APPLY. + * + * If you want this menu item to have changeable accelerators, then pass in + * %NULL for accel_group. Next call gtk_menu_item_set_accel_path() with an + * appropriate path for the menu item, use gtk_stock_lookup() to look up the + * standard accelerator for the stock item, and if one is found, call + * gtk_accel_map_add_entry() to register it. + * + * Returns: a new #ImageMenuItem. + * + */ +GtkWidget* +image_menu_item_new_from_stock (const gchar *stock_id, + GtkAccelGroup *accel_group) +{ + return g_object_new (TYPE_IMAGE_MENU_ITEM, + "label", stock_id, + "use-stock", TRUE, + "accel-group", accel_group, + NULL); +} + +/** + * image_menu_item_set_use_stock: + * @image_menu_item: a #ImageMenuItem + * @use_stock: %TRUE if the menuitem should use a stock item + * + * If %TRUE, the label set in the menuitem is used as a + * stock id to select the stock item for the item. + * + * Since: 2.16 + * + */ +void +image_menu_item_set_use_stock (ImageMenuItem *image_menu_item, + gboolean use_stock) +{ + ImageMenuItemPrivate *priv; + + g_return_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item)); + + priv = image_menu_item->priv; + + if (priv->use_stock != use_stock) + { + priv->use_stock = use_stock; + + image_menu_item_recalculate (image_menu_item); + + g_object_notify (G_OBJECT (image_menu_item), "use-stock"); + } +} + +/** + * image_menu_item_get_use_stock: + * @image_menu_item: a #ImageMenuItem + * + * Checks whether the label set in the menuitem is used as a + * stock id to select the stock item for the item. + * + * Returns: %TRUE if the label set in the menuitem is used as a + * stock id to select the stock item for the item + * + * Since: 2.16 + * + */ +gboolean +image_menu_item_get_use_stock (ImageMenuItem *image_menu_item) +{ + g_return_val_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item), FALSE); + + return image_menu_item->priv->use_stock; +} + +/** + * image_menu_item_set_accel_group: + * @image_menu_item: a #ImageMenuItem + * @accel_group: the #GtkAccelGroup + * + * Specifies an @accel_group to add the menu items accelerator to + * (this only applies to stock items so a stock item must already + * be set, make sure to call image_menu_item_set_use_stock() + * and gtk_menu_item_set_label() with a valid stock item first). + * + * If you want this menu item to have changeable accelerators then + * you shouldnt need this (see image_menu_item_new_from_stock()). + * + * Since: 2.16 + * + */ +void +image_menu_item_set_accel_group (ImageMenuItem *image_menu_item, + GtkAccelGroup *accel_group) +{ + ImageMenuItemPrivate *priv; + GtkStockItem stock_item; + + /* Silent return for the constructor */ + if (!accel_group) + return; + + g_return_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item)); + g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group)); + + priv = image_menu_item->priv; + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + + if (priv->use_stock && priv->label && gtk_stock_lookup (priv->label, &stock_item)) + if (stock_item.keyval) + { + gtk_widget_add_accelerator (GTK_WIDGET (image_menu_item), + "activate", + accel_group, + stock_item.keyval, + stock_item.modifier, + GTK_ACCEL_VISIBLE); + + g_object_notify (G_OBJECT (image_menu_item), "accel-group"); + } + + G_GNUC_END_IGNORE_DEPRECATIONS; + +} + +/** + * image_menu_item_set_image: + * @image_menu_item: a #ImageMenuItem. + * @image: (allow-none): a widget to set as the image for the menu item. + * + * Sets the image of @image_menu_item to the given widget. + * Note that it depends on the show-menu-images setting whether + * the image will be displayed or not. + * + */ +void +image_menu_item_set_image (ImageMenuItem *image_menu_item, + GtkWidget *image) +{ + ImageMenuItemPrivate *priv; + + g_return_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item)); + + priv = image_menu_item->priv; + + if (image == priv->image) + return; + + if (priv->image) + gtk_container_remove (GTK_CONTAINER (image_menu_item), + priv->image); + + priv->image = image; + + if (image == NULL) + return; + + gtk_widget_set_parent (image, GTK_WIDGET (image_menu_item)); + g_object_set (image, "visible", TRUE, "no-show-all", TRUE, NULL); + + g_object_notify (G_OBJECT (image_menu_item), "image"); +} + +/** + * image_menu_item_get_image: + * @image_menu_item: a #ImageMenuItem + * + * Gets the widget that is currently set as the image of @image_menu_item. + * See image_menu_item_set_image(). + * + * Return value: (transfer none): the widget set as image of @image_menu_item + * + **/ +GtkWidget* +image_menu_item_get_image (ImageMenuItem *image_menu_item) +{ + g_return_val_if_fail (IS_IMAGE_MENU_ITEM (image_menu_item), NULL); + + return image_menu_item->priv->image; +} + +static void +image_menu_item_remove (GtkContainer *container, + GtkWidget *child) +{ + ImageMenuItem *image_menu_item = IMAGE_MENU_ITEM (container); + ImageMenuItemPrivate *priv = image_menu_item->priv; + + if (child == priv->image) + { + gboolean widget_was_visible; + + widget_was_visible = gtk_widget_get_visible (child); + + gtk_widget_unparent (child); + priv->image = NULL; + + if (widget_was_visible && + gtk_widget_get_visible (GTK_WIDGET (container))) + gtk_widget_queue_resize (GTK_WIDGET (container)); + + g_object_notify (G_OBJECT (image_menu_item), "image"); + } + else + { + GTK_CONTAINER_CLASS (image_menu_item_parent_class)->remove (container, child); + } +} + +static void +show_image_change_notify (ImageMenuItem *image_menu_item) +{ + ImageMenuItemPrivate *priv = image_menu_item->priv; + + if (priv->image) + { + gtk_widget_show (priv->image); + } +} + +static void +traverse_container (GtkWidget *widget, + gpointer data) +{ + if (IS_IMAGE_MENU_ITEM (widget)) + show_image_change_notify (IMAGE_MENU_ITEM (widget)); + else if (GTK_IS_CONTAINER (widget)) + gtk_container_forall (GTK_CONTAINER (widget), traverse_container, NULL); +} + +static void +image_menu_item_setting_changed (GtkSettings *settings) +{ + GList *list, *l; + + list = gtk_window_list_toplevels (); + + for (l = list; l; l = l->next) + gtk_container_forall (GTK_CONTAINER (l->data), + traverse_container, NULL); + + g_list_free (list); +} + +static void +image_menu_item_screen_changed (GtkWidget *widget, + GdkScreen *previous_screen) +{ + GtkSettings *settings; + gulong show_image_connection; + + if (!gtk_widget_has_screen (widget)) + return; + + settings = gtk_widget_get_settings (widget); + + show_image_connection = + g_signal_handler_find (settings, G_SIGNAL_MATCH_FUNC, 0, 0, + NULL, image_menu_item_setting_changed, NULL); + + if (show_image_connection) + return; + + g_signal_connect (settings, "notify::gtk-menu-images", + G_CALLBACK (image_menu_item_setting_changed), NULL); + + show_image_change_notify (IMAGE_MENU_ITEM (widget)); +} diff --git a/src/widgets/image-menu-item.h b/src/widgets/image-menu-item.h new file mode 100644 index 000000000..61cc48f3a --- /dev/null +++ b/src/widgets/image-menu-item.h @@ -0,0 +1,81 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. + * Forked for , icons in menus are important to us. + */ + +#ifndef __IMAGE_MENU_ITEM_H__ +#define __IMAGE_MENU_ITEM_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define GTK_PARAM_READABLE G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB +#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB +#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB + +#define TYPE_IMAGE_MENU_ITEM (image_menu_item_get_type ()) +#define IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_IMAGE_MENU_ITEM, ImageMenuItem)) +#define IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_IMAGE_MENU_ITEM, ImageMenuItemClass)) +#define IS_IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_IMAGE_MENU_ITEM)) +#define IS_IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_IMAGE_MENU_ITEM)) +#define IMAGE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_IMAGE_MENU_ITEM, ImageMenuItemClass)) + +typedef struct _ImageMenuItem ImageMenuItem; +typedef struct _ImageMenuItemPrivate ImageMenuItemPrivate; +typedef struct _ImageMenuItemClass ImageMenuItemClass; + +struct _ImageMenuItem +{ + GtkMenuItem menu_item; + + /*< private >*/ + ImageMenuItemPrivate *priv; +}; + +struct _ImageMenuItemClass +{ + GtkMenuItemClass parent_class; + + /* Padding for future expansion */ + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); +}; + +GType image_menu_item_get_type (void) G_GNUC_CONST; +GtkWidget* image_menu_item_new (void); +GtkWidget* image_menu_item_new_with_label (const gchar *label); +GtkWidget* image_menu_item_new_with_mnemonic (const gchar *label); +GtkWidget* image_menu_item_new_from_stock (const gchar *stock_id, + GtkAccelGroup *accel_group); +void image_menu_item_set_image (ImageMenuItem *image_menu_item, + GtkWidget *image); +GtkWidget* image_menu_item_get_image (ImageMenuItem *image_menu_item); +void image_menu_item_set_use_stock (ImageMenuItem *image_menu_item, + gboolean use_stock); +gboolean image_menu_item_get_use_stock (ImageMenuItem *image_menu_item); +void image_menu_item_set_accel_group (ImageMenuItem *image_menu_item, + GtkAccelGroup *accel_group); + +G_END_DECLS + +#endif /* __IMAGE_MENU_ITEM_H__ */ diff --git a/src/widgets/ink-action.cpp b/src/widgets/ink-action.cpp index 5941c31e4..ace99d9aa 100644 --- a/src/widgets/ink-action.cpp +++ b/src/widgets/ink-action.cpp @@ -1,12 +1,20 @@ #include "widgets/icon.h" #include "icon-size.h" #include <glib/gi18n.h> -#include <gtk/gtk.h> + #include "widgets/ink-action.h" #include "widgets/button.h" +#include <gtk/gtk.h> + +#if GTK_CHECK_VERSION(3,0,0) + // Fork of gtk-imagemenuitem to continue support + #include "widgets/image-menu-item.h" + +#endif + static void ink_action_finalize( GObject* obj ); static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); @@ -158,7 +166,12 @@ static GtkWidget* ink_action_create_menu_item( GtkAction* action ) gchar* label = 0; g_object_get( G_OBJECT(act), "label", &label, NULL ); +#if GTK_CHECK_VERSION(3,0,0) + item = image_menu_item_new_with_mnemonic( label ); +#else item = gtk_image_menu_item_new_with_mnemonic( label ); +#endif + GtkWidget* child = sp_icon_new( Inkscape::ICON_SIZE_MENU, act->private_data->iconId ); // TODO this work-around is until SPIcon will live properly inside of a popup menu if ( SP_IS_ICON(child) ) { @@ -172,7 +185,12 @@ static GtkWidget* ink_action_create_menu_item( GtkAction* action ) } } gtk_widget_show_all( child ); + +#if GTK_CHECK_VERSION(3,0,0) + image_menu_item_set_image( IMAGE_MENU_ITEM(item), child ); +#else gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), child ); +#endif g_free( label ); label = 0; @@ -374,9 +392,16 @@ static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ) GtkToolButton* button = GTK_TOOL_BUTTON(item); if ( act->private_data->iconId ) { GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_hexpand(child, FALSE); + gtk_widget_set_vexpand(child, FALSE); + gtk_tool_button_set_icon_widget(button, child); +#else GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 ); gtk_container_add( GTK_CONTAINER(align), child ); gtk_tool_button_set_icon_widget( button, align ); +#endif } else { gchar *label = 0; g_object_get( G_OBJECT(action), "short_label", &label, NULL ); @@ -405,10 +430,18 @@ static void ink_toggle_action_update_icon( InkToggleAction* action ) GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data); GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_hexpand(child, FALSE); + gtk_widget_set_vexpand(child, FALSE); + gtk_widget_show_all(child); + gtk_tool_button_set_icon_widget(button, child); +#else GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 ); gtk_container_add( GTK_CONTAINER(align), child ); gtk_widget_show_all( align ); gtk_tool_button_set_icon_widget( button, align ); +#endif } } @@ -577,9 +610,16 @@ static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action ) GtkToolButton* button = GTK_TOOL_BUTTON(item); GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_hexpand(child, FALSE); + gtk_widget_set_vexpand(child, FALSE); + gtk_tool_button_set_icon_widget(button, child); +#else GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 ); gtk_container_add( GTK_CONTAINER(align), child ); gtk_tool_button_set_icon_widget( button, align ); +#endif } else { // For now trigger a warning but don't do anything else GtkToolButton* button = GTK_TOOL_BUTTON(item); diff --git a/src/widgets/ink-comboboxentry-action.cpp b/src/widgets/ink-comboboxentry-action.cpp index 1114d2cdb..ec5e26cf5 100644 --- a/src/widgets/ink-comboboxentry-action.cpp +++ b/src/widgets/ink-comboboxentry-action.cpp @@ -371,9 +371,16 @@ GtkWidget* create_tool_item( GtkAction* action ) g_free( combobox_name ); { +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(comboBoxEntry, GTK_ALIGN_START); + gtk_widget_set_hexpand(comboBoxEntry, FALSE); + gtk_widget_set_vexpand(comboBoxEntry, FALSE); + gtk_container_add(GTK_CONTAINER(item), comboBoxEntry); +#else GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0); gtk_container_add( GTK_CONTAINER(align), comboBoxEntry ); gtk_container_add( GTK_CONTAINER(item), align ); +#endif } ink_comboboxentry_action->combobox = GTK_COMBO_BOX (comboBoxEntry); @@ -956,3 +963,14 @@ gboolean keypress_cb( GtkWidget * /*widget*/, GdkEventKey *event, gpointer data return wasConsumed; } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index 7030753a5..89ab76585 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -84,12 +84,23 @@ spw_label_old(GtkWidget *table, const gchar *label_text, int col, int row) label_widget = gtk_label_new (label_text); g_assert(label_widget != NULL); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(label_widget, GTK_ALIGN_END); +#else gtk_misc_set_alignment (GTK_MISC (label_widget), 1.0, 0.5); +#endif + gtk_widget_show (label_widget); #if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_margin_start(label_widget, 4); + gtk_widget_set_margin_end(label_widget, 4); +#if GTK_CHECK_VERSION(3,12,0) +#else gtk_widget_set_margin_left(label_widget, 4); gtk_widget_set_margin_right(label_widget, 4); +#endif gtk_widget_set_hexpand(label_widget, TRUE); gtk_widget_set_halign(label_widget, GTK_ALIGN_FILL); gtk_widget_set_valign(label_widget, GTK_ALIGN_CENTER); @@ -166,7 +177,13 @@ spw_checkbutton(GtkWidget * dialog, GtkWidget * table, g_assert(table != NULL); GtkWidget *l = gtk_label_new (label); + +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_halign(l, GTK_ALIGN_END); +#else gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); +#endif + gtk_widget_show (l); #if GTK_CHECK_VERSION(3,0,0) @@ -238,12 +255,26 @@ sp_set_font_size_recursive (GtkWidget *w, gpointer font) { guint size = GPOINTER_TO_UINT (font); - PangoFontDescription* pan = pango_font_description_new (); - pango_font_description_set_size (pan, size); - #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_override_font (w, pan); + GtkCssProvider *css_provider = gtk_css_provider_new(); + + const double pt_size = size / static_cast<double>(PANGO_SCALE); + std::ostringstream css_data; + css_data << "GtkWidget {\n" + << " font-size: " << pt_size << "pt;\n" + << "}\n"; + + gtk_css_provider_load_from_data(css_provider, + css_data.str().c_str(), + -1, NULL); + + GtkStyleContext *style_context = gtk_widget_get_style_context(w); + gtk_style_context_add_provider(style_context, + GTK_STYLE_PROVIDER(css_provider), + GTK_STYLE_PROVIDER_PRIORITY_USER); #else + PangoFontDescription* pan = pango_font_description_new (); + pango_font_description_set_size (pan, size); gtk_widget_modify_font (w, pan); #endif @@ -251,7 +282,11 @@ sp_set_font_size_recursive (GtkWidget *w, gpointer font) gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font); } +#if GTK_CHECK_VERSION(3,0,0) + g_object_unref(css_provider); +#else pango_font_description_free (pan); +#endif } void diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index e71c911bd..661fc6fa9 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -508,6 +508,10 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } +static bool is_relative( Unit const *unit ) { + return (unit->abbr == "" || unit->abbr == "em" || unit->abbr == "ex" || unit->abbr == "%"); +} + static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) { // quit if run by the _changed callbacks @@ -524,21 +528,22 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so - // we can save it (allows us to adjust line height value when unit changes). - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); - + // Only save if not relative unit + if ( !is_relative(unit) ) { + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so + // we can save it (allows us to adjust line height value when unit changes). + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + } // Set css line height. SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - // We should handle unitless values as well as 'em' and 'ex' - if ((unit->abbr) == "em" || unit->abbr == "ex" || unit->abbr == "%") { + if ( is_relative(unit) ) { osfs << gtk_adjustment_get_value(adj) << unit->abbr; } else { // Inside SVG file, always use "px" for absolute units. @@ -601,13 +606,16 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) g_return_if_fail(unit != NULL); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + // Only save if not relative unit + if ( !is_relative(unit) ) { + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + } // Read current line height value EgeAdjustmentAction *line_height_act = @@ -620,19 +628,19 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) std::vector<SPItem*> itemlist=selection->itemList(); // Convert between units - if ((unit->abbr) == "em" && old_unit == SP_CSS_UNIT_EX) { + if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { line_height *= 0.5; - } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_EM) { + } else if ((unit->abbr) == "ex" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { line_height *= 2.0; - } else if ((unit->abbr) == "em" && old_unit == SP_CSS_UNIT_PERCENT) { + } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_PERCENT) { line_height /= 100.0; - } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EM) { + } else if ((unit->abbr) == "%" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { line_height *= 100; } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) { line_height /= 50.0; } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) { line_height *= 50; - } else if ((unit->abbr) == "%" || (unit->abbr) == "em" || (unit->abbr) == "ex") { + } else if (is_relative(unit)) { // Convert absolute to relative... for the moment use average font-size double font_size = 0; int count = 0; @@ -648,7 +656,10 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) } else { font_size = 20; } + + if (old_unit == SP_CSS_UNIT_NONE) old_unit = SP_CSS_UNIT_EM; line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px"); + if (font_size > 0) { line_height /= font_size; } @@ -657,7 +668,8 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) } else if ((unit->abbr) == "ex") { line_height *= 2; } - } else if (old_unit==SP_CSS_UNIT_PERCENT || old_unit==SP_CSS_UNIT_EM || old_unit==SP_CSS_UNIT_EX) { + } else if (old_unit==SP_CSS_UNIT_NONE || old_unit==SP_CSS_UNIT_PERCENT || + old_unit==SP_CSS_UNIT_EM || old_unit==SP_CSS_UNIT_EX) { // Convert relative to absolute... for the moment use average font-size double font_size = 0; int count = 0; @@ -689,8 +701,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Set css line height. SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream osfs; - // We should handle unitless values as well as 'em' and 'ex' - if ((unit->abbr) == "em" || unit->abbr == "ex" || unit->abbr == "%") { + if ( is_relative(unit) ) { osfs << line_height << unit->abbr; } else { osfs << Quantity::convert(line_height, unit, "px") << "px"; @@ -1264,8 +1275,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ switch (line_height_unit) { case SP_CSS_UNIT_NONE: - // tracker can't show no unit... use 'em' - line_height_unit = SP_CSS_UNIT_EM; case SP_CSS_UNIT_EM: case SP_CSS_UNIT_EX: break; @@ -1276,7 +1285,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // If unit is set to 'px', use the preferred display unit (if absolute). line_height_unit = prefs->getInt("/tools/text/lineheight/display_unit", SP_CSS_UNIT_PT); - if (line_height_unit != SP_CSS_UNIT_EM && + // But not if prefered unit is relative + if (line_height_unit != SP_CSS_UNIT_NONE && + line_height_unit != SP_CSS_UNIT_EM && line_height_unit != SP_CSS_UNIT_EX && line_height_unit != SP_CSS_UNIT_PERCENT) { height = @@ -1299,7 +1310,13 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ gtk_adjustment_set_value( lineHeightAdjustment, height ); UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); - tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit)); + if( line_height_unit == SP_CSS_UNIT_NONE ) { + // Function 'sp_style_get_css_unit_string' returns 'px' for unit none. + // We need to avoid this. + tracker->setActiveUnitByAbbr(""); + } else { + tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit)); + } // Save unit so we can do convertions between new/old units. g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); @@ -1797,10 +1814,10 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje /* Line height unit tracker */ UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->prependUnit(unit_table.getUnit("")); // No unit tracker->addUnit(unit_table.getUnit("%")); tracker->addUnit(unit_table.getUnit("em")); tracker->addUnit(unit_table.getUnit("ex")); - // tracker->addUnit(unit_table.getUnit("None")); tracker->setActiveUnit(unit_table.getUnit("%")); g_object_set_data( holder, "tracker", tracker ); |
