From b40f9bd37abc96d579f930dee9e6fb95031d74f0 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Wed, 6 Jul 2011 00:26:32 -0700 Subject: Refactoring color profile to bring more internal. Help to prep for optional lcms2 support. (bzr r10420) --- src/color-profile-fns.h | 1 - src/color-profile.cpp | 261 ++++++++++++++++++++++----------- src/color-profile.h | 32 ++-- src/interface.cpp | 4 - src/ui/dialog/document-properties.cpp | 60 +++----- src/ui/dialog/inkscape-preferences.cpp | 4 +- src/widgets/sp-color-icc-selector.h | 8 +- src/widgets/sp-color-notebook.cpp | 3 +- 8 files changed, 213 insertions(+), 160 deletions(-) (limited to 'src') diff --git a/src/color-profile-fns.h b/src/color-profile-fns.h index defc58f2c..3d22417f6 100644 --- a/src/color-profile-fns.h +++ b/src/color-profile-fns.h @@ -38,7 +38,6 @@ std::vector colorprofile_get_display_names(); std::vector colorprofile_get_softproof_names(); Glib::ustring get_path_for_profile(Glib::ustring const& name); -void colorprofile_load_profiles(bool force_refresh = false); #endif diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 4dc4d5bd8..7c9e83e3c 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -24,6 +24,10 @@ #include #endif +#if ENABLE_LCMS +#include +#endif // ENABLE_LCMS + #include "xml/repr.h" #include "color.h" #include "color-profile.h" @@ -42,12 +46,15 @@ using Inkscape::ColorProfile; using Inkscape::ColorProfileClass; +using Inkscape::ColorProfileImpl; -namespace Inkscape +namespace { #if ENABLE_LCMS -static cmsHPROFILE colorprofile_get_system_profile_handle(); -static cmsHPROFILE colorprofile_get_proof_profile_handle(); +cmsHPROFILE getSystemProfileHandle(); +cmsHPROFILE getProofProfileHandle(); +void loadProfiles(); +Glib::ustring getNameFromProfile(cmsHPROFILE profile); #endif // ENABLE_LCMS } @@ -93,20 +100,57 @@ extern guint update_in_progress; static SPObjectClass *cprof_parent_class; + +class ColorProfileImpl { +public: + static cmsHPROFILE _sRGBProf; + static cmsHPROFILE _NullProf; + + ColorProfileImpl(); + #if ENABLE_LCMS + static DWORD _getInputFormat( icColorSpaceSignature space ); + + static cmsHPROFILE getNULLProfile(); + static cmsHPROFILE getSRGBProfile(); -cmsHPROFILE ColorProfile::_sRGBProf = 0; + void _clearProfile(); -cmsHPROFILE ColorProfile::getSRGBProfile() { + cmsHPROFILE _profHandle; + icProfileClassSignature _profileClass; + icColorSpaceSignature _profileSpace; + cmsHTRANSFORM _transf; + cmsHTRANSFORM _revTransf; + cmsHTRANSFORM _gamutTransf; +#endif // ENABLE_LCMS +}; + +ColorProfileImpl::ColorProfileImpl() : +#if ENABLE_LCMS + _profHandle(0), + _profileClass(icSigInputClass), + _profileSpace(icSigRgbData), + _transf(0), + _revTransf(0), + _gamutTransf(0) +#endif // ENABLE_LCMS +{ +} + +#if ENABLE_LCMS + +cmsHPROFILE ColorProfileImpl::_sRGBProf = 0; + +cmsHPROFILE ColorProfileImpl::getSRGBProfile() { if ( !_sRGBProf ) { _sRGBProf = cmsCreate_sRGBProfile(); } - return _sRGBProf; + return ColorProfileImpl::_sRGBProf; } -cmsHPROFILE ColorProfile::_NullProf = 0; +cmsHPROFILE ColorProfileImpl::_NullProf = 0; -cmsHPROFILE ColorProfile::getNULLProfile() { +cmsHPROFILE ColorProfileImpl::getNULLProfile() { if ( !_NullProf ) { _NullProf = cmsCreateNULLProfile(); } @@ -162,19 +206,13 @@ void ColorProfile::classInit( ColorProfileClass *klass ) */ void ColorProfile::init( ColorProfile *cprof ) { + cprof->impl = new ColorProfileImpl(); + cprof->href = 0; cprof->local = 0; cprof->name = 0; cprof->intentStr = 0; cprof->rendering_intent = Inkscape::RENDERING_INTENT_UNKNOWN; -#if ENABLE_LCMS - cprof->profHandle = 0; - cprof->_profileClass = icSigInputClass; - cprof->_profileSpace = icSigRgbData; - cprof->_transf = 0; - cprof->_revTransf = 0; - cprof->_gamutTransf = 0; -#endif // ENABLE_LCMS } /** @@ -209,12 +247,15 @@ void ColorProfile::release( SPObject *object ) } #if ENABLE_LCMS - cprof->_clearProfile(); + cprof->impl->_clearProfile(); #endif // ENABLE_LCMS + + delete cprof->impl; + cprof->impl = 0; } #if ENABLE_LCMS -void ColorProfile::_clearProfile() +void ColorProfileImpl::_clearProfile() { _profileSpace = icSigRgbData; @@ -230,9 +271,9 @@ void ColorProfile::_clearProfile() cmsDeleteTransform( _gamutTransf ); _gamutTransf = 0; } - if ( profHandle ) { - cmsCloseProfile( profHandle ); - profHandle = 0; + if ( _profHandle ) { + cmsCloseProfile( _profHandle ); + _profHandle = 0; } } #endif // ENABLE_LCMS @@ -309,13 +350,13 @@ void ColorProfile::set( SPObject *object, unsigned key, gchar const *value ) // the w3c specs. All absolute and relative issues are considered org::w3c::dom::URI cprofUri = docUri.resolve(hrefUri); gchar* fullname = g_uri_unescape_string(cprofUri.getNativePath().c_str(), ""); - cprof->_clearProfile(); - cprof->profHandle = cmsOpenProfileFromFile( fullname, "r" ); - if ( cprof->profHandle ) { - cprof->_profileSpace = cmsGetColorSpace( cprof->profHandle ); - cprof->_profileClass = cmsGetDeviceClass( cprof->profHandle ); + cprof->impl->_clearProfile(); + cprof->impl->_profHandle = cmsOpenProfileFromFile( fullname, "r" ); + if ( cprof->impl->_profHandle ) { + cprof->impl->_profileSpace = cmsGetColorSpace( cprof->impl->_profHandle ); + cprof->impl->_profileClass = cmsGetDeviceClass( cprof->impl->_profHandle ); } - DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", fullname, (void*)cprof->profHandle ); + DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", fullname, (void*)cprof->impl->_profHandle ); g_free(escaped); escaped = 0; g_free(fullname); @@ -423,7 +464,7 @@ struct MapMap { DWORD inForm; }; -DWORD ColorProfile::_getInputFormat( icColorSpaceSignature space ) +DWORD ColorProfileImpl::_getInputFormat( icColorSpaceSignature space ) { MapMap possible[] = { {icSigXYZData, TYPE_XYZ_16}, @@ -498,7 +539,7 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* inte SPObject* thing = bruteFind( document, name ); if ( thing ) { - prof = COLORPROFILE(thing)->profHandle; + prof = COLORPROFILE(thing)->impl->_profHandle; } if ( intent ) { @@ -510,35 +551,43 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* inte return prof; } +icColorSpaceSignature ColorProfile::getColorSpace() const { + return impl->_profileSpace; +} + +icProfileClassSignature ColorProfile::getProfileClass() const { + return impl->_profileClass; +} + cmsHTRANSFORM ColorProfile::getTransfToSRGB8() { - if ( !_transf && profHandle ) { + if ( !impl->_transf && impl->_profHandle ) { int intent = getLcmsIntent(rendering_intent); - _transf = cmsCreateTransform( profHandle, _getInputFormat(_profileSpace), getSRGBProfile(), TYPE_BGRA_8, intent, 0 ); + impl->_transf = cmsCreateTransform( impl->_profHandle, ColorProfileImpl::_getInputFormat(impl->_profileSpace), ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, intent, 0 ); } - return _transf; + return impl->_transf; } cmsHTRANSFORM ColorProfile::getTransfFromSRGB8() { - if ( !_revTransf && profHandle ) { + if ( !impl->_revTransf && impl->_profHandle ) { int intent = getLcmsIntent(rendering_intent); - _revTransf = cmsCreateTransform( getSRGBProfile(), TYPE_BGRA_8, profHandle, _getInputFormat(_profileSpace), intent, 0 ); + impl->_revTransf = cmsCreateTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, impl->_profHandle, ColorProfileImpl::_getInputFormat(impl->_profileSpace), intent, 0 ); } - return _revTransf; + return impl->_revTransf; } cmsHTRANSFORM ColorProfile::getTransfGamutCheck() { - if ( !_gamutTransf ) { - _gamutTransf = cmsCreateProofingTransform(getSRGBProfile(), TYPE_BGRA_8, getNULLProfile(), TYPE_GRAY_8, profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); + if ( !impl->_gamutTransf ) { + impl->_gamutTransf = cmsCreateProofingTransform(ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, ColorProfileImpl::getNULLProfile(), TYPE_GRAY_8, impl->_profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); } - return _gamutTransf; + return impl->_gamutTransf; } bool ColorProfile::GamutCheck(SPColor color){ BYTE outofgamut = 0; - + guint32 val = color.toRGBA32(0); guchar check_color[4] = { SP_RGBA32_R_U(val), @@ -586,7 +635,7 @@ static std::vector knownProfiles; std::vector Inkscape::colorprofile_get_display_names() { - colorprofile_load_profiles(); + loadProfiles(); std::vector result; for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -600,7 +649,7 @@ std::vector Inkscape::colorprofile_get_display_names() std::vector Inkscape::colorprofile_get_softproof_names() { - colorprofile_load_profiles(); + loadProfiles(); std::vector result; for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -614,7 +663,7 @@ std::vector Inkscape::colorprofile_get_softproof_names() Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) { - colorprofile_load_profiles(); + loadProfiles(); Glib::ustring result; for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -628,7 +677,7 @@ Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) } #endif // ENABLE_LCMS -std::list ColorProfile::getBaseProfileDirs() { +std::vector ColorProfile::getBaseProfileDirs() { #if ENABLE_LCMS static bool warnSet = false; if (!warnSet) { @@ -636,7 +685,7 @@ std::list ColorProfile::getBaseProfileDirs() { warnSet = true; } #endif // ENABLE_LCMS - std::list sources; + std::vector sources; gchar* base = profile_path("XXX"); { @@ -662,10 +711,10 @@ std::list ColorProfile::getBaseProfileDirs() { // On OS X: { bool onOSX = false; - std::list possible; + std::vector possible; possible.push_back("/System/Library/ColorSync/Profiles"); possible.push_back("/Library/ColorSync/Profiles"); - for ( std::list::const_iterator it = possible.begin(); it != possible.end(); ++it ) { + for ( std::vector::const_iterator it = possible.begin(); it != possible.end(); ++it ) { if ( g_file_test(it->c_str(), G_FILE_TEST_EXISTS) && g_file_test(it->c_str(), G_FILE_TEST_IS_DIR) ) { sources.push_back(it->c_str()); onOSX = true; @@ -738,11 +787,15 @@ static bool isIccFile( gchar const *filepath ) return isIccFile; } -std::list ColorProfile::getProfileFiles() +std::vector ColorProfile::getProfileFiles() { - std::list files; + std::vector files; - std::list sources = ColorProfile::getBaseProfileDirs(); + std::list sources; + { + std::vector tmp = ColorProfile::getBaseProfileDirs(); + sources.insert(sources.begin(), tmp.begin(), tmp.end()); + } for ( std::list::const_iterator it = sources.begin(); it != sources.end(); ++it ) { if ( g_file_test( it->c_str(), G_FILE_TEST_EXISTS ) && g_file_test( it->c_str(), G_FILE_TEST_IS_DIR ) ) { GError *err = 0; @@ -775,7 +828,28 @@ std::list ColorProfile::getProfileFiles() } #if ENABLE_LCMS +#endif // ENABLE_LCMS + +std::vector > ColorProfile::getProfileFilesWithNames() +{ + std::vector > result; + +#if ENABLE_LCMS + std::vector files = getProfileFiles(); + for ( std::vector::const_iterator it = files.begin(); it != files.end(); ++it ) { + cmsHPROFILE hProfile = cmsOpenProfileFromFile(it->c_str(), "r"); + if ( hProfile ) { + Glib::ustring name = getNameFromProfile(hProfile); + result.push_back( std::make_pair(*it, name) ); + cmsCloseProfile(hProfile); + } + } +#endif // ENABLE_LCMS + + return result; +} +#if ENABLE_LCMS int errorHandlerCB(int ErrorCode, const char *ErrorText) { g_message("lcms: Error %d; %s", ErrorCode, ErrorText); @@ -783,9 +857,28 @@ int errorHandlerCB(int ErrorCode, const char *ErrorText) return 1; } -/* This function loads or refreshes data in knownProfiles. - * Call it at the start of every call that requires this data. */ -void Inkscape::colorprofile_load_profiles(bool force_refresh) +namespace +{ +Glib::ustring getNameFromProfile(cmsHPROFILE profile) +{ + gchar const *name = 0; + if ( profile ) { + name = cmsTakeProductDesc(profile); + if ( !name ) { + name = cmsTakeProductName(profile); + } + if ( name && !g_utf8_validate(name, -1, NULL) ) { + name = _("(invalid UTF-8 string)"); + } + } + return (name) ? name : _("None"); +} + +/** + * This function loads or refreshes data in knownProfiles. + * Call it at the start of every call that requires this data. + */ +void loadProfiles() { static bool error_handler_set = false; if (!error_handler_set) { @@ -794,32 +887,34 @@ void Inkscape::colorprofile_load_profiles(bool force_refresh) } static bool profiles_searched = false; - if (profiles_searched && !force_refresh) return; + if ( !profiles_searched ) { + knownProfiles.clear(); + std::vector files = ColorProfile::getProfileFiles(); - knownProfiles.clear(); - std::list files = ColorProfile::getProfileFiles(); - - for ( std::list::const_iterator it = files.begin(); it != files.end(); ++it ) { - cmsHPROFILE prof = cmsOpenProfileFromFile( it->c_str(), "r" ); - if ( prof ) { - ProfileInfo info( prof, Glib::filename_to_utf8( it->c_str() ) ); - cmsCloseProfile( prof ); - - bool sameName = false; - for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { - if ( it->getName() == info.getName() ) { - sameName = true; - break; + for ( std::vector::const_iterator it = files.begin(); it != files.end(); ++it ) { + cmsHPROFILE prof = cmsOpenProfileFromFile( it->c_str(), "r" ); + if ( prof ) { + ProfileInfo info( prof, Glib::filename_to_utf8( it->c_str() ) ); + cmsCloseProfile( prof ); + prof = 0; + + bool sameName = false; + for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { + if ( it->getName() == info.getName() ) { + sameName = true; + break; + } } - } - if ( !sameName ) { - knownProfiles.push_back(info); + if ( !sameName ) { + knownProfiles.push_back(info); + } } } + profiles_searched = true; } - profiles_searched = true; } +} // namespace static bool gamutWarn = false; static Gdk::Color lastGamutColor("#808080"); @@ -831,12 +926,13 @@ static int lastIntent = INTENT_PERCEPTUAL; static int lastProofIntent = INTENT_PERCEPTUAL; static cmsHTRANSFORM transf = 0; -cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() +namespace { +cmsHPROFILE getSystemProfileHandle() { static cmsHPROFILE theOne = 0; static Glib::ustring lastURI; - colorprofile_load_profiles(); + loadProfiles(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring uri = prefs->getString("/options/displayprofile/uri"); @@ -884,12 +980,12 @@ cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() } -cmsHPROFILE Inkscape::colorprofile_get_proof_profile_handle() +cmsHPROFILE getProofProfileHandle() { static cmsHPROFILE theOne = 0; static Glib::ustring lastURI; - colorprofile_load_profiles(); + loadProfiles(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool which = prefs->getBool( "/options/softproof/enable"); @@ -942,6 +1038,7 @@ cmsHPROFILE Inkscape::colorprofile_get_proof_profile_handle() return theOne; } +} // namespace static void free_transforms(); @@ -988,8 +1085,8 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() } // Fetch these now, as they might clear the transform as a side effect. - cmsHPROFILE hprof = Inkscape::colorprofile_get_system_profile_handle(); - cmsHPROFILE proofProf = hprof ? Inkscape::colorprofile_get_proof_profile_handle() : 0; + cmsHPROFILE hprof = getSystemProfileHandle(); + cmsHPROFILE proofProf = hprof ? getProofProfileHandle() : 0; if ( !transf ) { if ( hprof && proofProf ) { @@ -1006,9 +1103,9 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() dwFlags |= cmsFLAGS_PRESERVEBLACK; } #endif // defined(cmsFLAGS_PRESERVEBLACK) - transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); + transf = cmsCreateProofingTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); } else if ( hprof ) { - transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, intent, 0 ); + transf = cmsCreateTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, intent, 0 ); } } @@ -1149,7 +1246,7 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) } // Fetch these now, as they might clear the transform as a side effect. - cmsHPROFILE proofProf = item.hprof ? Inkscape::colorprofile_get_proof_profile_handle() : 0; + cmsHPROFILE proofProf = item.hprof ? getProofProfileHandle() : 0; if ( !item.transf ) { if ( item.hprof && proofProf ) { @@ -1166,9 +1263,9 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) dwFlags |= cmsFLAGS_PRESERVEBLACK; } #endif // defined(cmsFLAGS_PRESERVEBLACK) - item.transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); + item.transf = cmsCreateProofingTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); } else if ( item.hprof ) { - item.transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, intent, 0 ); + item.transf = cmsCreateTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, intent, 0 ); } } diff --git a/src/color-profile.h b/src/color-profile.h index e1dd298bd..a1b83bbef 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -23,6 +23,8 @@ enum { RENDERING_INTENT_ABSOLUTE_COLORIMETRIC = 5 }; +class ColorProfileImpl; + /// The SPColorProfile vtable. struct ColorProfileClass { SPObjectClass parent_class; @@ -30,17 +32,17 @@ struct ColorProfileClass { /** Color Profile. */ struct ColorProfile : public SPObject { + friend cmsHPROFILE colorprofile_get_handle( SPDocument*, guint*, gchar const* ); + static GType getType(); static void classInit( ColorProfileClass *klass ); - static std::list getBaseProfileDirs(); - static std::list getProfileFiles(); + static std::vector getBaseProfileDirs(); + static std::vector getProfileFiles(); + static std::vector > getProfileFilesWithNames(); #if ENABLE_LCMS - static cmsHPROFILE getSRGBProfile(); - static cmsHPROFILE getNULLProfile(); - - icColorSpaceSignature getColorSpace() const {return _profileSpace;} - icProfileClassSignature getProfileClass() const {return _profileClass;} + icColorSpaceSignature getColorSpace() const; + icProfileClassSignature getProfileClass() const; cmsHTRANSFORM getTransfToSRGB8(); cmsHTRANSFORM getTransfFromSRGB8(); cmsHTRANSFORM getTransfGamutCheck(); @@ -53,9 +55,6 @@ struct ColorProfile : public SPObject { gchar* name; gchar* intentStr; guint rendering_intent; -#if ENABLE_LCMS - cmsHPROFILE profHandle; -#endif // ENABLE_LCMS private: static void init( ColorProfile *cprof ); @@ -64,19 +63,8 @@ private: static void build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ); static void set( SPObject *object, unsigned key, gchar const *value ); static Inkscape::XML::Node *write( SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags ); -#if ENABLE_LCMS - static DWORD _getInputFormat( icColorSpaceSignature space ); - void _clearProfile(); - static cmsHPROFILE _sRGBProf; - static cmsHPROFILE _NullProf; - - icProfileClassSignature _profileClass; - icColorSpaceSignature _profileSpace; - cmsHTRANSFORM _transf; - cmsHTRANSFORM _revTransf; - cmsHTRANSFORM _gamutTransf; -#endif // ENABLE_LCMS + ColorProfileImpl *impl; }; } // namespace Inkscape diff --git a/src/interface.cpp b/src/interface.cpp index c7946cf18..9aa5cad31 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -56,10 +56,6 @@ #include "message-context.h" #include "ui/uxmanager.h" -// Added for color drag-n-drop -#if ENABLE_LCMS -#include "lcms.h" -#endif // ENABLE_LCMS #include "display/sp-canvas.h" #include "color.h" #include "svg/svg-color.h" diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 569dd2311..5d32839cb 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -43,8 +43,6 @@ #include "xml/repr.h" #if ENABLE_LCMS -#include -//#include "color-profile-fns.h" #include "color-profile.h" #endif // ENABLE_LCMS @@ -309,53 +307,29 @@ DocumentProperties::build_snap() } #if ENABLE_LCMS -static void -lcms_profile_get_name (cmsHPROFILE profile, const gchar **name) -{ - if (profile) - { - *name = cmsTakeProductDesc (profile); - - if (! *name) - *name = cmsTakeProductName (profile); - - if (*name && ! g_utf8_validate (*name, -1, NULL)) - *name = _("(invalid UTF-8 string)"); - } - else - { - *name = _("None"); - } -} - -void -DocumentProperties::populate_available_profiles(){ +void DocumentProperties::populate_available_profiles(){ Glib::ListHandle children = _menu.get_children(); for ( Glib::ListHandle::iterator it2 = children.begin(); it2 != children.end(); ++it2 ) { _menu.remove(**it2); delete(*it2); } - std::list files = ColorProfile::getProfileFiles(); - for ( std::list::const_iterator it = files.begin(); it != files.end(); ++it ) { - cmsHPROFILE hProfile = cmsOpenProfileFromFile(it->c_str(), "r"); - if ( hProfile ){ - const gchar* name = 0; - lcms_profile_get_name(hProfile, &name); - Gtk::MenuItem* mi = manage(new Gtk::MenuItem()); - mi->set_data("filepath", g_strdup(it->c_str())); - mi->set_data("name", g_strdup(name)); - Gtk::HBox *hbox = manage(new Gtk::HBox()); - hbox->show(); - Gtk::Label* lbl = manage(new Gtk::Label(name)); - lbl->show(); - hbox->pack_start(*lbl, true, true, 0); - mi->add(*hbox); - mi->show_all(); - _menu.append(*mi); -// g_free((void*)name); - cmsCloseProfile(hProfile); - } + std::vector > pairs = ColorProfile::getProfileFilesWithNames(); + for ( std::vector >::const_iterator it = pairs.begin(); it != pairs.end(); ++it ) { + Glib::ustring file = it->first; + Glib::ustring name = it->second; + + Gtk::MenuItem* mi = manage(new Gtk::MenuItem()); + mi->set_data("filepath", g_strdup(file.c_str())); + mi->set_data("name", g_strdup(name.c_str())); + Gtk::HBox *hbox = manage(new Gtk::HBox()); + hbox->show(); + Gtk::Label* lbl = manage(new Gtk::Label(name)); + lbl->show(); + hbox->pack_start(*lbl, true, true, 0); + mi->add(*hbox); + mi->show_all(); + _menu.append(*mi); } _menu.show_all(); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 3c272e691..aa3c18aaa 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -906,8 +906,8 @@ void InkscapePreferences::initPageCMS() _page_cms.add_group_header( _("Display adjustment")); Glib::ustring tmpStr; - std::list sources = ColorProfile::getBaseProfileDirs(); - for ( std::list::const_iterator it = sources.begin(); it != sources.end(); ++it ) { + std::vector sources = ColorProfile::getBaseProfileDirs(); + for ( std::vector::const_iterator it = sources.begin(); it != sources.end(); ++it ) { gchar* part = g_strdup_printf( "\n%s", it->c_str() ); tmpStr += part; g_free(part); diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h index 9238e3f68..a3915cd48 100644 --- a/src/widgets/sp-color-icc-selector.h +++ b/src/widgets/sp-color-icc-selector.h @@ -8,11 +8,9 @@ #include "sp-color-slider.h" #include "sp-color-selector.h" -#if ENABLE_LCMS -#include "color-profile.h" -#endif // ENABLE_LCMS - - +namespace Inkscape { +struct ColorProfile; +} struct SPColorICCSelector; struct SPColorICCSelectorClass; diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 377abf219..d041f85df 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -37,6 +37,7 @@ #include "../inkscape.h" #include "../document.h" #include "../profile-manager.h" +#include "color-profile.h" struct SPColorNotebookTracker { const gchar* name; @@ -529,7 +530,7 @@ void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) if (color.icc){ Inkscape::ColorProfile* target_profile = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); if ( target_profile ) - gtk_widget_set_sensitive (_box_outofgamut, target_profile->GamutCheck(color)); + gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color)); } /* update too-much-ink icon */ -- cgit v1.2.3 From aa7a997188b7f69017897a93bd153048df6b1dbc Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 6 Jul 2011 22:59:33 +0200 Subject: Fix mixed up colors when exporting images with bitmaps to PDF and other Cairo formats. Fixes LP #804311 Fixed bugs: - https://launchpad.net/bugs/804311 (bzr r10421) --- src/extension/internal/cairo-render-context.cpp | 65 +++---------------------- src/extension/internal/cairo-render-context.h | 2 +- src/extension/internal/cairo-renderer.cpp | 16 +++--- 3 files changed, 14 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 1c1dac028..22b68b0ca 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1419,7 +1419,7 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con return true; } -bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsigned int rs, +bool CairoRenderContext::renderImage(GdkPixbuf *pb, Geom::Affine const *image_transform, SPStyle const * /*style*/) { g_assert( _is_valid ); @@ -1428,63 +1428,18 @@ bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, return true; } - guchar* px_rgba = NULL; - guint64 size = 4L * (guint64)w * (guint64)h; + int w = gdk_pixbuf_get_width (pb); + int h = gdk_pixbuf_get_height (pb); - if(size < (guint64)G_MAXSIZE) { - px_rgba = (guchar*)g_try_malloc(4 * w * h); - if (!px_rgba) { - g_warning ("Could not allocate %lu bytes for pixel buffer!", (long unsigned) size); - return false; - } - } else { - g_warning ("the requested memory exceeds the system limit"); - return false; - } - - - float opacity; - if (_state->merge_opacity) - opacity = _state->opacity; - else - opacity = 1.0; - - // make a copy of the original pixbuf with premultiplied alpha - // if we pass the original pixbuf it will get messed up - /// @todo optimize this code, it costs a lot of time - for (unsigned i = 0; i < h; i++) { - guchar const *src = px + i * rs; - guint32 *dst = (guint32 *)(px_rgba + i * rs); - for (unsigned j = 0; j < w; j++) { - guchar r, g, b, alpha_dst; - - // calculate opacity-modified alpha - alpha_dst = src[3]; - if ((opacity != 1.0) && _vector_based_target) - alpha_dst = (guchar)ceil((float)alpha_dst * opacity); - - // premul alpha (needed because this will be undone by cairo-pdf) - r = src[0]*alpha_dst/255; - g = src[1]*alpha_dst/255; - b = src[2]*alpha_dst/255; - - *dst = (((alpha_dst) << 24) | (((r)) << 16) | (((g)) << 8) | (b)); - - dst++; // pointer to 4byte variables - src += 4; // pointer to 1byte variables - } - } + // TODO: reenable merge_opacity if useful + float opacity = _state->opacity; - cairo_surface_t *image_surface = cairo_image_surface_create_for_data(px_rgba, CAIRO_FORMAT_ARGB32, w, h, w * 4); + cairo_surface_t *image_surface = ink_cairo_surface_create_for_argb32_pixbuf(pb); if (cairo_surface_status(image_surface)) { TRACE(("Image surface creation failed:\n%s\n", cairo_status_to_string(cairo_surface_status(image_surface)))); return false; } - // setup automatic freeing of the image data when destroying the surface - static cairo_user_data_key_t key; - cairo_surface_set_user_data(image_surface, &key, px_rgba, (cairo_destroy_func_t)g_free); - cairo_save(_cr); // scaling by width & height is not needed because it will be done by Cairo @@ -1499,16 +1454,10 @@ bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, cairo_rectangle(_cr, 0, 0, w, h); cairo_clip(_cr); } - - if (_vector_based_target) - cairo_paint(_cr); - else - cairo_paint_with_alpha(_cr, opacity); + cairo_paint_with_alpha(_cr, opacity); cairo_restore(_cr); - cairo_surface_destroy(image_surface); - return true; } diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 68a3c6537..d4117ff7e 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -139,7 +139,7 @@ public: /* Rendering methods */ bool renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, NRRect const *pbox); - bool renderImage(unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, + bool renderImage(GdkPixbuf *pb, Geom::Affine const *image_transform, SPStyle const *style); bool renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix, std::vector const &glyphtext, SPStyle const *style); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index bbafd7e94..6118a7ae9 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -41,6 +41,7 @@ #include "display/nr-arena-group.h" #include "display/curve.h" #include "display/canvas-bpath.h" +#include "display/cairo-utils.h" #include "sp-item.h" #include "sp-item-group.h" #include "style.h" @@ -345,18 +346,15 @@ static void sp_flowtext_render(SPItem *item, CairoRenderContext *ctx) static void sp_image_render(SPItem *item, CairoRenderContext *ctx) { SPImage *image; - guchar *px; - int w, h, rs; + int w, h; image = SP_IMAGE (item); if (!image->pixbuf) return; if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) return; - px = gdk_pixbuf_get_pixels (image->pixbuf); w = gdk_pixbuf_get_width (image->pixbuf); h = gdk_pixbuf_get_height (image->pixbuf); - rs = gdk_pixbuf_get_rowstride (image->pixbuf); double x = image->x.computed; double y = image->y.computed; @@ -376,7 +374,7 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx) Geom::Scale s(width / (double)w, height / (double)h); Geom::Affine t(s * tp); - ctx->renderImage (px, w, h, rs, &t, item->style); + ctx->renderImage (image->pixbuf, &t, item->style); } static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx) @@ -516,11 +514,9 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) if (pb) { TEST(gdk_pixbuf_save( pb, "bitmap.png", "png", NULL, NULL )); - unsigned char *px = gdk_pixbuf_get_pixels (pb); - unsigned int w = gdk_pixbuf_get_width(pb); - unsigned int h = gdk_pixbuf_get_height(pb); - unsigned int rs = gdk_pixbuf_get_rowstride(pb); - ctx->renderImage(px, w, h, rs, &t, item->style); + // TODO this is stupid - we just converted to pixbuf format when generating the bitmap! + convert_pixbuf_normal_to_argb32(pb); + ctx->renderImage(pb, &t, item->style); gdk_pixbuf_unref(pb); pb = 0; } -- cgit v1.2.3 From 83a4acd5c2c92c42d9ae1d60bccffb4f9f39886d Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 6 Jul 2011 23:13:12 +0200 Subject: Fix outline mode for text objects (LP #802354). Fixed bugs: - https://launchpad.net/bugs/802354 (bzr r10422) --- src/display/nr-arena-glyphs.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index dbac07596..089d6de40 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -294,26 +294,26 @@ static unsigned int nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, } if (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE) { - + cairo_save(ct); guint32 rgba = item->arena->outlinecolor; ink_cairo_set_source_rgba32(ct, rgba); cairo_set_tolerance(ct, 1.25); // low quality, but good enough for outline mode - - NRRect temp(area->x0, area->y0, area->x1, area->y1); - Geom::OptRect area_2geom = temp.upgrade_2geom(); + cairo_new_path(ct); + ink_cairo_transform(ct, ggroup->ctm); for (child = group->children; child != NULL; child = child->next) { NRArenaGlyphs *g = NR_ARENA_GLYPHS(child); Geom::PathVector const * pathv = g->font->PathVector(g->glyph); - Geom::Affine transform = g->g_transform * group->ctm; + Geom::Affine transform = g->g_transform; - cairo_new_path(ct); + cairo_save(ct); ink_cairo_transform(ct, transform); feed_pathvector_to_cairo (ct, *pathv); cairo_fill(ct); + cairo_restore(ct); } - + cairo_restore(ct); return item->state; } -- cgit v1.2.3 From dd472649acce56329d8d5a6f26b0319828f39a2c Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 6 Jul 2011 23:47:14 +0200 Subject: Fix regression in swatch display (LP #804930). Fixed bugs: - https://launchpad.net/bugs/804930 (bzr r10423) --- src/ui/dialog/color-item.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 89245575c..3463aa496 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -517,11 +517,13 @@ void ColorItem::_regenPreview(EekPreview * preview) (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB() ); } else { - double w; - cairo_pattern_get_linear_points(_pattern, NULL, NULL, &w, NULL); - int width = ceil(w); + // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp + // TODO: the pattern to draw should be in the widget that draws the preview, + // so the preview can be scalable + int w = 128; + int h = 16; - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, 1); + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); cairo_t *ct = cairo_create(s); cairo_set_source(ct, _pattern); cairo_paint(ct); @@ -530,7 +532,7 @@ void ColorItem::_regenPreview(EekPreview * preview) GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, - width, 1, cairo_image_surface_get_stride(s), + w, h, cairo_image_surface_get_stride(s), (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); convert_pixbuf_argb32_to_normal(pixbuf); eek_preview_set_pixbuf( preview, pixbuf ); -- cgit v1.2.3 From 262ed2816e1faa073e8ca16b7d474100c8a9cf4f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 8 Jul 2011 04:15:46 +0000 Subject: fix for building without LCMS (bzr r10425) --- src/color-profile.cpp | 5 ++++- src/color-profile.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 7c9e83e3c..c2267d827 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -103,8 +103,10 @@ static SPObjectClass *cprof_parent_class; class ColorProfileImpl { public: +#if ENABLE_LCMS static cmsHPROFILE _sRGBProf; static cmsHPROFILE _NullProf; +#endif // ENABLE_LCMS ColorProfileImpl(); @@ -125,8 +127,9 @@ public: #endif // ENABLE_LCMS }; -ColorProfileImpl::ColorProfileImpl() : +ColorProfileImpl::ColorProfileImpl() #if ENABLE_LCMS + : _profHandle(0), _profileClass(icSigInputClass), _profileSpace(icSigRgbData), diff --git a/src/color-profile.h b/src/color-profile.h index a1b83bbef..28096cd20 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -32,8 +32,9 @@ struct ColorProfileClass { /** Color Profile. */ struct ColorProfile : public SPObject { +#if ENABLE_LCMS friend cmsHPROFILE colorprofile_get_handle( SPDocument*, guint*, gchar const* ); - +#endif // ENABLE_LCMS static GType getType(); static void classInit( ColorProfileClass *klass ); -- cgit v1.2.3 From 6844f54c33f5783d6ca3cf065748bec84203b171 Mon Sep 17 00:00:00 2001 From: Felipe Corr??a da Silva Sanches Date: Fri, 8 Jul 2011 16:22:58 -0300 Subject: auto-maximize the inkscape extension error dialog so that it is easier to read the error log (bzr r10427) --- src/extension/implementation/script.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 2f3e2cd65..e7599d996 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -855,6 +855,7 @@ void Script::checkStderr (const Glib::ustring &data, vbox->pack_start(*scrollwindow, true, true, 5 /* fix these */); + warning.maximize(); warning.run(); return; -- cgit v1.2.3 From 2994e0b96e7d5d6d198b3d8139e4134f9d454229 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 9 Jul 2011 02:18:40 -0700 Subject: Next step in refactoring color management. More to come. (bzr r10429) --- src/CMakeLists.txt | 2 ++ src/Makefile_insert | 3 +- src/cms-color-types.h | 58 +++++++++++++++++++++++++++++++++++ src/color-profile-cms-fns.h | 51 ++++++++++++++++++++++++++++++ src/color-profile-fns.h | 16 ++++------ src/color-profile.cpp | 42 ++++++++++++++++++++++--- src/color-profile.h | 23 +++++++++----- src/display/sp-canvas.cpp | 2 +- src/sp-image.cpp | 1 + src/sp-object-repr.cpp | 2 +- src/sp-object.cpp | 2 +- src/svg/svg-color.cpp | 10 ++++-- src/widgets/sp-color-icc-selector.cpp | 11 ++++--- src/widgets/sp-color-notebook.cpp | 9 ++++-- 14 files changed, 195 insertions(+), 37 deletions(-) create mode 100644 src/cms-color-types.h create mode 100644 src/color-profile-cms-fns.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 580d65b0c..11a307037 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -306,7 +306,9 @@ set(inkscape_SRC box3d-context.h box3d-side.h box3d.h + cms-color-types.h color-profile-fns.h + color-profile-cms-fns.h color-profile-test.h color-profile.h color-rgba.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 7d48dba93..d4f96fc87 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -12,9 +12,10 @@ ink_common_sources += \ box3d.cpp box3d.h \ box3d-side.cpp box3d-side.h \ brokenimage.xpm \ + cms-color-types.h \ color.cpp color.h \ color-profile.cpp color-profile.h \ - color-profile-fns.h \ + color-profile-fns.h color-profile-cms-fns.h \ color-rgba.h \ common-context.cpp common-context.h \ composite-undo-stack-observer.cpp \ diff --git a/src/cms-color-types.h b/src/cms-color-types.h new file mode 100644 index 000000000..74fdac12c --- /dev/null +++ b/src/cms-color-types.h @@ -0,0 +1,58 @@ +#ifndef SEEN_CMS_COLOR_TYPES_H +#define SEEN_CMS_COLOR_TYPES_H + +/** \file + * A simple abstraction to provide opaque compatibility with either lcms or lcms2. + */ + +#include + + +typedef void * cmsHPROFILE; +typedef void * cmsHTRANSFORM; + +namespace Inkscape { + +/** + * Opaque holder of a 32-bit signature type. + */ +class FourCCSig { +public: + FourCCSig( FourCCSig const &other ) : value(other.value) {}; + +protected: + FourCCSig( guint32 value ) : value(value) {}; + + guint32 value; +}; + +class ColorSpaceSig : public FourCCSig { +public: + ColorSpaceSig( ColorSpaceSig const &other ) : FourCCSig(other) {}; + +protected: + ColorSpaceSig( guint32 value ) : FourCCSig(value) {}; +}; + +class ColorProfileClassSig : public FourCCSig { +public: + ColorProfileClassSig( ColorProfileClassSig const &other ) : FourCCSig(other) {}; + +protected: + ColorProfileClassSig( guint32 value ) : FourCCSig(value) {}; +}; + +} // namespace Inkscape + +#endif // SEEN_CMS_COLOR_TYPES_H + +/* + 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/color-profile-cms-fns.h b/src/color-profile-cms-fns.h new file mode 100644 index 000000000..fe0eed392 --- /dev/null +++ b/src/color-profile-cms-fns.h @@ -0,0 +1,51 @@ +#ifndef SEEN_COLOR_PROFILE_CMS_FNS_H +#define SEEN_COLOR_PROFILE_CMS_FNS_H + +#if ENABLE_LCMS +#include +#endif // ENABLE_LCMS + +#include "cms-color-types.h" + +namespace Inkscape { + +#if ENABLE_LCMS + +// Note: these can later be adjusted to adapt for lcms2: + +class ColorSpaceSigWrapper : public ColorSpaceSig { +public : + ColorSpaceSigWrapper( icColorSpaceSignature sig ) : ColorSpaceSig( static_cast(sig) ) {} + ColorSpaceSigWrapper( ColorSpaceSig const &other ) : ColorSpaceSig( other ) {} + + operator icColorSpaceSignature() const { return static_cast(value); } +}; + +class ColorProfileClassSigWrapper : public ColorProfileClassSig { +public : + ColorProfileClassSigWrapper( icProfileClassSignature sig ) : ColorProfileClassSig( static_cast(sig) ) {} + ColorProfileClassSigWrapper( ColorProfileClassSig const &other ) : ColorProfileClassSig( other ) {} + + operator icProfileClassSignature() const { return static_cast(value); } +}; + +icColorSpaceSignature asICColorSpaceSig(ColorSpaceSig const & sig); +icProfileClassSignature asICColorProfileClassSig(ColorProfileClassSig const & sig); + +#endif // ENABLE_LCMS + +} // namespace Inkscape + + +#endif // !SEEN_COLOR_PROFILE_CMS_FNS_H + +/* + 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/color-profile-fns.h b/src/color-profile-fns.h index 3d22417f6..0588ce89e 100644 --- a/src/color-profile-fns.h +++ b/src/color-profile-fns.h @@ -10,8 +10,8 @@ #if ENABLE_LCMS #include #include -#include #endif // ENABLE_LCMS +#include "cms-color-types.h" class SPDocument; @@ -23,8 +23,6 @@ class Node; class ColorProfile; -GType colorprofile_get_type(); - #if ENABLE_LCMS cmsHPROFILE colorprofile_get_handle( SPDocument* document, guint* intent, gchar const* name ); @@ -39,15 +37,13 @@ std::vector colorprofile_get_softproof_names(); Glib::ustring get_path_for_profile(Glib::ustring const& name); -#endif +void colorprofile_cmsDoTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size); -} // namespace Inkscape +bool colorprofile_isPrintColorSpace(ColorProfile const *profile); -#define COLORPROFILE_TYPE (Inkscape::colorprofile_get_type()) -#define COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), COLORPROFILE_TYPE, Inkscape::ColorProfile)) -#define COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), COLORPROFILE_TYPE, Inkscape::ColorProfileClass)) -#define IS_COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), COLORPROFILE_TYPE)) -#define IS_COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), COLORPROFILE_TYPE)) +#endif // ENABLE_LCMS + +} // namespace Inkscape #endif // !SEEN_COLOR_PROFILE_FNS_H diff --git a/src/color-profile.cpp b/src/color-profile.cpp index c2267d827..4bc37fdf8 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -32,6 +32,7 @@ #include "color.h" #include "color-profile.h" #include "color-profile-fns.h" +#include "color-profile-cms-fns.h" #include "attributes.h" #include "inkscape.h" #include "document.h" @@ -100,7 +101,6 @@ extern guint update_in_progress; static SPObjectClass *cprof_parent_class; - class ColorProfileImpl { public: #if ENABLE_LCMS @@ -127,6 +127,22 @@ public: #endif // ENABLE_LCMS }; + + +namespace Inkscape { + +icColorSpaceSignature asICColorSpaceSig(ColorSpaceSig const & sig) +{ + return ColorSpaceSigWrapper(sig); +} + +icProfileClassSignature asICColorProfileClassSig(ColorProfileClassSig const & sig) +{ + return ColorProfileClassSigWrapper(sig); +} + +} // namespace Inkscape + ColorProfileImpl::ColorProfileImpl() #if ENABLE_LCMS : @@ -554,12 +570,12 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* inte return prof; } -icColorSpaceSignature ColorProfile::getColorSpace() const { - return impl->_profileSpace; +Inkscape::ColorSpaceSig ColorProfile::getColorSpace() const { + return ColorSpaceSigWrapper(impl->_profileSpace); } -icProfileClassSignature ColorProfile::getProfileClass() const { - return impl->_profileClass; +Inkscape::ColorProfileClassSig ColorProfile::getProfileClass() const { + return ColorProfileClassSigWrapper(impl->_profileClass); } cmsHTRANSFORM ColorProfile::getTransfToSRGB8() @@ -678,6 +694,22 @@ Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) return result; } + +void Inkscape::colorprofile_cmsDoTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size) +{ + cmsDoTransform(transform, inBuf, outBuf, size); +} + +bool Inkscape::colorprofile_isPrintColorSpace(ColorProfile const *profile) +{ + bool isPrint = false; + if ( profile ) { + ColorSpaceSigWrapper colorspace = profile->getColorSpace(); + isPrint = (colorspace == icSigCmykData) || (colorspace == icSigCmyData); + } + return isPrint; +} + #endif // ENABLE_LCMS std::vector ColorProfile::getBaseProfileDirs() { diff --git a/src/color-profile.h b/src/color-profile.h index 28096cd20..1b06b6a78 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -5,12 +5,11 @@ * SPColorProfile: SVG implementation */ +#include #include #include #include -#if ENABLE_LCMS -#include -#endif // ENABLE_LCMS +#include "cms-color-types.h" namespace Inkscape { @@ -25,6 +24,7 @@ enum { class ColorProfileImpl; + /// The SPColorProfile vtable. struct ColorProfileClass { SPObjectClass parent_class; @@ -32,9 +32,8 @@ struct ColorProfileClass { /** Color Profile. */ struct ColorProfile : public SPObject { -#if ENABLE_LCMS friend cmsHPROFILE colorprofile_get_handle( SPDocument*, guint*, gchar const* ); -#endif // ENABLE_LCMS + static GType getType(); static void classInit( ColorProfileClass *klass ); @@ -42,8 +41,10 @@ struct ColorProfile : public SPObject { static std::vector getProfileFiles(); static std::vector > getProfileFilesWithNames(); #if ENABLE_LCMS - icColorSpaceSignature getColorSpace() const; - icProfileClassSignature getProfileClass() const; + //icColorSpaceSignature getColorSpace() const; + ColorSpaceSig getColorSpace() const; + //icProfileClassSignature getProfileClass() const; + ColorProfileClassSig getProfileClass() const; cmsHTRANSFORM getTransfToSRGB8(); cmsHTRANSFORM getTransfFromSRGB8(); cmsHTRANSFORM getTransfGamutCheck(); @@ -68,8 +69,16 @@ private: ColorProfileImpl *impl; }; +GType colorprofile_get_type(); + } // namespace Inkscape +#define COLORPROFILE_TYPE (Inkscape::colorprofile_get_type()) +#define COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), COLORPROFILE_TYPE, Inkscape::ColorProfile)) +#define COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), COLORPROFILE_TYPE, Inkscape::ColorProfileClass)) +#define IS_COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), COLORPROFILE_TYPE)) +#define IS_COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), COLORPROFILE_TYPE)) + #endif // !SEEN_COLOR_PROFILE_H /* diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 3e8a4880c..ea39d3435 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1683,7 +1683,7 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int int stride = cairo_image_surface_get_stride(imgs); for (int i=0; icolorProfile.c_str()); gchar const** names = 0; gchar const** tips = 0; guint const* scales = 0; - getThings( prof->getColorSpace(), names, tips, scales ); + getThings( asICColorSpaceSig(prof->getColorSpace()), names, tips, scales ); - guint count = _cmsChannelsOf( prof->getColorSpace() ); - if (count>4) count=4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?) + guint count = _cmsChannelsOf( asICColorSpaceSig(prof->getColorSpace()) ); + if (count > 4) { + count = 4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?) + } for (guint i=0;icolors[i])*256.0) * (gdouble)scales[i]); g_message("input[%d]: %d",i, color_in[i]); diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index 94f450e50..9e5291cc4 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -16,6 +16,7 @@ #if ENABLE_LCMS #include "color-profile-fns.h" +#include "color-profile-cms-fns.h" #include "color-profile.h" #ifdef DEBUG_LCMS @@ -497,12 +498,12 @@ void ColorICCSelector::_switchToProfile( gchar const* name ) #ifdef DEBUG_LCMS g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]); #endif // DEBUG_LCMS - guint count = _cmsChannelsOf( newProf->getColorSpace() ); + guint count = _cmsChannelsOf( asICColorSpaceSig(newProf->getColorSpace()) ); gchar const** names = 0; gchar const** tips = 0; guint const* scales = 0; - getThings( newProf->getColorSpace(), names, tips, scales ); + getThings( asICColorSpaceSig(newProf->getColorSpace()), names, tips, scales ); for ( guint i = 0; i < count; i++ ) { gdouble val = (((gdouble)post[i])/65535.0) * (gdouble)scales[i]; @@ -680,12 +681,12 @@ void ColorICCSelector::_setProfile( SVGICCColor* profile ) if ( profile ) { _prof = SP_ACTIVE_DOCUMENT->profileManager->find(profile->colorProfile.c_str()); - if ( _prof && _prof->getProfileClass() != icSigNamedColorClass ) { - _profChannelCount = _cmsChannelsOf( _prof->getColorSpace() ); + if ( _prof && (asICColorProfileClassSig(_prof->getProfileClass()) != icSigNamedColorClass) ) { + _profChannelCount = _cmsChannelsOf( asICColorSpaceSig(_prof->getColorSpace()) ); gchar const** names = 0; gchar const** tips = 0; - getThings( _prof->getColorSpace(), names, tips, _fooScales ); + getThings( asICColorSpaceSig(_prof->getColorSpace()), names, tips, _fooScales ); if ( profChanged ) { for ( guint i = 0; i < _profChannelCount; i++ ) { diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index d041f85df..546f7838b 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -1,5 +1,3 @@ -#define __SP_COLOR_NOTEBOOK_C__ - /* * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages * @@ -38,6 +36,11 @@ #include "../document.h" #include "../profile-manager.h" #include "color-profile.h" +#include "color-profile-fns.h" +#if ENABLE_LCMS +//#include "lcms.h" +//#include "color-profile-cms-fns.h" +#endif // ENABLE_LCMS struct SPColorNotebookTracker { const gchar* name; @@ -537,7 +540,7 @@ void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) gtk_widget_set_sensitive (_box_toomuchink, false); if (color.icc){ Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); - if ( prof && ( (prof->getColorSpace() == icSigCmykData) || (prof->getColorSpace() == icSigCmyData) ) ) { + if ( prof && colorprofile_isPrintColorSpace(prof) ) { gtk_widget_show(GTK_WIDGET(_box_toomuchink)); double ink_sum = 0; for (unsigned int i=0; icolors.size(); i++){ -- cgit v1.2.3 From 351ad21da89e374b88b2214977f6e67ce4795ff0 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 9 Jul 2011 15:26:35 +0100 Subject: Merge upstream GDL 0.7.8 changes (bzr r10430) --- src/libgdl/Makefile_insert | 2 +- src/libgdl/gdl-combo-button.c | 383 ++++++++++ src/libgdl/gdl-combo-button.h | 65 ++ src/libgdl/gdl-data-frame.c | 297 ++++++++ src/libgdl/gdl-data-frame.h | 72 ++ src/libgdl/gdl-data-model-test.c | 240 +++++++ src/libgdl/gdl-data-model-test.h | 32 + src/libgdl/gdl-data-model.c | 160 +++++ src/libgdl/gdl-data-model.h | 105 +++ src/libgdl/gdl-data-row.c | 604 ++++++++++++++++ src/libgdl/gdl-data-row.h | 90 +++ src/libgdl/gdl-data-view.c | 526 ++++++++++++++ src/libgdl/gdl-data-view.h | 71 ++ src/libgdl/gdl-dock-item-grip.c | 4 +- src/libgdl/gdl-dock-item.c | 47 +- src/libgdl/gdl-dock-layout.c | 1411 +++++++++++++++++++++++++++++++++++++ src/libgdl/gdl-dock-layout.h | 98 +++ src/libgdl/gdl-dock-object.c | 37 +- src/libgdl/gdl-dock-placeholder.c | 4 +- src/libgdl/gdl-icons.c | 267 +++++++ src/libgdl/gdl-icons.h | 61 ++ src/libgdl/gdl-switcher.c | 12 +- src/libgdl/gdl.h | 39 + src/libgdl/libgdl.h | 37 - src/libgdl/libgdltypebuiltins.h | 2 +- src/libgdl/test-combo-button.c | 111 +++ src/libgdl/test-dataview.c | 43 ++ src/libgdl/test-dock.c | 311 ++++++++ src/ui/dialog/dock-behavior.h | 2 +- src/ui/widget/dock-item.h | 2 +- src/ui/widget/dock.h | 2 +- 31 files changed, 5068 insertions(+), 69 deletions(-) create mode 100644 src/libgdl/gdl-combo-button.c create mode 100644 src/libgdl/gdl-combo-button.h create mode 100644 src/libgdl/gdl-data-frame.c create mode 100644 src/libgdl/gdl-data-frame.h create mode 100644 src/libgdl/gdl-data-model-test.c create mode 100644 src/libgdl/gdl-data-model-test.h create mode 100644 src/libgdl/gdl-data-model.c create mode 100644 src/libgdl/gdl-data-model.h create mode 100644 src/libgdl/gdl-data-row.c create mode 100644 src/libgdl/gdl-data-row.h create mode 100644 src/libgdl/gdl-data-view.c create mode 100644 src/libgdl/gdl-data-view.h create mode 100644 src/libgdl/gdl-dock-layout.c create mode 100644 src/libgdl/gdl-dock-layout.h create mode 100644 src/libgdl/gdl-icons.c create mode 100644 src/libgdl/gdl-icons.h create mode 100644 src/libgdl/gdl.h delete mode 100644 src/libgdl/libgdl.h create mode 100644 src/libgdl/test-combo-button.c create mode 100644 src/libgdl/test-dataview.c create mode 100644 src/libgdl/test-dock.c (limited to 'src') diff --git a/src/libgdl/Makefile_insert b/src/libgdl/Makefile_insert index 5869633ea..2276aa801 100644 --- a/src/libgdl/Makefile_insert +++ b/src/libgdl/Makefile_insert @@ -40,4 +40,4 @@ libgdl_libgdl_a_SOURCES = \ libgdl/libgdltypebuiltins.c \ libgdl/libgdlmarshal.h \ libgdl/libgdlmarshal.c \ - libgdl/libgdl.h + libgdl/gdl.h diff --git a/src/libgdl/gdl-combo-button.c b/src/libgdl/gdl-combo-button.c new file mode 100644 index 000000000..6414a8110 --- /dev/null +++ b/src/libgdl/gdl-combo-button.c @@ -0,0 +1,383 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * gdl-combo-button.c + * + * Copyright (C) 2003 Jeroen Zwartepoorte + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "gdl-tools.h" +#include "gdl-combo-button.h" + +struct _GdlComboButtonPrivate { + GtkWidget *default_button; + GtkWidget *image; + GtkWidget *label; + GtkWidget *menu_button; + GtkWidget *menu; + gboolean menu_popped_up; +}; + +GDL_CLASS_BOILERPLATE (GdlComboButton, gdl_combo_button, GtkHBox, GTK_TYPE_HBOX); + +static void +default_button_clicked_cb (GtkButton *button, + gpointer user_data) +{ + GdlComboButton *combo; + GdlComboButtonPrivate *priv; + + combo = GDL_COMBO_BUTTON (user_data); + priv = combo->priv; + + if (!priv->menu_popped_up) + g_signal_emit_by_name (G_OBJECT (combo), + "activate-default", NULL); +} + +static gboolean +default_button_press_event_cb (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + + if (event->type == GDK_BUTTON_PRESS && event->button == 1) { + GTK_BUTTON (priv->menu_button)->button_down = TRUE; + gtk_button_pressed (GTK_BUTTON (priv->menu_button)); + } + + return FALSE; +} + +static gboolean +default_button_release_event_cb (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + + if (event->button == 1) { + gtk_button_released (GTK_BUTTON (priv->menu_button)); + } + + return FALSE; +} + +static gboolean +button_enter_notify_cb (GtkWidget *widget, + GdkEventCrossing *event, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + + if (event->detail != GDK_NOTIFY_INFERIOR) { + GTK_BUTTON (priv->default_button)->in_button = TRUE; + GTK_BUTTON (priv->menu_button)->in_button = TRUE; + gtk_button_enter (GTK_BUTTON (priv->default_button)); + gtk_button_enter (GTK_BUTTON (priv->menu_button)); + } + + return TRUE; +} + +static gboolean +button_leave_notify_cb (GtkWidget *widget, + GdkEventCrossing *event, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + + if (priv->menu_popped_up) + return TRUE; + + if (event->detail != GDK_NOTIFY_INFERIOR) { + GTK_BUTTON (priv->default_button)->in_button = FALSE; + GTK_BUTTON (priv->menu_button)->in_button = FALSE; + gtk_button_leave (GTK_BUTTON (priv->default_button)); + gtk_button_leave (GTK_BUTTON (priv->menu_button)); + } + + return TRUE; +} + +static void +menu_position_func (GtkMenu *menu, + gint *x_return, + gint *y_return, + gboolean *push_in, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + GtkAllocation *allocation; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + allocation = &(priv->default_button->allocation); + + gdk_window_get_origin (priv->default_button->window, x_return, y_return); + + *x_return += allocation->x; + *y_return += allocation->height; +} + +static gboolean +menu_button_press_event_cb (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + + if (event->type == GDK_BUTTON_PRESS && + (event->button == 1 || event->button == 3)) { + GTK_BUTTON (priv->menu_button)->button_down = TRUE; + + gtk_button_pressed (GTK_BUTTON (priv->menu_button)); + + priv->menu_popped_up = TRUE; + gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, + menu_position_func, combo_button, + event->button, event->time); + } + + return TRUE; +} + +static void +menu_deactivate_cb (GtkMenuShell *menu_shell, + gpointer user_data) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (user_data); + priv = combo_button->priv; + + priv->menu_popped_up = FALSE; + + GTK_BUTTON (priv->menu_button)->button_down = FALSE; + GTK_BUTTON (priv->menu_button)->in_button = FALSE; + GTK_BUTTON (priv->default_button)->in_button = FALSE; + gtk_button_leave (GTK_BUTTON (priv->menu_button)); + gtk_button_leave (GTK_BUTTON (priv->default_button)); + gtk_button_clicked (GTK_BUTTON (priv->menu_button)); +} + +static void +menu_detacher (GtkWidget *widget, + GtkMenu *menu) +{ + GdlComboButton *combo_button; + + combo_button = GDL_COMBO_BUTTON (widget); + + g_signal_handlers_disconnect_by_func (G_OBJECT (menu), + menu_deactivate_cb, + combo_button); + combo_button->priv->menu = NULL; +} + +static void +gdl_combo_button_destroy (GtkObject *object) +{ + GdlComboButton *combo_button; + GdlComboButtonPrivate *priv; + + combo_button = GDL_COMBO_BUTTON (object); + priv = combo_button->priv; + + if (priv) { + g_free (priv); + combo_button->priv = NULL; + } + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +gdl_combo_button_class_init (GdlComboButtonClass *klass) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (klass); + object_class = GTK_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); + + object_class->destroy = gdl_combo_button_destroy; + + g_signal_new ("activate-default", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdlComboButtonClass, activate_default), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +gdl_combo_button_instance_init (GdlComboButton *combo_button) +{ + GdlComboButtonPrivate *priv; + GtkWidget *hbox, *align, *arrow; + + priv = g_new (GdlComboButtonPrivate, 1); + combo_button->priv = priv; + + priv->menu = NULL; + priv->menu_popped_up = FALSE; + + priv->default_button = gtk_button_new (); + gtk_button_set_relief (GTK_BUTTON (priv->default_button), GTK_RELIEF_NONE); + + /* Following code copied from gtk_button_construct_child. */ + priv->label = gtk_label_new (""); + gtk_label_set_use_underline (GTK_LABEL (priv->label), TRUE); + gtk_label_set_mnemonic_widget (GTK_LABEL (priv->label), + priv->default_button); + + priv->image = gtk_image_new (); + hbox = gtk_hbox_new (FALSE, 2); + + align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); + + gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), priv->label, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (priv->default_button), align); + gtk_container_add (GTK_CONTAINER (align), hbox); + /* End copied block. */ + + gtk_box_pack_start (GTK_BOX (combo_button), priv->default_button, + FALSE, FALSE, 0); + gtk_widget_show_all (priv->default_button); + + priv->menu_button = gtk_button_new (); + gtk_button_set_relief (GTK_BUTTON (priv->menu_button), GTK_RELIEF_NONE); + arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); + gtk_container_add (GTK_CONTAINER (priv->menu_button), arrow); + gtk_box_pack_start (GTK_BOX (combo_button), priv->menu_button, FALSE, + FALSE, 0); + gtk_widget_show_all (priv->menu_button); + + /* Default button. */ + g_signal_connect (G_OBJECT (priv->default_button), "clicked", + G_CALLBACK (default_button_clicked_cb), combo_button); + g_signal_connect (G_OBJECT (priv->default_button), "button_press_event", + G_CALLBACK (default_button_press_event_cb), combo_button); + g_signal_connect (G_OBJECT (priv->default_button), "button_release_event", + G_CALLBACK (default_button_release_event_cb), combo_button); + g_signal_connect (G_OBJECT (priv->default_button), "enter_notify_event", + G_CALLBACK (button_enter_notify_cb), combo_button); + g_signal_connect (G_OBJECT (priv->default_button), "leave_notify_event", + G_CALLBACK (button_leave_notify_cb), combo_button); + + /* Menu button. */ + g_signal_connect (G_OBJECT (priv->menu_button), "button_press_event", + G_CALLBACK (menu_button_press_event_cb), combo_button); + g_signal_connect (G_OBJECT (priv->menu_button), "enter_notify_event", + G_CALLBACK (button_enter_notify_cb), combo_button); + g_signal_connect (G_OBJECT (priv->menu_button), "leave_notify_event", + G_CALLBACK (button_leave_notify_cb), combo_button); +} + +GtkWidget * +gdl_combo_button_new (void) +{ + GtkWidget *combo_button; + + combo_button = GTK_WIDGET (g_object_new (GDL_TYPE_COMBO_BUTTON, NULL)); + + return combo_button; +} + +void +gdl_combo_button_set_icon (GdlComboButton *combo_button, + GdkPixbuf *pixbuf) +{ + GdlComboButtonPrivate *priv; + + g_return_if_fail (GDL_IS_COMBO_BUTTON (combo_button)); + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + + priv = combo_button->priv; + + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf); +} + +void +gdl_combo_button_set_label (GdlComboButton *combo_button, + const gchar *label) +{ + GdlComboButtonPrivate *priv; + + g_return_if_fail (GDL_IS_COMBO_BUTTON (combo_button)); + g_return_if_fail (label != NULL); + + priv = combo_button->priv; + + gtk_label_set_text (GTK_LABEL (priv->label), label); +} + +void +gdl_combo_button_set_menu (GdlComboButton *combo_button, + GtkMenu *menu) +{ + GdlComboButtonPrivate *priv; + + g_return_if_fail (GDL_IS_COMBO_BUTTON (combo_button)); + g_return_if_fail (GTK_IS_MENU (menu)); + + priv = combo_button->priv; + + if (priv->menu != NULL) + gtk_menu_detach (GTK_MENU (priv->menu)); + + priv->menu = GTK_WIDGET (menu); + if (menu == NULL) + return; + + gtk_menu_attach_to_widget (menu, GTK_WIDGET (combo_button), menu_detacher); + + g_signal_connect (G_OBJECT (menu), "deactivate", + G_CALLBACK (menu_deactivate_cb), combo_button); +} diff --git a/src/libgdl/gdl-combo-button.h b/src/libgdl/gdl-combo-button.h new file mode 100644 index 000000000..6e80af0b6 --- /dev/null +++ b/src/libgdl/gdl-combo-button.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * gdl-combo-button.h + * + * Copyright (C) 2003 Jeroen Zwartepoorte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _GDL_COMBO_BUTTON_H_ +#define _GDL_COMBO_BUTTON_H_ + +#include +#include +#include + +G_BEGIN_DECLS + +#define GDL_TYPE_COMBO_BUTTON (gdl_combo_button_get_type ()) +#define GDL_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_COMBO_BUTTON, GdlComboButton)) +#define GDL_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_COMBO_BUTTON, GdlComboButtonClass)) +#define GDL_IS_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_COMBO_BUTTON)) +#define GDL_IS_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GDL_TYPE_COMBO_BUTTON)) + +typedef struct _GdlComboButton GdlComboButton; +typedef struct _GdlComboButtonPrivate GdlComboButtonPrivate; +typedef struct _GdlComboButtonClass GdlComboButtonClass; + +struct _GdlComboButton { + GtkHBox parent; + + GdlComboButtonPrivate *priv; +}; + +struct _GdlComboButtonClass { + GtkHBoxClass parent_class; + + /* Signals. */ + void (* activate_default) (GdlComboButton *combo_button); +}; + +GType gdl_combo_button_get_type (void); +GtkWidget *gdl_combo_button_new (void); + +void gdl_combo_button_set_icon (GdlComboButton *combo_button, + GdkPixbuf *pixbuf); +void gdl_combo_button_set_label (GdlComboButton *combo_button, + const gchar *label); +void gdl_combo_button_set_menu (GdlComboButton *combo_button, + GtkMenu *menu); + +G_END_DECLS + +#endif /* _GDL_COMBO_BUTTON_H_ */ diff --git a/src/libgdl/gdl-data-frame.c b/src/libgdl/gdl-data-frame.c new file mode 100644 index 000000000..d6fb19533 --- /dev/null +++ b/src/libgdl/gdl-data-frame.c @@ -0,0 +1,297 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-i18n.h" +#include "gdl-tools.h" +#include + +#include "gdl-data-view.h" +#include "gdl-data-frame.h" +#include "gdl-data-model.h" +#include "gdl-data-row.h" + +struct _GdlDataFramePrivate { + GdkRectangle shadow_r; + GdkRectangle frame_r; + GdkRectangle titlebar_r; + GdkRectangle title_r; + GdkRectangle close_r; + GdkRectangle row_r; + + int shadow_offset; + int titlebar_height; + char *title; + + GdlDataRow *row; + + PangoLayout *layout; + + gboolean selected; +}; + +static void gdl_data_frame_class_init (GdlDataFrameClass *klass); +static void gdl_data_frame_instance_init (GdlDataFrame *obj); +static void gdl_data_frame_finalize (GObject *object); + +GDL_CLASS_BOILERPLATE (GdlDataFrame, gdl_data_frame, GObject, G_TYPE_OBJECT); + +#define PAD 2 +#define BORDER 1 + +#define CENTERY(r1, r2) { r1.y = ((r2.y + (r2.height / 2)) - (r1.height / 2)); } + +void +gdl_data_frame_layout (GdlDataFrame *frame) +{ + GdkPixbuf *close_pixbuf; + /* Sizes */ + if (frame->priv->row) { + gdl_data_row_get_size (frame->priv->row, + NULL, NULL, + &frame->priv->row_r.width, + &frame->priv->row_r.height); + } else { + frame->priv->row_r.height = frame->priv->row_r.width = 0; + } + + if (frame->priv->layout) { + pango_layout_get_pixel_size (frame->priv->layout, + &frame->priv->title_r.width, + &frame->priv->title_r.height); + } else { + frame->priv->title_r.width = frame->priv->title_r.height = 0; + } + + close_pixbuf = gdl_data_view_get_close_pixbuf (frame->view); + if (close_pixbuf) { + frame->priv->close_r.width = + gdk_pixbuf_get_width (close_pixbuf); + frame->priv->close_r.height = + gdk_pixbuf_get_width (close_pixbuf); + } else { + frame->priv->close_r.width = frame->priv->close_r.height = 0; + } + + frame->priv->titlebar_r.height = MAX (frame->priv->titlebar_height, + frame->priv->title_r.height); + frame->priv->titlebar_r.height = MAX (frame->priv->titlebar_r.height, + frame->priv->close_r.height); + + frame->priv->frame_r.width = 2 * BORDER + 3 * PAD + frame->priv->title_r.width + frame->priv->close_r.width; + frame->priv->frame_r.width = MAX (frame->priv->frame_r.width, + frame->priv->row_r.width + 2 * BORDER + 2 * PAD); + frame->priv->frame_r.height = frame->priv->row_r.height + frame->priv->titlebar_r.height + 2 * PAD + 2 * BORDER; + frame->priv->titlebar_r.width = frame->priv->frame_r.width - BORDER; + frame->priv->shadow_r.width = frame->priv->frame_r.width; + frame->priv->shadow_r.height = frame->priv->frame_r.height; + + /* Locations */ + frame->priv->frame_r.x = frame->area.x; + frame->priv->frame_r.y = frame->area.y; + + frame->priv->shadow_r.x = frame->priv->frame_r.x + frame->priv->shadow_offset; + frame->priv->shadow_r.y = frame->priv->frame_r.y + frame->priv->shadow_offset; + frame->priv->titlebar_r.x = frame->priv->frame_r.x + BORDER; + frame->priv->titlebar_r.y = frame->priv->frame_r.y + BORDER; + frame->priv->title_r.x = frame->priv->frame_r.x + BORDER + PAD; + CENTERY (frame->priv->title_r, frame->priv->titlebar_r); + frame->priv->close_r.x = (frame->priv->frame_r.x + frame->priv->frame_r.width) - (frame->priv->close_r.width + BORDER + PAD); + CENTERY (frame->priv->close_r, frame->priv->titlebar_r); + + if (frame->priv->row) { + frame->priv->row_r.x = frame->priv->frame_r.x + BORDER + PAD; + frame->priv->row_r.y = frame->priv->titlebar_r.y + frame->priv->titlebar_r.height + PAD; + gdl_data_row_layout (frame->priv->row, &frame->priv->row_r); + } else { + frame->priv->row_r.x = frame->priv->row_r.y = 0; + } + + frame->area.width = frame->priv->frame_r.width + frame->priv->shadow_offset; + frame->area.height = frame->priv->frame_r.height + frame->priv->shadow_offset; +} + +#if 0 /* not used */ +static void +change_layout (GdlDataFrame *frame) +{ + char *text = frame->priv->title ? frame->priv->title : "?"; + pango_layout_set_text (frame->priv->layout, text, strlen (text)); +} +#endif + +#define EXPLODE(r) (r).x, (r).y, (r).width, (r).height + +void +gdl_data_frame_draw (GdlDataFrame *frame, GdkDrawable *drawable, + GdkRectangle *expose_area) +{ + GdkRectangle inter; + guint8 state = + frame->priv->selected ? GTK_STATE_SELECTED : GTK_STATE_NORMAL; + + gdk_draw_rectangle (drawable, + GTK_WIDGET (frame->view)->style->dark_gc[state], + TRUE, + EXPLODE (frame->priv->shadow_r)); + gdk_draw_rectangle (drawable, + GTK_WIDGET (frame->view)->style->base_gc[GTK_STATE_NORMAL], + TRUE, + EXPLODE (frame->priv->frame_r)); + gdk_draw_rectangle (drawable, + GTK_WIDGET (frame->view)->style->black_gc, + FALSE, + EXPLODE (frame->priv->frame_r)); + gdk_draw_rectangle (drawable, + GTK_WIDGET (frame->view)->style->bg_gc[state], + TRUE, + EXPLODE (frame->priv->titlebar_r)); + gdk_draw_layout (drawable, + GTK_WIDGET (frame->view)->style->fg_gc[state], + frame->priv->title_r.x, frame->priv->title_r.y, + frame->priv->layout); + + if (gdk_rectangle_intersect (expose_area, &frame->priv->close_r, &inter)) { + GdkPixbuf *pixbuf = gdl_data_view_get_close_pixbuf (frame->view); + gdk_draw_pixbuf (drawable, NULL, pixbuf, + 0, 0, + inter.x - frame->priv->close_r.x, + inter.y - frame->priv->close_r.y, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + } + + if (frame->priv->row) { + if (gdk_rectangle_intersect (expose_area, &frame->priv->row_r, + &inter)) { + gdl_data_row_render (frame->priv->row, drawable, + &inter, + frame->priv->selected ? GTK_CELL_RENDERER_SELECTED : 0); + } + } +} + +void +gdl_data_frame_class_init (GdlDataFrameClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *)klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->finalize = gdl_data_frame_finalize; +} + +void +gdl_data_frame_instance_init (GdlDataFrame *frame) +{ + frame->priv = g_new0 (GdlDataFramePrivate, 1); + frame->area.x = frame->area.y = 0; + frame->priv->shadow_offset = 3; + frame->priv->titlebar_height = 20; + + frame->area.height = frame->area.width = 100; +} + +void +gdl_data_frame_finalize (GObject *object) +{ + GdlDataFrame *frame = GDL_DATA_FRAME (object); + + if (frame->priv) { + g_free (frame->priv->title); + g_object_unref (frame->priv->layout); + g_object_unref (frame->priv->row); + + g_free (frame->priv); + frame->priv = NULL; + } + GDL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +void +gdl_data_frame_set_selected (GdlDataFrame *frame, + gboolean val) +{ + frame->priv->selected = val; + + gdk_window_invalidate_rect (GTK_LAYOUT (frame->view)->bin_window, + &frame->priv->frame_r, + TRUE); +} + +gboolean +gdl_data_frame_button_press (GdlDataFrame *frame, + GdkEventButton *event) +{ + return FALSE; +} + +void +gdl_data_frame_set_position (GdlDataFrame *frame, + int x, + int y) +{ + frame->area.x = x; + frame->area.y = y; + + gdl_data_frame_layout (frame); +} + +static void +setup_layout (GdlDataFrame *frame) +{ + PangoFontDescription *font_desc = + pango_font_description_copy (GTK_WIDGET (frame->view)->style->font_desc); + + pango_font_description_set_weight (font_desc, + PANGO_WEIGHT_BOLD); + + frame->priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (frame->view), + frame->priv->title ? frame->priv->title : "?"); + pango_layout_set_font_description (frame->priv->layout, + font_desc); + pango_font_description_free (font_desc); +} + + +GdlDataFrame * +gdl_data_frame_new (GdlDataView *view, + GdlDataRow *row) +{ + GdlDataFrame *frame; + frame = GDL_DATA_FRAME (g_object_new (GDL_TYPE_DATA_FRAME, NULL)); + + frame->view = view; + + frame->priv->row = row; + frame->priv->title = g_strdup (gdl_data_row_get_title (row)); + + setup_layout (frame); + + gdl_data_frame_layout (frame); + + return frame; +} diff --git a/src/libgdl/gdl-data-frame.h b/src/libgdl/gdl-data-frame.h new file mode 100644 index 000000000..740c38293 --- /dev/null +++ b/src/libgdl/gdl-data-frame.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GDL_DATA_FRAME_H +#define GDL_DATA_FRAME_H + +#include +#include + +G_BEGIN_DECLS + +#define GDL_TYPE_DATA_FRAME (gdl_data_frame_get_type ()) +#define GDL_DATA_FRAME(obj) (GTK_CHECK_CAST ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrame)) +#define GDL_DATA_FRAME_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GDL_DATA_VIEW_FRAM, GdlDataFrame)) +#define GDL_IS_DATA_FRAME(obj) (GTK_CHECK_TYPE ((obj), GDL_TYPE_DATA_FRAME)) +#define GDL_IS_DATA_FRAME_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_FRAME)) +#define GDL_DATA_FRAME_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrameClass)) + +typedef struct _GdlDataFrame GdlDataFrame; +typedef struct _GdlDataFramePrivate GdlDataFramePrivate; +typedef struct _GdlDataFrameClass GdlDataFrameClass; + +struct _GdlDataFrame { + GObject parent; + + GdlDataView *view; + GdkRectangle area; + + GdlDataFramePrivate *priv; +}; + +struct _GdlDataFrameClass { + GObjectClass parent_class; +}; + +GType gdl_data_frame_get_type (void); +GdlDataFrame *gdl_data_frame_new (GdlDataView *view, + GdlDataRow *row); +void gdl_data_frame_layout (GdlDataFrame *frame); +void gdl_data_frame_draw (GdlDataFrame *item, + GdkDrawable *drawable, + GdkRectangle *expose_area); +void gdl_data_frame_set_selected (GdlDataFrame *frame, + gboolean val); +gboolean gdl_data_frame_button_press (GdlDataFrame *frame, + GdkEventButton *event); +void gdl_data_frame_set_position (GdlDataFrame *frame, + int x, + int y); + +G_END_DECLS + +#endif diff --git a/src/libgdl/gdl-data-model-test.c b/src/libgdl/gdl-data-model-test.c new file mode 100644 index 000000000..ec6ed4d50 --- /dev/null +++ b/src/libgdl/gdl-data-model-test.c @@ -0,0 +1,240 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-i18n.h" + +#include "gdl-data-model-test.h" +#include "gdl-data-model.h" + +#include +#include +#include + +GObjectClass *parent_class; + +typedef struct _DataItem { + char *name; + char *value; + char *path; + struct _DataItem *children; +} DataItem; + +DataItem data1[] = { + { "foo1", "foo1", "0:0", NULL}, + { "bar1", "bar1", "0:1", NULL }, + { "baz1", "baz1", "0:2", NULL }, + { NULL, NULL, NULL, NULL } + +}; +DataItem data2[] = { + { "foo2", "foo2", "1:0", NULL }, + { "bar2", "bar2", "1:1", NULL }, + { "baz2", "baz2", "1:2", NULL }, + { NULL, NULL, NULL, NULL } + +}; + +DataItem data5[] = { + { "1", "1", "2:2:1:0", NULL }, + { "2", "2", "2:2:1:1", NULL }, + { "3", "3", "2:2:1:2", NULL }, + { "4", "4", "2:2:1:3", NULL }, + { "5", "5", "2:2:1:4", NULL }, + { "6", "6", "2:2:1:5", NULL }, + { NULL, NULL, NULL, NULL } + +}; +DataItem data4[] = { + { "foo4", "foo4", "2:2:0", NULL }, + { "bar4", "[...]", "2:2:1", data5 }, + { "baz4", "baz4", "2:2:2", NULL }, + { NULL, NULL, NULL, NULL } + +}; +DataItem data3[] = { + { "foo foo", "foo3", "2:0", NULL }, + { "bar3", "1", "2:1", NULL }, + { "baz3", "{...}", "2:2", data4 }, + { NULL, NULL, NULL, NULL } + +}; + +DataItem root[] = { + { "test-data", "value1", "0", NULL } , + { "test-data2", "value2", "1", NULL } , + { "test-data3", "{...}", "2", data3 } , + { NULL, NULL, NULL } +}; + +static gboolean +get_iter (GdlDataModel *dm, GdlDataIter *iter, GtkTreePath *path) +{ + int *i = gtk_tree_path_get_indices (path); + int n = gtk_tree_path_get_depth (path); + DataItem *item; + + g_assert (i); + item = &root[*i++]; + + while (--n) { + item = &item->children[*i++]; + } + + iter->data1 = item; + + return TRUE; +} + +static GtkTreePath * +get_path (GdlDataModel *dm, GdlDataIter *iter) +{ + DataItem *item = iter->data1; + return gtk_tree_path_new_from_string (item->path); +} + +static void +get_name (GdlDataModel *dm, GdlDataIter *iter, char **name) +{ + DataItem *item = iter->data1; + *name = item->name; +} + +static void +get_value (GdlDataModel *dm, GdlDataIter *iter, GValue *value) +{ + DataItem *item = iter->data1; + if (strcmp (item->name, "bar3")) { + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, item->value); + } else { + g_value_init (value, G_TYPE_BOOLEAN); + g_value_set_boolean (value, !strcmp (item->value, "1")); + } +} + +static void +get_renderer (GdlDataModel *dm, GdlDataIter *iter, + GtkCellRenderer **renderer, char **field, + gboolean *is_editable) +{ + DataItem *item = iter->data1; + if (!strcmp (item->name, "bar3")) { + *renderer = g_object_new (gtk_cell_renderer_toggle_get_type (), + "activatable", TRUE, NULL); + *field = "active"; + } else { + *renderer = g_object_new (gtk_cell_renderer_text_get_type (), + "editable", TRUE, NULL); + *field = "text"; + } + *is_editable = (item->children == NULL); +} + +static gboolean +iter_next (GdlDataModel *dm, GdlDataIter *iter) +{ + DataItem *item = iter->data1; + item++; + if (item->name) { + iter->data1 = item; + return TRUE; + } else { + return FALSE; + } +} + +static gboolean +iter_children (GdlDataModel *dm, GdlDataIter *iter, GdlDataIter *parent) +{ + DataItem *item = parent->data1; + + item = &item->children[0]; + if (item) { + iter->data1 = item; + return TRUE; + } else { + return FALSE; + } +} + +static gboolean +iter_has_child (GdlDataModel *dm, GdlDataIter *iter) +{ + DataItem *item = iter->data1; + if (item->children) { + return TRUE; + } else { + return FALSE; + } +} + + +static void +gdl_data_model_test_instance_init (GdlDataModelTest *model) +{ +} + +static void +gdl_data_model_test_finalize (GObject *object) +{ + (*parent_class->finalize) (object); +} + +static void +gdl_data_model_test_class_init (GdlDataModelTestClass *klass) +{ + GObjectClass *object_class; + parent_class = g_type_class_peek_parent (klass); + object_class = (GObjectClass *)klass; + object_class->finalize = gdl_data_model_test_finalize; +} + +static void +gdl_data_model_test_data_model_init (GdlDataModelIface *iface) +{ + iface->get_iter = get_iter; + iface->get_path = get_path; + iface->get_name = get_name; + iface->get_value = get_value; + iface->get_renderer = get_renderer; + iface->iter_next = iter_next; + iface->iter_children = iter_children; + iface->iter_has_child = iter_has_child; +} + +GType +gdl_data_model_test_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo data_model_test_info = { + sizeof (GdlDataModelTestClass), + NULL, NULL, + (GClassInitFunc) gdl_data_model_test_class_init, + NULL, NULL, + sizeof (GdlDataModelTest), 0, + (GInstanceInitFunc) gdl_data_model_test_instance_init + }; + + static const GInterfaceInfo data_model_info = { + (GInterfaceInitFunc) gdl_data_model_test_data_model_init, + NULL, NULL + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "GdlDataModelTest", + &data_model_test_info, 0); + g_type_add_interface_static (type, + GDL_TYPE_DATA_MODEL, + &data_model_info); + } + return type; +} + +GdlDataModelTest * +gdl_data_model_test_new (void) +{ + return GDL_DATA_MODEL_TEST (g_object_new (gdl_data_model_test_get_type (), NULL)); +} diff --git a/src/libgdl/gdl-data-model-test.h b/src/libgdl/gdl-data-model-test.h new file mode 100644 index 000000000..c8add8daf --- /dev/null +++ b/src/libgdl/gdl-data-model-test.h @@ -0,0 +1,32 @@ +#ifndef GDL_DATA_MODEL_TEST_H +#define GDL_DATA_MODEL_TEST_H + +#include +#include "gdl-data-model.h" + +G_BEGIN_DECLS + +#define GDL_TYPE_DATA_MODEL_TEST (gdl_data_model_test_get_type ()) +#define GDL_DATA_MODEL_TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_MODEL_TEST, GdlDataModelTest)) +#define GDL_IS_DATA_MODEL_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_MODEL_TEST)) + + +typedef struct _GdlDataModelTest GdlDataModelTest; +typedef struct _GdlDataModelTestClass GdlDataModelTestClass; + +struct _GdlDataModelTest { + GObject parent; + + int stamp; +}; + +struct _GdlDataModelTestClass { + GObjectClass parent_class; +}; + +GType gdl_data_model_test_get_type (void); +GdlDataModelTest *gdl_data_model_test_new (void); + +G_END_DECLS + +#endif diff --git a/src/libgdl/gdl-data-model.c b/src/libgdl/gdl-data-model.c new file mode 100644 index 000000000..69fbb93d5 --- /dev/null +++ b/src/libgdl/gdl-data-model.c @@ -0,0 +1,160 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-data-model.h" + +gboolean +gdl_data_model_get_iter (GdlDataModel *dm, + GdlDataIter *iter, + GtkTreePath *path) +{ + g_return_val_if_fail (dm != NULL, FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_iter != NULL, + FALSE); + + return (*GDL_DATA_MODEL_GET_IFACE (dm)->get_iter) (dm, iter, path); +} + +GtkTreePath * +gdl_data_model_get_path (GdlDataModel *dm, + GdlDataIter *iter) +{ + g_return_val_if_fail (dm != NULL, NULL); + g_return_val_if_fail (iter != NULL, NULL); + g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_path != NULL, + NULL); + + return (*GDL_DATA_MODEL_GET_IFACE (dm)->get_path) (dm, iter); +} + +void +gdl_data_model_get_name (GdlDataModel *dm, + GdlDataIter *iter, + char **name) +{ + g_return_if_fail (dm != NULL); + g_return_if_fail (iter != NULL); + g_return_if_fail (name != NULL); + g_return_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_name != NULL); + + (*GDL_DATA_MODEL_GET_IFACE (dm)->get_name) (dm, iter, name); +} + +void +gdl_data_model_get_value (GdlDataModel *dm, + GdlDataIter *iter, + GValue *value) +{ + g_return_if_fail (dm != NULL); + g_return_if_fail (iter != NULL); + g_return_if_fail (value != NULL); + g_return_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_value != NULL); + + (*GDL_DATA_MODEL_GET_IFACE (dm)->get_value) (dm, iter, value); +} + +void +gdl_data_model_get_renderer (GdlDataModel *dm, + GdlDataIter *iter, + GtkCellRenderer **renderer, + char **field, + gboolean *is_editable) +{ + g_return_if_fail (dm != NULL); + g_return_if_fail (iter != NULL); + g_return_if_fail (renderer != NULL); + g_return_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_renderer != NULL); + + (*GDL_DATA_MODEL_GET_IFACE (dm)->get_renderer) (dm, iter, + renderer, field, + is_editable); +} + +gboolean +gdl_data_model_iter_next (GdlDataModel *dm, + GdlDataIter *iter) +{ + g_return_val_if_fail (dm != NULL, FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->iter_next != NULL, FALSE); + + return (*GDL_DATA_MODEL_GET_IFACE (dm)->iter_next) (dm, iter); +} + +gboolean +gdl_data_model_iter_children (GdlDataModel *dm, + GdlDataIter *iter, + GdlDataIter *parent) +{ + g_return_val_if_fail (dm != NULL, FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->iter_children != NULL, FALSE); + + return (*GDL_DATA_MODEL_GET_IFACE (dm)->iter_children) (dm, iter, parent); +} + +gboolean +gdl_data_model_iter_has_child (GdlDataModel *dm, + GdlDataIter *iter) +{ + g_return_val_if_fail (dm != NULL, FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->iter_has_child != NULL, FALSE); + + return (*GDL_DATA_MODEL_GET_IFACE (dm)->iter_has_child) (dm, iter); +} + +static void +gdl_data_model_base_init (gpointer g_class) +{ + static gboolean initialized = FALSE; + + if (!initialized) { + } +} + +GType +gdl_data_model_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo info = { + sizeof (GdlDataModelIface), + gdl_data_model_base_init, + NULL, NULL, NULL, NULL, 0, 0, NULL + }; + + type = g_type_register_static (G_TYPE_INTERFACE, + "GdlDataModel", + &info, 0); + g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); + } + + return type; +} diff --git a/src/libgdl/gdl-data-model.h b/src/libgdl/gdl-data-model.h new file mode 100644 index 000000000..521a65d0c --- /dev/null +++ b/src/libgdl/gdl-data-model.h @@ -0,0 +1,105 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GDL_DATA_MODEL_H +#define GDL_DATA_MODEL_H + +#include +#include + +/* Using GtkTreePath to save time */ +#include +#include + +G_BEGIN_DECLS + +#define GDL_TYPE_DATA_MODEL (gdl_data_model_get_type ()) +#define GDL_DATA_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_MODEL, GdlDataModel)) +#define GDL_IS_DATA_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_MODEL)) +#define GDL_DATA_MODEL_GET_IFACE(obj) ((GdlDataModelIface *)g_type_interface_peek (((GTypeInstance *)GDL_DATA_MODEL (obj))->g_class, GDL_TYPE_DATA_MODEL)) + +typedef struct _GdlDataModel GdlDataModel; +typedef struct _GdlDataIter GdlDataIter; +typedef struct _GdlDataModelIface GdlDataModelIface; + +struct _GdlDataIter { + int stamp; + + gpointer data1; + gpointer data2; + gpointer data3; +}; + +struct _GdlDataModelIface { + GTypeInterface g_iface; + + /* Signals */ + void (*path_changed) (GdlDataModel *dm, GtkTreePath *path); + void (*path_inserted) (GdlDataModel *dm, GtkTreePath *path); + void (*path_deleted) (GdlDataModel *dm, GtkTreePath *path); + + /* Virtual Table */ + gboolean (*get_iter) (GdlDataModel *dm, GdlDataIter *iter, + GtkTreePath *path); + GtkTreePath* (*get_path) (GdlDataModel *dm, GdlDataIter *iter); + + void (*get_name) (GdlDataModel *dm, GdlDataIter *iter, + char **name); + void (*get_value) (GdlDataModel *dm, GdlDataIter *iter, + GValue *value); + void (*get_renderer) (GdlDataModel *dm, GdlDataIter *iter, + GtkCellRenderer **renderer, char **field, + gboolean *is_editable); + gboolean (*iter_next) (GdlDataModel *dm, GdlDataIter *iter); + gboolean (*iter_children) (GdlDataModel *dm, GdlDataIter *iter, + GdlDataIter *parent); + gboolean (*iter_has_child) (GdlDataModel *dm, GdlDataIter *iter); +}; + +GType gdl_data_model_get_type (void); +gboolean gdl_data_model_get_iter (GdlDataModel *dm, + GdlDataIter *iter, + GtkTreePath *path); +GtkTreePath *gdl_data_model_get_path (GdlDataModel *dm, + GdlDataIter *iter); +void gdl_data_model_get_name (GdlDataModel *dm, + GdlDataIter *iter, + char **name); +void gdl_data_model_get_value (GdlDataModel *dm, + GdlDataIter *iter, + GValue *value); +void gdl_data_model_get_renderer (GdlDataModel *dm, + GdlDataIter *iter, + GtkCellRenderer **renderer, + char **field, + gboolean *is_editable); +gboolean gdl_data_model_iter_next (GdlDataModel *dm, + GdlDataIter *iter); +gboolean gdl_data_model_iter_children (GdlDataModel *dm, + GdlDataIter *iter, + GdlDataIter *children); +gboolean gdl_data_model_iter_has_child (GdlDataModel *dm, + GdlDataIter *iter); + +G_END_DECLS + +#endif diff --git a/src/libgdl/gdl-data-row.c b/src/libgdl/gdl-data-row.c new file mode 100644 index 000000000..666c658fe --- /dev/null +++ b/src/libgdl/gdl-data-row.c @@ -0,0 +1,604 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-i18n.h" +#include "gdl-tools.h" +#include "gdl-data-row.h" +#include "gdl-data-model.h" + +#include +#include + +struct _GdlDataRowPrivate { + GdlDataModel *model; + GtkTreePath *path; + GdlDataView *view; + + char *name; + + /* area_r + * +- title_r + * | +- name_r + * | +- sep_r + * +- data_r + * +- expand_r + * +- cell_r + */ + + GdkRectangle area_r; + + GdkRectangle title_r; + GdkRectangle name_r; + GdkRectangle sep_r; + + GdkRectangle data_r; + GdkRectangle expand_r; + GdkRectangle cell_r; + + gboolean multi; + GtkCellRenderer *cell; + GList *subrows; + + char *renderer_field; + + gboolean expanded; + gboolean focused; + gboolean editable; + + int split; + int child_split; + gboolean selected; +}; + +GDL_CLASS_BOILERPLATE (GdlDataRow, gdl_data_row, GObject, G_TYPE_OBJECT); + + +static void +expand (GdlDataRow *row) +{ + GdlDataIter iter; + gboolean valid; + + if (gdl_data_model_get_iter (row->priv->model, &iter, row->priv->path)) { + valid = gdl_data_model_iter_children (row->priv->model, + &iter, &iter); + while (valid) { + GdlDataRow *new_row; + GtkTreePath *path; + + path = gdl_data_model_get_path (row->priv->model, + &iter); + new_row = gdl_data_row_new (row->priv->view, + path); + row->priv->subrows = + g_list_prepend (row->priv->subrows, new_row); + gtk_tree_path_free (path); + + valid = gdl_data_model_iter_next (row->priv->model, + &iter); + } + row->priv->subrows = g_list_reverse (row->priv->subrows); + + row->priv->expanded = TRUE; + gdl_data_view_layout (GDL_DATA_VIEW (row->priv->view)); + gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); + } +} + +static void +contract (GdlDataRow *row) +{ + GList *l; + for (l = row->priv->subrows; l != NULL; l = l->next) { + g_object_unref (G_OBJECT (l->data)); + } + g_list_free (row->priv->subrows); + row->priv->subrows = NULL; + + row->priv->expanded = FALSE; + gdl_data_view_layout (GDL_DATA_VIEW (row->priv->view)); + gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); +} + +static void +load_path (GdlDataRow *row) +{ + GdlDataIter iter; + + /* Make sure the path has been unloaded */ + g_return_if_fail (row->priv->name == NULL); + g_return_if_fail (row->priv->cell == NULL); + + if (gdl_data_model_get_iter (row->priv->model, + &iter, row->priv->path)) { + GValue val = { 0, }; + char *str; + + gdl_data_model_get_name (row->priv->model, &iter, + &str); + row->priv->name = g_strdup (str); + + if (gdl_data_model_iter_has_child (row->priv->model, &iter)) { + row->priv->multi = TRUE; + } + + gdl_data_model_get_renderer (row->priv->model, &iter, + &row->priv->cell, + &str, + &row->priv->editable); + g_object_ref (GTK_OBJECT (row->priv->cell)); + gtk_object_sink (GTK_OBJECT (row->priv->cell)); + + row->priv->renderer_field = g_strdup (str); + gdl_data_model_get_value (row->priv->model, &iter, &val); + + g_object_set_property (G_OBJECT (row->priv->cell), + row->priv->renderer_field, + &val); + g_value_unset (&val); + } +} + +static void +unload_path (GdlDataRow *row) +{ + if (row->priv->renderer_field) { + g_free (row->priv->renderer_field); + row->priv->renderer_field = NULL; + } + + if (row->priv->name) { + g_free (row->priv->name); + row->priv->name = NULL; + } + + if (row->priv->cell) { + g_object_unref (row->priv->cell); + row->priv->cell = NULL; + } + + if (row->priv->subrows) { + GList *l; + for (l = row->priv->subrows; l != NULL; l = l->next) { + g_object_unref (G_OBJECT (l->data)); + } + g_list_free (row->priv->subrows); + row->priv->subrows = NULL; + } +} + +static void +gdl_data_row_instance_init (GdlDataRow *row) +{ + row->priv = g_new0 (GdlDataRowPrivate, 1); +} + +static void +gdl_data_row_finalize (GObject *object) +{ + GdlDataRow *row = GDL_DATA_ROW (object); + if (row->priv) { + unload_path (row); + + if (row->priv->path) { + gtk_tree_path_free (row->priv->path); + row->priv->path = NULL; + } + + + g_object_unref (row->priv->model); + + g_free (row->priv); + row->priv = NULL; + } +} + +static void +gdl_data_row_class_init (GdlDataRowClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + gobject_class->finalize = gdl_data_row_finalize; + + parent_class = g_type_class_peek_parent (klass); +} + +GdlDataRow * +gdl_data_row_new (GdlDataView *view, + GtkTreePath *path) +{ + GdlDataRow *row; + + row = GDL_DATA_ROW (g_object_new (gdl_data_row_get_type (), + NULL)); + + row->priv->view = view; + row->priv->model = g_object_ref (view->model); + row->priv->path = gtk_tree_path_copy (path); + load_path (row); + + return row; +} + + +#define PAD 3 + +static void +layout_row (GdlDataRow *row, + int x, int y, int width, int height) +{ + PangoLayout *layout; + + /* sizes */ + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), + row->priv->name); + pango_layout_get_pixel_size (layout, + &row->priv->name_r.width, + &row->priv->name_r.height); + g_object_unref (layout); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), "="); + pango_layout_get_pixel_size (layout, + &row->priv->sep_r.width, + &row->priv->sep_r.height); + g_object_unref (layout); + + row->priv->title_r.width = + MAX (row->priv->name_r.width + row->priv->sep_r.width + PAD, + row->priv->split); + row->priv->title_r.height = + MAX (row->priv->name_r.height, row->priv->sep_r.width); + + if (row->priv->cell) { + gtk_cell_renderer_get_size (row->priv->cell, + GTK_WIDGET (row->priv->view), + NULL, NULL, NULL, + &row->priv->cell_r.width, + &row->priv->cell_r.height); + } else { + row->priv->cell_r.width = row->priv->cell_r.height = 0; + } + + row->priv->data_r.width = row->priv->cell_r.width; + row->priv->data_r.height = row->priv->cell_r.height; + + if (row->priv->multi) { + row->priv->expand_r.width = 10; + row->priv->expand_r.height = 10; + + row->priv->data_r.width += row->priv->expand_r.width; + row->priv->data_r.height = MAX (row->priv->expand_r.height, + row->priv->data_r.height); + + if (row->priv->expanded) { + GList *l; + int name_w = 0, data_w = 0; + for (l = row->priv->subrows; l != NULL; l = l->next) { + int w1, w2, h; + gdl_data_row_get_size (GDL_DATA_ROW (l->data), + &w1, &w2, NULL, &h); + name_w = MAX (name_w, w1); + data_w = MAX (data_w, w2); + row->priv->data_r.height += h; + } + row->priv->child_split = name_w; + row->priv->data_r.width = + MAX (name_w + data_w + 3 * PAD, + row->priv->data_r.width); + row->priv->data_r.height += 2 * PAD; + } + } + + row->priv->area_r.width = MAX (width, + row->priv->data_r.width + row->priv->title_r.width + PAD); + + row->priv->area_r.height = MAX (height, + (MAX (row->priv->data_r.height, + row->priv->title_r.height))); + + /* Positions */ + + row->priv->area_r.x = x; + row->priv->area_r.y = y; + + row->priv->title_r.x = x; + row->priv->title_r.y = y + ((row->priv->area_r.height) / 2) - (row->priv->title_r.height / 2); + + row->priv->name_r.x = x; + row->priv->name_r.y = y + ((row->priv->area_r.height) / 2) - (row->priv->name_r.height / 2); + + row->priv->sep_r.x = row->priv->title_r.x + row->priv->title_r.width - row->priv->sep_r.width; + row->priv->sep_r.y = y + ((row->priv->area_r.height) / 2) - (row->priv->sep_r.height / 2); + + row->priv->data_r.x = row->priv->title_r.x + row->priv->title_r.width + PAD; + row->priv->data_r.y = y; + + /* Readjust the data area size to fit */ + row->priv->data_r.width = row->priv->area_r.width - (row->priv->title_r.width + PAD); + row->priv->data_r.height = row->priv->area_r.height; + + if (row->priv->multi) { + row->priv->expand_r.x = row->priv->data_r.x; + row->priv->expand_r.y = row->priv->data_r.y + ((row->priv->cell_r.height) / 2) - (row->priv->expand_r.height / 2); + + row->priv->cell_r.y = row->priv->data_r.y; + row->priv->cell_r.height = MAX (row->priv->expand_r.height, row->priv->cell_r.height); + row->priv->cell_r.width = (row->priv->data_r.width - row->priv->expand_r.width); + + row->priv->cell_r.x = row->priv->expand_r.x + row->priv->expand_r.width; + } else { + row->priv->cell_r = row->priv->data_r; + } +} + +void +gdl_data_row_get_size (GdlDataRow *row, int *sep_width, + int *cell_width, int *total_width, int *height) +{ + layout_row (row, 0, 0, 0, 0); + + if (sep_width) { + *sep_width = row->priv->name_r.width + row->priv->sep_r.width + PAD; + } + + if (cell_width) *cell_width = row->priv->data_r.width; + if (total_width) *total_width = row->priv->area_r.width; + if (height) *height = row->priv->area_r.height; +} + +void +gdl_data_row_set_show_name (GdlDataRow *row, gboolean show_name) +{ +} + +void +gdl_data_row_layout (GdlDataRow *row, GdkRectangle *alloc) +{ + layout_row (row, alloc->x, alloc->y, alloc->width, alloc->height); + + if (row->priv->multi && row->priv->expanded) { + GList *l; + GdkRectangle sub; + sub.y = row->priv->expand_r.y + row->priv->expand_r.width + PAD; + sub.x = row->priv->data_r.x + PAD; + sub.width = row->priv->data_r.width - 2 * PAD; + sub.height = row->priv->data_r.height - 2 * PAD; + + for (l = row->priv->subrows; l != NULL; l = l->next) { + gdl_data_row_get_size (GDL_DATA_ROW (l->data), + NULL, NULL, NULL, &sub.height); + gdl_data_row_set_split (GDL_DATA_ROW (l->data), + row->priv->child_split); + gdl_data_row_layout (GDL_DATA_ROW (l->data), + &sub); + sub.y += sub.height; + } + } +} + +#if 0 +#define DRAWR(r) { gdk_draw_rectangle (drawable, GTK_WIDGET (row->priv->view)->style->text_gc[GTK_STATE_NORMAL],FALSE,row->priv->r.x,row->priv->r.y,row->priv->r.width, row->priv->r.height); } +#else +#define DRAWR(r) +#endif + + +void +gdl_data_row_render (GdlDataRow *row, GdkDrawable *drawable, + GdkRectangle *expose_area, + GtkCellRendererState flags) +{ + PangoLayout *layout; + + guint state = GTK_STATE_NORMAL; + + if (row->priv->selected) { + if (flags & GTK_CELL_RENDERER_SELECTED) + state = GTK_STATE_SELECTED; + else + state = GTK_STATE_ACTIVE; + gtk_paint_flat_box (GTK_WIDGET (row->priv->view)->style, + drawable, state, + GTK_SHADOW_NONE, expose_area, + GTK_WIDGET (row->priv->view), "cell_even", + row->priv->area_r.x, row->priv->area_r.y, + row->priv->area_r.width + 1, + row->priv->area_r.height + 1); + + } + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), + row->priv->name); + gdk_draw_layout (drawable, + GTK_WIDGET (row->priv->view)->style->text_gc[state], + row->priv->name_r.x, row->priv->name_r.y, layout); + g_object_unref (layout); + DRAWR(name_r); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), "="); + gdk_draw_layout (drawable, + GTK_WIDGET (row->priv->view)->style->text_gc[state], + row->priv->sep_r.x, row->priv->sep_r.y, layout); + g_object_unref (layout); + DRAWR(sep_r); + DRAWR(title_r); + + if (row->priv->cell) { + if (row->priv->focused) { + gtk_paint_focus (GTK_WIDGET (row->priv->view)->style, + drawable, + GTK_WIDGET_STATE (GTK_WIDGET (row->priv->view)), + NULL, GTK_WIDGET (row->priv->view), + "treeview", + row->priv->cell_r.x - 1, + row->priv->cell_r.y - 1, + row->priv->cell_r.width + 2, + row->priv->cell_r.height + 2); + } + + gtk_cell_renderer_render (row->priv->cell, + drawable, GTK_WIDGET (row->priv->view), + &row->priv->area_r, + &row->priv->cell_r, + expose_area, + row->priv->selected ? GTK_CELL_RENDERER_SELECTED : 0); + DRAWR(cell_r); + } + if (row->priv->multi) { + gtk_paint_expander (GTK_WIDGET (row->priv->view)->style, + drawable, + GTK_WIDGET_STATE (GTK_WIDGET (row->priv->view)), + expose_area, + GTK_WIDGET (row->priv->view), + "gdldataview", + row->priv->expand_r.x + row->priv->expand_r.width / 2, + row->priv->expand_r.y + row->priv->expand_r.height / 2, + row->priv->expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED); + DRAWR(expand_r); + + if (row->priv->expanded) { + GList *l; + + for (l = row->priv->subrows; l != NULL; l = l->next) { + gdl_data_row_render (GDL_DATA_ROW (l->data), + drawable, + expose_area, flags); + } + } + gdk_draw_rectangle (drawable, + GTK_WIDGET (row->priv->view)->style->text_gc[GTK_STATE_NORMAL], + FALSE, + row->priv->data_r.x, + row->priv->data_r.y, + row->priv->data_r.width, + row->priv->data_r.height); + } + DRAWR(data_r); +} + + +GdlDataRow * +gdl_data_row_at (GdlDataRow *row, int x, int y) +{ + if (!GDL_POINT_IN (x, y, &row->priv->area_r)) { + return NULL; + } + + if (row->priv->multi && row->priv->expanded) { + GList *l; + for (l = row->priv->subrows; l != NULL; l = l->next) { + GdlDataRow *ret = gdl_data_row_at (GDL_DATA_ROW (l->data), x, y); + if (ret) + return ret; + } + } + + return row; +} + +static gboolean +button_press_event (GdlDataRow *row, GdkEventButton *event, + GtkCellEditable **editable_widget) +{ + if (editable_widget) + *editable_widget = NULL; + + if (GDL_POINT_IN (event->x, event->y, &row->priv->expand_r)) { + if (row->priv->expanded) + contract (row); + else + expand (row); + } + + if (GDL_POINT_IN (event->x, event->y, &row->priv->cell_r) + && row->priv->editable) { + g_return_val_if_fail (editable_widget, FALSE); + *editable_widget = gtk_cell_renderer_start_editing + (row->priv->cell, + (GdkEvent*)event, + GTK_WIDGET (row->priv->view), + "1:2:3", + &row->priv->area_r, + &row->priv->cell_r, + GTK_CELL_RENDERER_SELECTED); + } + + return FALSE; + +} + + +gboolean +gdl_data_row_event (GdlDataRow *row, GdkEvent *event, + GtkCellEditable **editable_widget) +{ + switch (((GdkEventAny *)event)->type) { + case GDK_BUTTON_PRESS: + return button_press_event (row, + (GdkEventButton *)event, + editable_widget); + default: + break; + } + return FALSE; +} + +void +gdl_data_row_get_cell_area (GdlDataRow *row, + GdkRectangle *rect) +{ + *rect = row->priv->cell_r; +} + +void +gdl_data_row_set_split (GdlDataRow *row, int split) +{ + row->priv->split = split; +} + +void +gdl_data_row_set_selected (GdlDataRow *row, gboolean selected) +{ + row->priv->selected = selected; + + /* FIXME: invalidate here */ + gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); +} + +void +gdl_data_row_set_focused (GdlDataRow *row, gboolean focused) +{ + row->priv->focused = focused; + + /* FIXME: invalidate here */ + gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); +} + +const char * +gdl_data_row_get_title (GdlDataRow *row) +{ + return row->priv->name; +} diff --git a/src/libgdl/gdl-data-row.h b/src/libgdl/gdl-data-row.h new file mode 100644 index 000000000..d4928958d --- /dev/null +++ b/src/libgdl/gdl-data-row.h @@ -0,0 +1,90 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GDL_DATA_ROW_H +#define GDL_DATA_ROW_H + +#include + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GDL_TYPE_DATA_ROW (gdl_data_row_get_type ()) +#define GDL_DATA_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_ROW, GdlDataRow)) +#define GDL_DATA_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DATA_ROW, GdlDataRowClass)) +#define GDL_IS_DATA_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_ROW)) +#define GDL_IS_DATA_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_ROW)) + +typedef struct _GdlDataRow GdlDataRow; +typedef struct _GdlDataRowClass GdlDataRowClass; +typedef struct _GdlDataRowPrivate GdlDataRowPrivate; + +struct _GdlDataRow { + GObject parent; + + GdlDataRowPrivate *priv; +}; + +struct _GdlDataRowClass { + GObjectClass parent_class; +}; + +GType gdl_data_row_get_type (void); +GdlDataRow *gdl_data_row_new (GdlDataView *view, + GtkTreePath *path); +void gdl_data_row_get_size (GdlDataRow *row, + int *text_w, + int *cell_w, + int *total_width, + int *height); +void gdl_data_row_set_show_name (GdlDataRow *row, + gboolean show_name); +void gdl_data_row_layout (GdlDataRow *row, + GdkRectangle *alloc); +void gdl_data_row_render (GdlDataRow *row, + GdkDrawable *drawable, + GdkRectangle *expose_area, + GtkCellRendererState flags); +GdlDataRow *gdl_data_row_at (GdlDataRow *row, + int x, + int y); +gboolean gdl_data_row_event (GdlDataRow *row, + GdkEvent *event, + GtkCellEditable **editable_widget); +void gdl_data_row_get_cell_area (GdlDataRow *row, + GdkRectangle *rect); +void gdl_data_row_set_split (GdlDataRow *row, + int split); +void gdl_data_row_set_selected (GdlDataRow *row, + gboolean selected); +void gdl_data_row_set_focused (GdlDataRow *row, + gboolean focused); +const char *gdl_data_row_get_title (GdlDataRow *row); + + +G_END_DECLS + +#endif diff --git a/src/libgdl/gdl-data-view.c b/src/libgdl/gdl-data-view.c new file mode 100644 index 000000000..81e1795f7 --- /dev/null +++ b/src/libgdl/gdl-data-view.c @@ -0,0 +1,526 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-i18n.h" +#include "gdl-tools.h" +#include "gdl-data-view.h" +#include "gdl-data-frame.h" + +#include "tree-expand.xpm" +#include "tree-contract.xpm" + +struct _GdlDataViewPrivate { + GList *frames; + GList *rows; + GList *widgets; + + GdlDataFrame *selected_frame; + GdlDataRow *selected_row; + + GtkCellEditable *editable; + + GdkPixbuf *close_pixbuf; + GdkPixbuf *expand_pixbuf; + GdkPixbuf *contract_pixbuf; +}; + +typedef struct { + GtkWidget *widget; + int x, y, height, width; +} ChildWidget; + +static void gdl_data_view_instance_init (GdlDataView *dv); +static void gdl_data_view_class_init (GdlDataViewClass *klass); + +GDL_CLASS_BOILERPLATE (GdlDataView, gdl_data_view, GtkLayout, GTK_TYPE_LAYOUT); + + +#define GRID_SPACING 15 + +static void +paint_grid (GtkWidget *widget, GdkDrawable *drawable, + int offset_x, int offset_y, int width, int height) +{ + GdlDataView *dv; + int x; + int y; + + g_return_if_fail (GDL_IS_DATA_VIEW (widget)); + dv = GDL_DATA_VIEW (widget); + + x = offset_x + ((GRID_SPACING - (offset_x % GRID_SPACING)) % GRID_SPACING); + + /* Draw grid points */ + for (; x < width; x += GRID_SPACING) { + y = offset_y + ((GRID_SPACING - (offset_y % GRID_SPACING)) % GRID_SPACING); + + for (; y < height; y += GRID_SPACING) { + gdk_draw_point (drawable, + widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + x, y); + } + } +} + +static void +expose_frames (GdlDataView *view, GdkEventExpose *event) +{ + GList *l; + + for (l = view->priv->frames; l != NULL; l = l->next) { + GdkRectangle intersect; + GdlDataFrame *frame = GDL_DATA_FRAME (l->data); + if (gdk_rectangle_intersect (&frame->area, + &event->area, + &intersect)) { + gdl_data_frame_draw (GDL_DATA_FRAME (l->data), + GTK_LAYOUT(view)->bin_window, + &intersect); + } + } +} + +static void +expose_widgets (GdlDataView *view, GdkEventExpose *event) +{ + GList *l; + + for (l = view->priv->widgets; l != NULL; l = l->next) { + ChildWidget *child = l->data; + gtk_container_propagate_expose (GTK_CONTAINER (view), + child->widget, event); + } +} + +static gboolean +gdl_data_view_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + if (GTK_WIDGET_DRAWABLE (widget)) { + if (event->window == GTK_LAYOUT (widget)->bin_window) { + paint_grid (widget, GTK_LAYOUT (widget)->bin_window, + event->area.x, event->area.y, + event->area.width, event->area.height); + expose_frames (GDL_DATA_VIEW (widget), event); + expose_widgets (GDL_DATA_VIEW (widget), event); + return TRUE; + } else { + GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + } + } + + return FALSE; +} + +static GdlDataFrame * +frame_at (GdlDataView *dv, int x, int y) +{ + GList *l; + for (l = dv->priv->frames; l != NULL; l = l->next) { + GdlDataFrame *frame = l->data; + if (x >= frame->area.x && x <= frame->area.x + frame->area.width + && y >= frame->area.y && y <= frame->area.y + frame->area.height) { + return frame; + } + } + return NULL; +} + +static GdlDataRow * +row_at (GdlDataView *view, int x, int y) +{ + GList *l; + GdlDataRow *ret = NULL; + for (l = view->priv->rows; l != NULL; l = l->next) { + GdlDataRow *row = l->data; + ret = gdl_data_row_at (row, x, y); + if (ret) break; + } + return ret; +} + +static void +gdl_data_view_put (GdlDataView *view, GtkWidget *widget, + int x, int y, int width, int height) +{ + ChildWidget *child = g_new0 (ChildWidget, 1); + + child->widget = widget; + child->x = x; + child->y = y; + child->width = width; + child->height = height; + + view->priv->widgets = g_list_append (view->priv->widgets, child); + + if (GTK_WIDGET_REALIZED (view)) { + gtk_widget_set_parent_window (child->widget, + GTK_LAYOUT (view)->bin_window); + } + + gtk_widget_set_parent (child->widget, GTK_WIDGET (view)); +} + +static void +stop_editing (GdlDataView *dv) +{ + if (dv->priv->editable) { + gtk_cell_editable_editing_done (dv->priv->editable); + gtk_cell_editable_remove_widget (dv->priv->editable); + } +} + +static void +remove_widget_cb (GtkCellEditable *cell_editable, GdlDataView *view) +{ + if (view->priv->editable) { + view->priv->editable = NULL; + gdl_data_row_set_focused (view->priv->selected_row, FALSE); + gtk_widget_grab_focus (GTK_WIDGET (view)); + gtk_container_remove (GTK_CONTAINER (view), + GTK_WIDGET (cell_editable)); + } +} + +static gboolean +button_press_event_cb (GdlDataView *dv, GdkEventButton *event, gpointer data) +{ + GdlDataFrame *frame; + GdlDataRow *row; + gboolean ret = FALSE; + + stop_editing (dv); + + if (event->type == GDK_BUTTON_PRESS) { + frame = frame_at (dv, event->x, event->y); + if (frame) { + if (dv->priv->selected_frame) { + gdl_data_frame_set_selected (dv->priv->selected_frame, FALSE); + } + gdl_data_frame_set_selected (frame, TRUE); + dv->priv->selected_frame = frame; + } + + row = row_at (dv, event->x, event->y); + if (row) { + GtkCellEditable *editable; + + if (dv->priv->selected_row) { + gdl_data_row_set_selected (dv->priv->selected_row, + FALSE); + } + dv->priv->selected_row = row; + gdl_data_row_set_selected (row, TRUE); + ret = gdl_data_row_event (row, (GdkEvent*)event, + &editable); + if (editable) { + GdkRectangle area; + dv->priv->editable = editable; + gtk_cell_editable_start_editing (editable, + (GdkEvent*)event); + + gdl_data_row_get_cell_area (row, &area); + gdl_data_view_put (dv, + GTK_WIDGET (editable), + area.x, + area.y, + area.width, + area.height); + + gtk_widget_grab_focus (GTK_WIDGET (editable)); + dv->priv->editable = editable; + gdl_data_row_set_focused (row, TRUE); + + g_signal_connect + (G_OBJECT (editable), + "remove_widget", + G_CALLBACK (remove_widget_cb), dv); + } + } + } + + return ret; +} + +static void +gdl_data_view_instance_init (GdlDataView *dv) +{ + GTK_WIDGET_SET_FLAGS (dv, GTK_CAN_FOCUS); + dv->priv = g_new0 (GdlDataViewPrivate, 1); + + g_signal_connect (G_OBJECT (dv), "button_press_event", + G_CALLBACK (button_press_event_cb), + NULL); + + dv->priv->close_pixbuf = gtk_widget_render_icon (GTK_WIDGET (dv), + "gtk-close", + GTK_ICON_SIZE_MENU, + "gdl-data-view-close"); + + dv->priv->expand_pixbuf = + gdk_pixbuf_new_from_xpm_data ((const char **)tree_expand_xpm); + + dv->priv->contract_pixbuf = + gdk_pixbuf_new_from_xpm_data ((const char **)tree_contract_xpm); +} + +static void +gdl_data_view_realize (GtkWidget *widget) +{ + GList *l; + GdlDataView *view = GDL_DATA_VIEW (widget); + + GDL_CALL_PARENT (GTK_WIDGET_CLASS, realize, (widget)); + + for (l = view->priv->widgets; l != NULL; l = l->next) { + ChildWidget *child = l->data; + gtk_widget_set_parent_window (child->widget, + GTK_LAYOUT (view)->bin_window); + } +} + +static void +gdl_data_view_size_request (GtkWidget *widget, GtkRequisition *req) +{ + GList *l; + + req->width = req->height = 0; + + for (l = GDL_DATA_VIEW (widget)->priv->widgets; l != NULL; l = l->next) { + GtkRequisition child_req; + ChildWidget *child = l->data; + + gtk_widget_size_request (child->widget, &child_req); + } +} + + +static void +gdl_data_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc) +{ + GdlDataView *view = GDL_DATA_VIEW (widget); + GList *l; +; + for (l = view->priv->widgets; l != NULL; l = l->next) { + ChildWidget *child = l->data; + GtkAllocation child_alloc; + + child_alloc.x = child->x; + child_alloc.y = child->y; + child_alloc.width = child->width; + child_alloc.height = child->height; + + gtk_widget_size_allocate (child->widget, &child_alloc); + } + GDL_CALL_PARENT (GTK_WIDGET_CLASS, size_allocate, (widget, alloc)); +} + +static void +gdl_data_view_forall (GtkContainer *container, gboolean include_internals, + GtkCallback callback, gpointer callback_data) +{ + GdlDataView *view = GDL_DATA_VIEW (container); + GList *l; + + for (l = view->priv->widgets; l != NULL; l = l->next) { + ChildWidget *child = l->data; + (*callback) (child->widget, callback_data); + } +} + +static void +gdl_data_view_remove (GtkContainer *container, GtkWidget *widget) +{ + GList *l; + GdlDataView *view = GDL_DATA_VIEW (container); + + for (l = view->priv->widgets; l != NULL; l = l->next) { + ChildWidget *child = l->data; + if (child->widget == widget) { + gtk_widget_unparent (widget); + view->priv->widgets = + g_list_remove_link (view->priv->widgets, l); + g_list_free_1 (l); + g_free (child); + return; + } + } +} + +static void +gdl_data_view_destroy (GtkObject *obj) +{ + GdlDataView *dv = GDL_DATA_VIEW (obj); + + stop_editing (dv); + + if (dv->priv) { + GList *l; + for (l = dv->priv->frames; l != NULL; l = l->next) { + g_object_unref (G_OBJECT (l->data)); + } + g_list_free (dv->priv->frames); + + g_object_unref (dv->priv->close_pixbuf); + g_object_unref (dv->priv->expand_pixbuf); + g_object_unref (dv->priv->contract_pixbuf); + + g_free (dv->priv); + dv->priv = NULL; + } + GDL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (obj)); +} + +static void +gdl_data_view_class_init (GdlDataViewClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *)klass; + GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; + GtkContainerClass *container_class = (GtkContainerClass *)klass; + + parent_class = gtk_type_class (GTK_TYPE_LAYOUT); + + container_class->forall = gdl_data_view_forall; + container_class->remove = gdl_data_view_remove; + + widget_class->expose_event = gdl_data_view_expose; + widget_class->realize = gdl_data_view_realize; + /* FIXME: unrealize */ + widget_class->size_request = gdl_data_view_size_request; + widget_class->size_allocate = gdl_data_view_size_allocate; + object_class->destroy = gdl_data_view_destroy; + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_int ("expander-size", + _("Expander Size"), + _("Size of the expander arrow."), + 0, + G_MAXINT, + 10, + G_PARAM_READABLE)); +} + +GtkWidget * +gdl_data_view_new (void) +{ + GdlDataView *dv; + dv = g_object_new (gdl_data_view_get_type (), NULL); + return GTK_WIDGET (dv); +} + +void +gdl_data_view_set_model (GdlDataView *dv, GdlDataModel *model) +{ + GtkTreePath *path; + GdlDataIter iter; + gboolean iter_valid; + int x = 5; + + dv->model = model; + + path = gtk_tree_path_new_from_string ("0"); + + iter_valid = gdl_data_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + while (iter_valid) { + GdlDataFrame *frame; + GdlDataRow *row; + + path = gdl_data_model_get_path (model, &iter); + + row = gdl_data_row_new (dv, path); + frame = gdl_data_frame_new (dv, row); + gdl_data_frame_set_position (frame, x, 5); + + dv->priv->frames = g_list_append (dv->priv->frames, + frame); + dv->priv->rows = g_list_append (dv->priv->rows, row); + + gtk_tree_path_free (path); + + x += 150; + + iter_valid = gdl_data_model_iter_next (model, &iter); + } +} + +void +gdl_data_view_layout (GdlDataView *view) +{ + GList *l; + for (l = view->priv->frames; l != NULL; l = l->next) { + gdl_data_frame_layout (GDL_DATA_FRAME (l->data)); + } +} + +GdkPixbuf * +gdl_data_view_get_close_pixbuf (GdlDataView *view) +{ + return view->priv->close_pixbuf; +} + +void +gdl_data_view_set_close_pixbuf (GdlDataView *view, GdkPixbuf *pixbuf) +{ + if (view->priv->close_pixbuf) { + g_object_unref (view->priv->close_pixbuf); + } + + view->priv->close_pixbuf = g_object_ref (pixbuf); +} + +GdkPixbuf * +gdl_data_view_get_expand_pixbuf (GdlDataView *view) +{ + return view->priv->expand_pixbuf; +} + +void +gdl_data_view_set_expand_pixbuf (GdlDataView *view, GdkPixbuf *pixbuf) +{ + if (view->priv->expand_pixbuf) { + g_object_unref (view->priv->expand_pixbuf); + } + + view->priv->expand_pixbuf = g_object_ref (pixbuf); +} + +GdkPixbuf * +gdl_data_view_get_contract_pixbuf (GdlDataView *view) +{ + return view->priv->contract_pixbuf; +} + +void +gdl_data_view_set_contract_pixbuf (GdlDataView *view, GdkPixbuf *pixbuf) +{ + if (view->priv->contract_pixbuf) { + g_object_unref (view->priv->contract_pixbuf); + } + + view->priv->contract_pixbuf = g_object_ref (pixbuf); +} diff --git a/src/libgdl/gdl-data-view.h b/src/libgdl/gdl-data-view.h new file mode 100644 index 000000000..a29132074 --- /dev/null +++ b/src/libgdl/gdl-data-view.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2001 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GDL_DATA_VIEW_H +#define GDL_DATA_VIEW_H + +#include +#include + +G_BEGIN_DECLS + +#define GDL_TYPE_DATA_VIEW (gdl_data_view_get_type ()) +#define GDL_DATA_VIEW(obj) (GTK_CHECK_CAST ((obj), GDL_TYPE_DATA_VIEW, GdlDataView)) +#define GDL_DATA_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) +#define GDL_IS_DATA_VIEW(obj) (GTK_CHECK_TYPE ((obj), GDL_TYPE_DATA_VIEW)) +#define GDL_IS_DATA_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_VIEW)) +#define GDL_DATA_VIEW_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) + +typedef struct _GdlDataView GdlDataView; +typedef struct _GdlDataViewClass GdlDataViewClass; +typedef struct _GdlDataViewPrivate GdlDataViewPrivate; + +#define GDL_POINT_IN(x1,y1,r) ((x1) >= (r)->x && x1 < (r)->x + (r)->width && (y1) >= (r)->y && y1 < (r)->y + (r)->height) + +struct _GdlDataView { + GtkLayout layout; + + GdlDataModel *model; + + GdlDataViewPrivate *priv; +}; + +struct _GdlDataViewClass { + GtkLayoutClass parent_class; +}; + +GtkType gdl_data_view_get_type (void); +GtkWidget *gdl_data_view_new (void); +void gdl_data_view_set_model (GdlDataView *view, + GdlDataModel *model); +void gdl_data_view_layout (GdlDataView *view); +GdkPixbuf *gdl_data_view_get_close_pixbuf (GdlDataView *view); +void gdl_data_view_set_close_pixbuf (GdlDataView *view, + GdkPixbuf *pixbuf); +GdkPixbuf *gdl_data_view_get_expand_pixbuf (GdlDataView *view); +void gdl_data_view_set_expand_pixbuf (GdlDataView *view, + GdkPixbuf *pixbuf); +GdkPixbuf *gdl_data_view_get_contract_pixbuf (GdlDataView *view); +void gdl_data_view_set_contract_pixbuf (GdlDataView *view, + GdkPixbuf *pixbuf); + +#endif diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 2513313ef..2101d9621 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -293,10 +293,10 @@ gdl_dock_item_grip_set_property (GObject *object, case PROP_ITEM: grip->item = g_value_get_object (value); if (grip->item) { - g_signal_connect (grip->item, "notify::long_name", + g_signal_connect (grip->item, "notify::long-name", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); - g_signal_connect (grip->item, "notify::stock_id", + g_signal_connect (grip->item, "notify::stock-id", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); g_signal_connect (grip->item, "notify::behavior", diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index c01737636..db31ade30 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -1257,8 +1257,9 @@ gdl_dock_item_dock (GdlDockObject *object, GdlDockPlacement position, GValue *other_data) { - GdlDockObject *new_parent, *parent; - gboolean add_ourselves_first; + GdlDockObject *new_parent = NULL; + GdlDockObject *parent, *requestor_parent; + gboolean add_ourselves_first = FALSE; guint available_space=0; gint pref_size=-1; @@ -1372,11 +1373,16 @@ gdl_dock_item_dock (GdlDockObject *object, pref_size = req.width; break; case GDL_DOCK_CENTER: - new_parent = g_object_new (gdl_dock_object_type_from_nick ("notebook"), - "preferred-width", object_req.width, - "preferred-height", object_req.height, - NULL); - add_ourselves_first = TRUE; + /* If the parent is already a DockNotebook, we don't need + to create a new one. */ + if (!GDL_IS_DOCK_NOTEBOOK (parent)) + { + new_parent = g_object_new (gdl_dock_object_type_from_nick ("notebook"), + "preferred-width", object_req.width, + "preferred-height", object_req.height, + NULL); + add_ourselves_first = TRUE; + } break; default: { @@ -1396,9 +1402,12 @@ gdl_dock_item_dock (GdlDockObject *object, gdl_dock_object_freeze (parent); /* ref ourselves since we could be destroyed when detached */ - g_object_ref (object); - GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_REFLOW); - gdl_dock_object_detach (object, FALSE); + if (new_parent) + { + g_object_ref (object); + GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_REFLOW); + gdl_dock_object_detach (object, FALSE); + } /* freeze the new parent, so reduce won't get called before it's actually added to our parent */ @@ -1424,7 +1433,14 @@ gdl_dock_item_dock (GdlDockObject *object, /* show automatic object */ if (gtk_widget_get_visible (GTK_WIDGET (object))) + { gtk_widget_show (GTK_WIDGET (new_parent)); + GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_IN_REFLOW); + gdl_dock_object_thaw (new_parent); + } + else // If the parent is already a DockNotebook, we don't need + // to create a new one. + gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (requestor)); /* use extra docking parameter */ if (position != GDL_DOCK_CENTER && other_data && @@ -1437,10 +1453,17 @@ gdl_dock_item_dock (GdlDockObject *object, g_object_set (G_OBJECT (new_parent), "position", splitpos, NULL); } - GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_IN_REFLOW); g_object_unref (object); - gdl_dock_object_thaw (new_parent); + requestor_parent = gdl_dock_object_get_parent_object (requestor); + if (GDL_IS_DOCK_NOTEBOOK (requestor_parent)) + { + /* Activate the page we just added */ + GdlDockItem* notebook = GDL_DOCK_ITEM (gdl_dock_object_get_parent_object (requestor)); + gtk_notebook_set_page (GTK_NOTEBOOK (notebook->child), + gtk_notebook_page_num (GTK_NOTEBOOK (notebook->child), GTK_WIDGET (requestor))); + } + if (parent) gdl_dock_object_thaw (parent); diff --git a/src/libgdl/gdl-dock-layout.c b/src/libgdl/gdl-dock-layout.c new file mode 100644 index 000000000..c3b0a4dac --- /dev/null +++ b/src/libgdl/gdl-dock-layout.c @@ -0,0 +1,1411 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2002 Gustavo Giráldez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-i18n.h" +#include +#include +#include +#include +#include + +#include "gdl-dock-layout.h" +#include "gdl-tools.h" +#include "gdl-dock-placeholder.h" + + +/* ----- Private variables ----- */ + +enum { + PROP_0, + PROP_MASTER, + PROP_DIRTY +}; + +#define ROOT_ELEMENT "dock-layout" +#define DEFAULT_LAYOUT "__default__" +#define LAYOUT_ELEMENT_NAME "layout" +#define NAME_ATTRIBUTE_NAME "name" + +#define LAYOUT_GLADE_FILE "layout.glade" + +enum { + COLUMN_NAME, + COLUMN_SHOW, + COLUMN_LOCKED, + COLUMN_ITEM +}; + +#define COLUMN_EDITABLE COLUMN_SHOW + +struct _GdlDockLayoutPrivate { + xmlDocPtr doc; + + /* layout list models */ + GtkListStore *items_model; + GtkListStore *layouts_model; + + /* idle control */ + gboolean idle_save_pending; +}; + +typedef struct _GdlDockLayoutUIData GdlDockLayoutUIData; + +struct _GdlDockLayoutUIData { + GdlDockLayout *layout; + GtkWidget *locked_check; + GtkTreeSelection *selection; +}; + + +/* ----- Private prototypes ----- */ + +static void gdl_dock_layout_class_init (GdlDockLayoutClass *klass); + +static void gdl_dock_layout_instance_init (GdlDockLayout *layout); + +static void gdl_dock_layout_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static void gdl_dock_layout_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void gdl_dock_layout_dispose (GObject *object); + +static void gdl_dock_layout_build_doc (GdlDockLayout *layout); + +static xmlNodePtr gdl_dock_layout_find_layout (GdlDockLayout *layout, + const gchar *name); + +static void gdl_dock_layout_build_models (GdlDockLayout *layout); + + +/* ----- Private implementation ----- */ + +GDL_CLASS_BOILERPLATE (GdlDockLayout, gdl_dock_layout, GObject, G_TYPE_OBJECT); + +static void +gdl_dock_layout_class_init (GdlDockLayoutClass *klass) +{ + GObjectClass *g_object_class = (GObjectClass *) klass; + + g_object_class->set_property = gdl_dock_layout_set_property; + g_object_class->get_property = gdl_dock_layout_get_property; + g_object_class->dispose = gdl_dock_layout_dispose; + + g_object_class_install_property ( + g_object_class, PROP_MASTER, + g_param_spec_object ("master", _("Master"), + _("GdlDockMaster object which the layout object " + "is attached to"), + GDL_TYPE_DOCK_MASTER, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + g_object_class, PROP_DIRTY, + g_param_spec_boolean ("dirty", _("Dirty"), + _("True if the layouts have changed and need to be " + "saved to a file"), + FALSE, + G_PARAM_READABLE)); +} + +static void +gdl_dock_layout_instance_init (GdlDockLayout *layout) +{ + layout->master = NULL; + layout->dirty = FALSE; + layout->_priv = g_new0 (GdlDockLayoutPrivate, 1); + layout->_priv->idle_save_pending = FALSE; + + gdl_dock_layout_build_models (layout); +} + +static void +gdl_dock_layout_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdlDockLayout *layout = GDL_DOCK_LAYOUT (object); + + switch (prop_id) { + case PROP_MASTER: + gdl_dock_layout_attach (layout, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + }; +} + +static void +gdl_dock_layout_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdlDockLayout *layout = GDL_DOCK_LAYOUT (object); + + switch (prop_id) { + case PROP_MASTER: + g_value_set_object (value, layout->master); + break; + case PROP_DIRTY: + g_value_set_boolean (value, layout->dirty); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + }; +} + +static void +gdl_dock_layout_dispose (GObject *object) +{ + GdlDockLayout *layout; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDL_IS_DOCK_LAYOUT (object)); + + layout = GDL_DOCK_LAYOUT (object); + + if (layout->master) + gdl_dock_layout_attach (layout, NULL); + + if (layout->_priv) { + if (layout->_priv->idle_save_pending) { + layout->_priv->idle_save_pending = FALSE; + g_idle_remove_by_data (layout); + } + + if (layout->_priv->doc) { + xmlFreeDoc (layout->_priv->doc); + layout->_priv->doc = NULL; + } + + if (layout->_priv->items_model) { + g_object_unref (layout->_priv->items_model); + g_object_unref (layout->_priv->layouts_model); + layout->_priv->items_model = NULL; + layout->_priv->layouts_model = NULL; + } + + xmlFreeDoc(layout->_priv->doc); + g_free (layout->_priv); + layout->_priv = NULL; + } +} + +static void +gdl_dock_layout_build_doc (GdlDockLayout *layout) +{ + g_return_if_fail (layout->_priv->doc == NULL); + + layout->_priv->doc = xmlNewDoc (BAD_CAST "1.0"); + layout->_priv->doc->children = xmlNewDocNode (layout->_priv->doc, NULL, + BAD_CAST ROOT_ELEMENT, NULL); +} + +static xmlNodePtr +gdl_dock_layout_find_layout (GdlDockLayout *layout, + const gchar *name) +{ + xmlNodePtr node; + gboolean found = FALSE; + + g_return_val_if_fail (layout != NULL, NULL); + + if (!layout->_priv->doc) + return NULL; + + /* get document root */ + node = layout->_priv->doc->children; + for (node = node->children; node; node = node->next) { + xmlChar *layout_name; + + if (strcmp ((char*)node->name, LAYOUT_ELEMENT_NAME)) + /* skip non-layout element */ + continue; + + /* we want the first layout */ + if (!name) + break; + + layout_name = xmlGetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME); + if (!strcmp (name, (char*)layout_name)) + found = TRUE; + xmlFree (layout_name); + + if (found) + break; + }; + return node; +} + +static void +gdl_dock_layout_build_models (GdlDockLayout *layout) +{ + if (!layout->_priv->items_model) { + layout->_priv->items_model = gtk_list_store_new (4, + G_TYPE_STRING, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, + G_TYPE_POINTER); + gtk_tree_sortable_set_sort_column_id ( + GTK_TREE_SORTABLE (layout->_priv->items_model), + COLUMN_NAME, GTK_SORT_ASCENDING); + } + + if (!layout->_priv->layouts_model) { + layout->_priv->layouts_model = gtk_list_store_new (2, G_TYPE_STRING, + G_TYPE_BOOLEAN); + gtk_tree_sortable_set_sort_column_id ( + GTK_TREE_SORTABLE (layout->_priv->layouts_model), + COLUMN_NAME, GTK_SORT_ASCENDING); + } +} + +static void +build_list (GdlDockObject *object, GList **list) +{ + /* add only items, not toplevels */ + if (GDL_IS_DOCK_ITEM (object)) + *list = g_list_prepend (*list, object); +} + +static void +update_items_model (GdlDockLayout *layout) +{ + GList *items, *l; + GtkTreeIter iter; + GtkListStore *store; + gchar *long_name; + gboolean locked; + + g_return_if_fail (layout != NULL); + g_return_if_fail (layout->_priv->items_model != NULL); + + if (!layout->master) + return; + + /* build items list */ + items = NULL; + gdl_dock_master_foreach (layout->master, (GFunc) build_list, &items); + + /* walk the current model */ + store = layout->_priv->items_model; + + /* update items model data after a layout load */ + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gboolean valid = TRUE; + + while (valid) { + GdlDockItem *item; + + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, + COLUMN_ITEM, &item, + -1); + if (item) { + /* look for the object in the items list */ + for (l = items; l && l->data != item; l = l->next); + + if (l) { + /* found, update data */ + g_object_get (item, + "long-name", &long_name, + "locked", &locked, + NULL); + gtk_list_store_set (store, &iter, + COLUMN_NAME, long_name, + COLUMN_SHOW, GDL_DOCK_OBJECT_ATTACHED (item), + COLUMN_LOCKED, locked, + -1); + g_free (long_name); + + /* remove the item from the linked list and keep on walking the model */ + items = g_list_delete_link (items, l); + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); + + } else { + /* not found, which means the item has been removed */ + valid = gtk_list_store_remove (store, &iter); + + } + + } else { + /* not a valid row */ + valid = gtk_list_store_remove (store, &iter); + } + } + } + + /* add any remaining objects */ + for (l = items; l; l = l->next) { + GdlDockObject *object = l->data; + + g_object_get (object, + "long-name", &long_name, + "locked", &locked, + NULL); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + COLUMN_ITEM, object, + COLUMN_NAME, long_name, + COLUMN_SHOW, GDL_DOCK_OBJECT_ATTACHED (object), + COLUMN_LOCKED, locked, + -1); + g_free (long_name); + } + + g_list_free (items); +} + +static void +update_layouts_model (GdlDockLayout *layout) +{ + GList *items, *l; + GtkTreeIter iter; + + g_return_if_fail (layout != NULL); + g_return_if_fail (layout->_priv->layouts_model != NULL); + + /* build layouts list */ + gtk_list_store_clear (layout->_priv->layouts_model); + items = gdl_dock_layout_get_layouts (layout, FALSE); + for (l = items; l; l = l->next) { + gtk_list_store_append (layout->_priv->layouts_model, &iter); + gtk_list_store_set (layout->_priv->layouts_model, &iter, + COLUMN_NAME, l->data, COLUMN_EDITABLE, TRUE, + -1); + g_free (l->data); + }; + g_list_free (items); +} + + +/* ------- UI functions & callbacks ------ */ + +static void +load_layout_cb (GtkWidget *w, + gpointer data) +{ + GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; + + GtkTreeModel *model; + GtkTreeIter iter; + GdlDockLayout *layout = ui_data->layout; + gchar *name; + + g_return_if_fail (layout != NULL); + + if (gtk_tree_selection_get_selected (ui_data->selection, &model, &iter)) { + gtk_tree_model_get (model, &iter, + COLUMN_NAME, &name, + -1); + gdl_dock_layout_load_layout (layout, name); + g_free (name); + } +} + +static void +delete_layout_cb (GtkWidget *w, gpointer data) +{ + GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; + + GtkTreeModel *model; + GtkTreeIter iter; + GdlDockLayout *layout = ui_data->layout; + gchar *name; + + g_return_if_fail (layout != NULL); + + if (gtk_tree_selection_get_selected (ui_data->selection, &model, &iter)) { + gtk_tree_model_get (model, &iter, + COLUMN_NAME, &name, + -1); + gdl_dock_layout_delete_layout (layout, name); + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + g_free (name); + }; +} + +static void +show_toggled_cb (GtkCellRendererToggle *renderer, + gchar *path_str, + gpointer data) +{ + GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; + + GdlDockLayout *layout = ui_data->layout; + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + gboolean value; + GdlDockItem *item; + + g_return_if_fail (layout != NULL); + + model = GTK_TREE_MODEL (layout->_priv->items_model); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, + COLUMN_SHOW, &value, + COLUMN_ITEM, &item, + -1); + + value = !value; + if (value) + gdl_dock_item_show_item (item); + else + gdl_dock_item_hide_item (item); + + gtk_tree_path_free (path); +} + +static void +all_locked_toggled_cb (GtkWidget *widget, + gpointer data) +{ + GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; + GdlDockMaster *master; + gboolean locked; + + g_return_if_fail (ui_data->layout != NULL); + master = ui_data->layout->master; + g_return_if_fail (master != NULL); + + locked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + g_object_set (master, "locked", locked ? 1 : 0, NULL); +} + +static void +layout_ui_destroyed (GtkWidget *widget, + gpointer user_data) +{ + GdlDockLayoutUIData *ui_data; + + /* widget is the GtkContainer */ + ui_data = g_object_get_data (G_OBJECT (widget), "ui_data"); + if (ui_data) { + if (ui_data->layout) { + if (ui_data->layout->master) + /* disconnet the notify handler */ + g_signal_handlers_disconnect_matched (ui_data->layout->master, + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, + ui_data); + + g_object_remove_weak_pointer (G_OBJECT (ui_data->layout), + (gpointer *) &ui_data->layout); + ui_data->layout = NULL; + } + g_object_set_data (G_OBJECT (widget), "ui_data", NULL); + g_free (ui_data); + } +} + +static void +master_locked_notify_cb (GdlDockMaster *master, + GParamSpec *pspec, + gpointer user_data) +{ + GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) user_data; + gint locked; + + g_object_get (master, "locked", &locked, NULL); + if (locked == -1) { + gtk_toggle_button_set_inconsistent ( + GTK_TOGGLE_BUTTON (ui_data->locked_check), TRUE); + } + else { + gtk_toggle_button_set_inconsistent ( + GTK_TOGGLE_BUTTON (ui_data->locked_check), FALSE); + gtk_toggle_button_set_active ( + GTK_TOGGLE_BUTTON (ui_data->locked_check), (locked == 1)); + } +} + +static GladeXML * +load_interface (const gchar *top_widget) +{ + GladeXML *gui; + gchar *gui_file; + + /* load ui */ + gui_file = g_build_filename (GDL_GLADEDIR, LAYOUT_GLADE_FILE, NULL); + gui = glade_xml_new (gui_file, top_widget, GETTEXT_PACKAGE); + g_free (gui_file); + if (!gui) { + /* FIXME: pop up an error dialog */ + g_warning (_("Could not load layout user interface file '%s'"), + LAYOUT_GLADE_FILE); + return NULL; + }; + return gui; +} + +static GtkWidget * +gdl_dock_layout_construct_items_ui (GdlDockLayout *layout) +{ + GladeXML *gui; + GtkWidget *container; + GtkWidget *items_list; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + GdlDockLayoutUIData *ui_data; + + /* load the interface if it wasn't provided */ + gui = load_interface ("items_vbox"); + + if (!gui) + return NULL; + + /* get the container */ + container = glade_xml_get_widget (gui, "items_vbox"); + + ui_data = g_new0 (GdlDockLayoutUIData, 1); + ui_data->layout = layout; + g_object_add_weak_pointer (G_OBJECT (layout), + (gpointer *) &ui_data->layout); + g_object_set_data (G_OBJECT (container), "ui_data", ui_data); + + /* get ui widget references */ + ui_data->locked_check = glade_xml_get_widget (gui, "locked_check"); + items_list = glade_xml_get_widget (gui, "items_list"); + + /* locked check connections */ + g_signal_connect (ui_data->locked_check, "toggled", + (GCallback) all_locked_toggled_cb, ui_data); + if (layout->master) { + g_signal_connect (layout->master, "notify::locked", + (GCallback) master_locked_notify_cb, ui_data); + /* force update now */ + master_locked_notify_cb (layout->master, NULL, ui_data); + } + + /* set models */ + gtk_tree_view_set_model (GTK_TREE_VIEW (items_list), + GTK_TREE_MODEL (layout->_priv->items_model)); + + /* construct list views */ + renderer = gtk_cell_renderer_toggle_new (); + g_signal_connect (renderer, "toggled", + G_CALLBACK (show_toggled_cb), ui_data); + column = gtk_tree_view_column_new_with_attributes (_("Visible"), + renderer, + "active", COLUMN_SHOW, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (items_list), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Item"), + renderer, + "text", COLUMN_NAME, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (items_list), column); + + /* connect signals */ + g_signal_connect (container, "destroy", (GCallback) layout_ui_destroyed, NULL); + + g_object_unref (gui); + + return container; +} + +static void +cell_edited_cb (GtkCellRendererText *cell, + const gchar *path_string, + const gchar *new_text, + gpointer data) +{ + GdlDockLayoutUIData *ui_data = data; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gchar *name; + xmlNodePtr node; + + model = GTK_TREE_MODEL (ui_data->layout->_priv->layouts_model); + path = gtk_tree_path_new_from_string (path_string); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, COLUMN_NAME, &name, -1); + + node = gdl_dock_layout_find_layout (ui_data->layout, name); + g_free (name); + g_return_if_fail (node != NULL); + + xmlSetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME, BAD_CAST new_text); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_NAME, new_text, + COLUMN_EDITABLE, TRUE, -1); + + gdl_dock_layout_save_layout (ui_data->layout, new_text); + + gtk_tree_path_free (path); +} + +static GtkWidget * +gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) +{ + GladeXML *gui; + GtkWidget *container; + GtkWidget *layouts_list; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + GdlDockLayoutUIData *ui_data; + + /* load the interface if it wasn't provided */ + gui = load_interface ("layouts_vbox"); + + if (!gui) + return NULL; + + /* get the container */ + container = glade_xml_get_widget (gui, "layouts_vbox"); + + ui_data = g_new0 (GdlDockLayoutUIData, 1); + ui_data->layout = layout; + g_object_add_weak_pointer (G_OBJECT (layout), + (gpointer *) &ui_data->layout); + g_object_set_data (G_OBJECT (container), "ui-data", ui_data); + + /* get ui widget references */ + layouts_list = glade_xml_get_widget (gui, "layouts_list"); + + /* set models */ + gtk_tree_view_set_model (GTK_TREE_VIEW (layouts_list), + GTK_TREE_MODEL (layout->_priv->layouts_model)); + + /* construct list views */ + renderer = gtk_cell_renderer_text_new (); + g_signal_connect (G_OBJECT (renderer), "edited", + G_CALLBACK (cell_edited_cb), ui_data); + column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, + "text", COLUMN_NAME, + "editable", COLUMN_EDITABLE, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (layouts_list), column); + + ui_data->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (layouts_list)); + + /* connect signals */ + glade_xml_signal_connect_data (gui, "on_load_button_clicked", + GTK_SIGNAL_FUNC (load_layout_cb), ui_data); + glade_xml_signal_connect_data (gui, "on_delete_button_clicked", + GTK_SIGNAL_FUNC (delete_layout_cb), ui_data); + + g_signal_connect (container, "destroy", (GCallback) layout_ui_destroyed, NULL); + + g_object_unref (gui); + + return container; +} + +static GtkWidget * +gdl_dock_layout_construct_ui (GdlDockLayout *layout) +{ + GtkWidget *container, *child; + + container = gtk_notebook_new (); + gtk_widget_show (container); + + child = gdl_dock_layout_construct_items_ui (layout); + if (child) + gtk_notebook_append_page (GTK_NOTEBOOK (container), + child, + gtk_label_new (_("Dock items"))); + + child = gdl_dock_layout_construct_layouts_ui (layout); + if (child) + gtk_notebook_append_page (GTK_NOTEBOOK (container), + child, + gtk_label_new (_("Saved layouts"))); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (container), 0); + + return container; +} + +/* ----- Save & Load layout functions --------- */ + +#define GDL_DOCK_PARAM_CONSTRUCTION(p) \ + (((p)->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) != 0) + +static GdlDockObject * +gdl_dock_layout_setup_object (GdlDockMaster *master, + xmlNodePtr node, + gint *n_after_params, + GParameter **after_params) +{ + GdlDockObject *object = NULL; + GType object_type; + xmlChar *object_name; + GObjectClass *object_class = NULL; + + GParamSpec **props; + guint n_props, i; + GParameter *params = NULL; + gint n_params = 0; + GValue serialized = { 0, }; + + object_name = xmlGetProp (node, BAD_CAST GDL_DOCK_NAME_PROPERTY); + if (object_name && strlen ((char*)object_name) > 0) { + /* the object must already be bound to the master */ + object = gdl_dock_master_get_object (master, (char*)object_name); + + xmlFree (object_name); + object_type = object ? G_TYPE_FROM_INSTANCE (object) : G_TYPE_NONE; + } + else { + /* the object should be automatic, so create it by + retrieving the object type from the dock registry */ + object_type = gdl_dock_object_type_from_nick ((char*)node->name); + if (object_type == G_TYPE_NONE) { + g_warning (_("While loading layout: don't know how to create " + "a dock object whose nick is '%s'"), node->name); + } + } + + if (object_type == G_TYPE_NONE || !G_TYPE_IS_CLASSED (object_type)) + return NULL; + + object_class = g_type_class_ref (object_type); + props = g_object_class_list_properties (object_class, &n_props); + + /* create parameter slots */ + /* extra parameter is the master */ + params = g_new0 (GParameter, n_props + 1); + *after_params = g_new0 (GParameter, n_props); + *n_after_params = 0; + + /* initialize value used for transformations */ + g_value_init (&serialized, GDL_TYPE_DOCK_PARAM); + + for (i = 0; i < n_props; i++) { + xmlChar *xml_prop; + + /* process all exported properties, skip + GDL_DOCK_NAME_PROPERTY, since named items should + already by in the master */ + if (!(props [i]->flags & GDL_DOCK_PARAM_EXPORT) || + !strcmp (props [i]->name, GDL_DOCK_NAME_PROPERTY)) + continue; + + /* get the property from xml if there is one */ + xml_prop = xmlGetProp (node, BAD_CAST props [i]->name); + if (xml_prop) { + g_value_set_static_string (&serialized, (char*)xml_prop); + + if (!GDL_DOCK_PARAM_CONSTRUCTION (props [i]) && + (props [i]->flags & GDL_DOCK_PARAM_AFTER)) { + (*after_params) [*n_after_params].name = props [i]->name; + g_value_init (&((* after_params) [*n_after_params].value), + props [i]->value_type); + g_value_transform (&serialized, + &((* after_params) [*n_after_params].value)); + (*n_after_params)++; + } + else if (!object || (!GDL_DOCK_PARAM_CONSTRUCTION (props [i]) && object)) { + params [n_params].name = props [i]->name; + g_value_init (&(params [n_params].value), props [i]->value_type); + g_value_transform (&serialized, &(params [n_params].value)); + n_params++; + } + xmlFree (xml_prop); + } + } + g_value_unset (&serialized); + g_free (props); + + if (!object) { + params [n_params].name = GDL_DOCK_MASTER_PROPERTY; + g_value_init (¶ms [n_params].value, GDL_TYPE_DOCK_MASTER); + g_value_set_object (¶ms [n_params].value, master); + n_params++; + + /* construct the object if we have to */ + /* set the master, so toplevels are created correctly and + other objects are bound */ + object = g_object_newv (object_type, n_params, params); + } + else { + /* set the parameters to the existing object */ + for (i = 0; i < n_params; i++) + g_object_set_property (G_OBJECT (object), + params [i].name, + ¶ms [i].value); + } + + /* free the parameters (names are static/const strings) */ + for (i = 0; i < n_params; i++) + g_value_unset (¶ms [i].value); + g_free (params); + + /* finally unref object class */ + g_type_class_unref (object_class); + + return object; +} + +static void +gdl_dock_layout_recursive_build (GdlDockMaster *master, + xmlNodePtr parent_node, + GdlDockObject *parent) +{ + GdlDockObject *object; + xmlNodePtr node; + + g_return_if_fail (master != NULL && parent_node != NULL); + + /* if parent is NULL we should build toplevels */ + for (node = parent_node->children; node; node = node->next) { + GParameter *after_params = NULL; + gint n_after_params = 0, i; + + object = gdl_dock_layout_setup_object (master, node, + &n_after_params, + &after_params); + + if (object) { + gdl_dock_object_freeze (object); + + /* recurse here to catch placeholders */ + gdl_dock_layout_recursive_build (master, node, object); + + if (GDL_IS_DOCK_PLACEHOLDER (object)) + /* placeholders are later attached to the parent */ + gdl_dock_object_detach (object, FALSE); + + /* apply "after" parameters */ + for (i = 0; i < n_after_params; i++) { + g_object_set_property (G_OBJECT (object), + after_params [i].name, + &after_params [i].value); + /* unset and free the value */ + g_value_unset (&after_params [i].value); + } + g_free (after_params); + + /* add the object to the parent */ + if (parent) { + if (GDL_IS_DOCK_PLACEHOLDER (object)) + gdl_dock_placeholder_attach (GDL_DOCK_PLACEHOLDER (object), + parent); + else if (gdl_dock_object_is_compound (parent)) { + gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (object)); + if (GTK_WIDGET_VISIBLE (parent)) + gtk_widget_show (GTK_WIDGET (object)); + } + } + else { + GdlDockObject *controller = gdl_dock_master_get_controller (master); + if (controller != object && GTK_WIDGET_VISIBLE (controller)) + gtk_widget_show (GTK_WIDGET (object)); + } + + /* call reduce just in case any child is missing */ + if (gdl_dock_object_is_compound (object)) + gdl_dock_object_reduce (object); + + gdl_dock_object_thaw (object); + } + } +} + +static void +_gdl_dock_layout_foreach_detach (GdlDockObject *object) +{ + gdl_dock_object_detach (object, TRUE); +} + +static void +gdl_dock_layout_foreach_toplevel_detach (GdlDockObject *object) +{ + gtk_container_foreach (GTK_CONTAINER (object), + (GtkCallback) _gdl_dock_layout_foreach_detach, + NULL); +} + +static void +gdl_dock_layout_load (GdlDockMaster *master, xmlNodePtr node) +{ + g_return_if_fail (master != NULL && node != NULL); + + /* start by detaching all items from the toplevels */ + gdl_dock_master_foreach_toplevel (master, TRUE, + (GFunc) gdl_dock_layout_foreach_toplevel_detach, + NULL); + + gdl_dock_layout_recursive_build (master, node, NULL); +} + +static void +gdl_dock_layout_foreach_object_save (GdlDockObject *object, + gpointer user_data) +{ + struct { + xmlNodePtr where; + GHashTable *placeholders; + } *info = user_data, info_child; + + xmlNodePtr node; + guint n_props, i; + GParamSpec **props; + GValue attr = { 0, }; + + g_return_if_fail (object != NULL && GDL_IS_DOCK_OBJECT (object)); + g_return_if_fail (info->where != NULL); + + node = xmlNewChild (info->where, + NULL, /* ns */ + BAD_CAST gdl_dock_object_nick_from_type (G_TYPE_FROM_INSTANCE (object)), + BAD_CAST NULL); /* contents */ + + /* get object exported attributes */ + props = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), + &n_props); + g_value_init (&attr, GDL_TYPE_DOCK_PARAM); + for (i = 0; i < n_props; i++) { + GParamSpec *p = props [i]; + + if (p->flags & GDL_DOCK_PARAM_EXPORT) { + GValue v = { 0, }; + + /* export this parameter */ + /* get the parameter value */ + g_value_init (&v, p->value_type); + g_object_get_property (G_OBJECT (object), + p->name, + &v); + + /* only save the object "name" if it is set + (i.e. don't save the empty string) */ + if (strcmp (p->name, GDL_DOCK_NAME_PROPERTY) || + g_value_get_string (&v)) { + if (g_value_transform (&v, &attr)) + xmlSetProp (node, BAD_CAST p->name, BAD_CAST g_value_get_string (&attr)); + } + + /* free the parameter value */ + g_value_unset (&v); + } + } + g_value_unset (&attr); + g_free (props); + + info_child = *info; + info_child.where = node; + + /* save placeholders for the object */ + if (info->placeholders && !GDL_IS_DOCK_PLACEHOLDER (object)) { + GList *lph = g_hash_table_lookup (info->placeholders, object); + for (; lph; lph = lph->next) + gdl_dock_layout_foreach_object_save (GDL_DOCK_OBJECT (lph->data), + (gpointer) &info_child); + } + + /* recurse the object if appropiate */ + if (gdl_dock_object_is_compound (object)) { + gtk_container_foreach (GTK_CONTAINER (object), + (GtkCallback) gdl_dock_layout_foreach_object_save, + (gpointer) &info_child); + } +} + +static void +add_placeholder (GdlDockObject *object, + GHashTable *placeholders) +{ + if (GDL_IS_DOCK_PLACEHOLDER (object)) { + GdlDockObject *host; + GList *l; + + g_object_get (object, "host", &host, NULL); + if (host) { + l = g_hash_table_lookup (placeholders, host); + /* add the current placeholder to the list of placeholders + for that host */ + if (l) + g_hash_table_steal (placeholders, host); + + l = g_list_prepend (l, object); + g_hash_table_insert (placeholders, host, l); + g_object_unref (host); + } + } +} + +static void +gdl_dock_layout_save (GdlDockMaster *master, + xmlNodePtr where) +{ + struct { + xmlNodePtr where; + GHashTable *placeholders; + } info; + + GHashTable *placeholders; + + g_return_if_fail (master != NULL && where != NULL); + + /* build the placeholder's hash: the hash keeps lists of + * placeholders associated to each object, so that we can save the + * placeholders when we are saving the object (since placeholders + * don't show up in the normal widget hierarchy) */ + placeholders = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_list_free); + gdl_dock_master_foreach (master, (GFunc) add_placeholder, placeholders); + + /* save the layout recursively */ + info.where = where; + info.placeholders = placeholders; + + gdl_dock_master_foreach_toplevel (master, TRUE, + (GFunc) gdl_dock_layout_foreach_object_save, + (gpointer) &info); + + g_hash_table_destroy (placeholders); +} + + +/* ----- Public interface ----- */ + +GdlDockLayout * +gdl_dock_layout_new (GdlDock *dock) +{ + GdlDockMaster *master = NULL; + + /* get the master of the given dock */ + if (dock) + master = GDL_DOCK_OBJECT_GET_MASTER (dock); + + return g_object_new (GDL_TYPE_DOCK_LAYOUT, + "master", master, + NULL); +} + +static gboolean +gdl_dock_layout_idle_save (GdlDockLayout *layout) +{ + /* save default layout */ + gdl_dock_layout_save_layout (layout, NULL); + + layout->_priv->idle_save_pending = FALSE; + + return FALSE; +} + +static void +gdl_dock_layout_layout_changed_cb (GdlDockMaster *master, + GdlDockLayout *layout) +{ + /* update model */ + update_items_model (layout); + + if (!layout->_priv->idle_save_pending) { + g_idle_add ((GSourceFunc) gdl_dock_layout_idle_save, layout); + layout->_priv->idle_save_pending = TRUE; + } +} + +void +gdl_dock_layout_attach (GdlDockLayout *layout, + GdlDockMaster *master) +{ + g_return_if_fail (layout != NULL); + g_return_if_fail (master == NULL || GDL_IS_DOCK_MASTER (master)); + + if (layout->master) { + g_signal_handlers_disconnect_matched (layout->master, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, layout); + g_object_unref (layout->master); + } + + gtk_list_store_clear (layout->_priv->items_model); + + layout->master = master; + if (layout->master) { + g_object_ref (layout->master); + g_signal_connect (layout->master, "layout-changed", + (GCallback) gdl_dock_layout_layout_changed_cb, + layout); + } + + update_items_model (layout); +} + +gboolean +gdl_dock_layout_load_layout (GdlDockLayout *layout, + const gchar *name) +{ + xmlNodePtr node; + gchar *layout_name; + + g_return_val_if_fail (layout != NULL, FALSE); + + if (!layout->_priv->doc || !layout->master) + return FALSE; + + if (!name) + layout_name = DEFAULT_LAYOUT; + else + layout_name = (gchar *) name; + + node = gdl_dock_layout_find_layout (layout, layout_name); + if (!node && !name) + /* return the first layout if the default name failed to load */ + node = gdl_dock_layout_find_layout (layout, NULL); + + if (node) { + gdl_dock_layout_load (layout->master, node); + return TRUE; + } else + return FALSE; +} + +void +gdl_dock_layout_save_layout (GdlDockLayout *layout, + const gchar *name) +{ + xmlNodePtr node; + gchar *layout_name; + + g_return_if_fail (layout != NULL); + g_return_if_fail (layout->master != NULL); + + if (!layout->_priv->doc) + gdl_dock_layout_build_doc (layout); + + if (!name) + layout_name = DEFAULT_LAYOUT; + else + layout_name = (gchar *) name; + + /* delete any previously node with the same name */ + node = gdl_dock_layout_find_layout (layout, layout_name); + if (node) { + xmlUnlinkNode (node); + xmlFreeNode (node); + }; + + /* create the new node */ + node = xmlNewChild (layout->_priv->doc->children, NULL, + BAD_CAST LAYOUT_ELEMENT_NAME, NULL); + xmlSetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME, BAD_CAST layout_name); + + /* save the layout */ + gdl_dock_layout_save (layout->master, node); + layout->dirty = TRUE; + g_object_notify (G_OBJECT (layout), "dirty"); +} + +void +gdl_dock_layout_delete_layout (GdlDockLayout *layout, + const gchar *name) +{ + xmlNodePtr node; + + g_return_if_fail (layout != NULL); + + /* don't allow the deletion of the default layout */ + if (!name || !strcmp (DEFAULT_LAYOUT, name)) + return; + + node = gdl_dock_layout_find_layout (layout, name); + if (node) { + xmlUnlinkNode (node); + xmlFreeNode (node); + layout->dirty = TRUE; + g_object_notify (G_OBJECT (layout), "dirty"); + } +} + +void +gdl_dock_layout_run_manager (GdlDockLayout *layout) +{ + GtkWidget *dialog, *container; + GtkWidget *parent = NULL; + + g_return_if_fail (layout != NULL); + + if (!layout->master) + /* not attached to a dock yet */ + return; + + container = gdl_dock_layout_construct_ui (layout); + if (!container) + return; + + parent = GTK_WIDGET (gdl_dock_master_get_controller (layout->master)); + if (parent) + parent = gtk_widget_get_toplevel (parent); + + dialog = gtk_dialog_new_with_buttons (_("Layout managment"), + parent ? GTK_WINDOW (parent) : NULL, + GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + + gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 300); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), container); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); +} + +gboolean +gdl_dock_layout_load_from_file (GdlDockLayout *layout, + const gchar *filename) +{ + gboolean retval = FALSE; + + if (layout->_priv->doc) { + xmlFreeDoc (layout->_priv->doc); + layout->_priv->doc = NULL; + layout->dirty = FALSE; + g_object_notify (G_OBJECT (layout), "dirty"); + } + + /* FIXME: cannot open symlinks */ + if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { + layout->_priv->doc = xmlParseFile (filename); + if (layout->_priv->doc) { + xmlNodePtr root = layout->_priv->doc->children; + /* minimum validation: test the root element */ + if (root && !strcmp ((char*)root->name, ROOT_ELEMENT)) { + update_layouts_model (layout); + retval = TRUE; + } else { + xmlFreeDoc (layout->_priv->doc); + layout->_priv->doc = NULL; + } + } + } + + return retval; +} + +gboolean +gdl_dock_layout_save_to_file (GdlDockLayout *layout, + const gchar *filename) +{ + FILE *file_handle; + int bytes; + gboolean retval = FALSE; + + g_return_val_if_fail (layout != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + /* if there is still no xml doc, create an empty one */ + if (!layout->_priv->doc) + gdl_dock_layout_build_doc (layout); + + file_handle = fopen (filename, "w"); + if (file_handle) { + bytes = xmlDocDump (file_handle, layout->_priv->doc); + if (bytes >= 0) { + layout->dirty = FALSE; + g_object_notify (G_OBJECT (layout), "dirty"); + retval = TRUE; + }; + fclose (file_handle); + }; + + return retval; +} + +gboolean +gdl_dock_layout_is_dirty (GdlDockLayout *layout) +{ + g_return_val_if_fail (layout != NULL, FALSE); + + return layout->dirty; +}; + +GList * +gdl_dock_layout_get_layouts (GdlDockLayout *layout, + gboolean include_default) +{ + GList *retval = NULL; + xmlNodePtr node; + + g_return_val_if_fail (layout != NULL, NULL); + + if (!layout->_priv->doc) + return NULL; + + node = layout->_priv->doc->children; + for (node = node->children; node; node = node->next) { + xmlChar *name; + + if (strcmp ((char*)node->name, LAYOUT_ELEMENT_NAME)) + continue; + + name = xmlGetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME); + if (include_default || strcmp ((char*)name, DEFAULT_LAYOUT)) + retval = g_list_prepend (retval, g_strdup ((char*)name)); + xmlFree (name); + }; + retval = g_list_reverse (retval); + + return retval; +} + +GtkWidget * +gdl_dock_layout_get_ui (GdlDockLayout *layout) +{ + GtkWidget *ui; + + g_return_val_if_fail (layout != NULL, NULL); + ui = gdl_dock_layout_construct_ui (layout); + + return ui; +} + +GtkWidget * +gdl_dock_layout_get_items_ui (GdlDockLayout *layout) +{ + GtkWidget *ui; + + g_return_val_if_fail (layout != NULL, NULL); + ui = gdl_dock_layout_construct_items_ui (layout); + + return ui; +} + +GtkWidget * +gdl_dock_layout_get_layouts_ui (GdlDockLayout *layout) +{ + GtkWidget *ui; + + g_return_val_if_fail (layout != NULL, NULL); + ui = gdl_dock_layout_construct_layouts_ui (layout); + + return ui; +} diff --git a/src/libgdl/gdl-dock-layout.h b/src/libgdl/gdl-dock-layout.h new file mode 100644 index 000000000..2ce5d13b3 --- /dev/null +++ b/src/libgdl/gdl-dock-layout.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 2002 Gustavo Giráldez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef __GDL_DOCK_LAYOUT_H__ +#define __GDL_DOCK_LAYOUT_H__ + +#include +#include "libgdl/gdl-dock-master.h" +#include "libgdl/gdl-dock.h" + +G_BEGIN_DECLS + +/* standard macros */ +#define GDL_TYPE_DOCK_LAYOUT (gdl_dock_layout_get_type ()) +#define GDL_DOCK_LAYOUT(object) (GTK_CHECK_CAST ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayout)) +#define GDL_DOCK_LAYOUT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) +#define GDL_IS_DOCK_LAYOUT(object) (GTK_CHECK_TYPE ((object), GDL_TYPE_DOCK_LAYOUT)) +#define GDL_IS_DOCK_LAYOUT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_LAYOUT)) +#define GDL_DOCK_LAYOUT_GET_CLASS(object) (GTK_CHECK_GET_CLASS ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) + +/* data types & structures */ +typedef struct _GdlDockLayout GdlDockLayout; +typedef struct _GdlDockLayoutClass GdlDockLayoutClass; +typedef struct _GdlDockLayoutPrivate GdlDockLayoutPrivate; + +struct _GdlDockLayout { + GObject g_object; + + gboolean dirty; + GdlDockMaster *master; + + GdlDockLayoutPrivate *_priv; +}; + +struct _GdlDockLayoutClass { + GObjectClass g_object_class; +}; + + +/* public interface */ + +GType gdl_dock_layout_get_type (void); + +GdlDockLayout *gdl_dock_layout_new (GdlDock *dock); + +void gdl_dock_layout_attach (GdlDockLayout *layout, + GdlDockMaster *master); + +gboolean gdl_dock_layout_load_layout (GdlDockLayout *layout, + const gchar *name); + +void gdl_dock_layout_save_layout (GdlDockLayout *layout, + const gchar *name); + +void gdl_dock_layout_delete_layout (GdlDockLayout *layout, + const gchar *name); + +GList *gdl_dock_layout_get_layouts (GdlDockLayout *layout, + gboolean include_default); + +void gdl_dock_layout_run_manager (GdlDockLayout *layout); + +gboolean gdl_dock_layout_load_from_file (GdlDockLayout *layout, + const gchar *filename); + +gboolean gdl_dock_layout_save_to_file (GdlDockLayout *layout, + const gchar *filename); + +gboolean gdl_dock_layout_is_dirty (GdlDockLayout *layout); + +GtkWidget *gdl_dock_layout_get_ui (GdlDockLayout *layout); +GtkWidget *gdl_dock_layout_get_items_ui (GdlDockLayout *layout); +GtkWidget *gdl_dock_layout_get_layouts_ui (GdlDockLayout *layout); + +G_END_DECLS + +#endif + + diff --git a/src/libgdl/gdl-dock-object.c b/src/libgdl/gdl-dock-object.c index 9bdcd18ed..129cc28d9 100644 --- a/src/libgdl/gdl-dock-object.c +++ b/src/libgdl/gdl-dock-object.c @@ -396,6 +396,7 @@ gdl_dock_object_real_reduce (GdlDockObject *object) children = gtk_container_get_children (GTK_CONTAINER (object)); if (g_list_length (children) <= 1) { GList *l; + GList *dchildren = NULL; /* detach ourselves and then re-attach our children to our current parent. if we are not currently attached, the @@ -403,18 +404,41 @@ gdl_dock_object_real_reduce (GdlDockObject *object) if (parent) gdl_dock_object_freeze (parent); gdl_dock_object_freeze (object); - gdl_dock_object_detach (object, FALSE); + /* Detach the children before detaching this object, since in this + * way the children can have access to the whole object hierarchy. + * Set the InDetach flag now, so the children know that this object + * is going to be detached. */ + + + GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_DETACH); + for (l = children; l; l = l->next) { - GdlDockObject *child = GDL_DOCK_OBJECT (l->data); + GdlDockObject *child; + + if (!GDL_IS_DOCK_OBJECT (l->data)) + continue; + + child = GDL_DOCK_OBJECT (l->data); g_object_ref (child); - GDL_DOCK_OBJECT_SET_FLAGS (child, GDL_DOCK_IN_REFLOW); gdl_dock_object_detach (child, FALSE); + GDL_DOCK_OBJECT_SET_FLAGS (child, GDL_DOCK_IN_REFLOW); if (parent) - gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (child)); + dchildren = g_list_append (dchildren, child); GDL_DOCK_OBJECT_UNSET_FLAGS (child, GDL_DOCK_IN_REFLOW); - g_object_unref (child); } + /* Now it can be detached */ + gdl_dock_object_detach (object, FALSE); + + /* After detaching the reduced object, we can add the + children (the only child in fact) to the new parent */ + for (l = dchildren; l; l = l->next) { + gtk_container_add (GTK_CONTAINER (parent), l->data); + g_object_unref (l->data); + } + g_list_free (dchildren); + + /* sink the widget, so any automatic floating widget is destroyed */ g_object_ref_sink (object); /* don't reenter */ @@ -469,6 +493,9 @@ gdl_dock_object_detach (GdlDockObject *object, { g_return_if_fail (object != NULL); + if (!GDL_IS_DOCK_OBJECT (object)) + return; + if (!GDL_DOCK_OBJECT_ATTACHED (object)) return; diff --git a/src/libgdl/gdl-dock-placeholder.c b/src/libgdl/gdl-dock-placeholder.c index ca7763a55..33934e2e0 100644 --- a/src/libgdl/gdl-dock-placeholder.c +++ b/src/libgdl/gdl-dock-placeholder.c @@ -189,14 +189,14 @@ gdl_dock_placeholder_class_init (GdlDockPlaceholderClass *klass) g_object_class_install_property ( g_object_class, PROP_FLOAT_X, g_param_spec_int ("floatx", _("X-Coordinate"), - _("X coordinate for dock when floating"), + _("X-Coordinate for dock when floating"), -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | GDL_DOCK_PARAM_EXPORT)); g_object_class_install_property ( g_object_class, PROP_FLOAT_Y, g_param_spec_int ("floaty", _("Y-Coordinate"), - _("Y coordinate for dock when floating"), + _("Y-Coordinate for dock when floating"), -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | GDL_DOCK_PARAM_EXPORT)); diff --git a/src/libgdl/gdl-icons.c b/src/libgdl/gdl-icons.c new file mode 100644 index 000000000..2af2a8a9a --- /dev/null +++ b/src/libgdl/gdl-icons.c @@ -0,0 +1,267 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gdl-icons.c + * + * Copyright (C) 2000-2001 Dave Camp + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Dave Camp, Jeroen Zwartepoorte + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gdl-i18n.h" +#include "gdl-tools.h" +#include +#include +#include +#include "gdl-icons.h" + +enum { + PROP_BOGUS, + PROP_ICON_SIZE, +}; + +#define GDL_ICONS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDL_TYPE_ICONS, GdlIconsPrivate)) + +typedef struct _GdlIconsPrivate GdlIconsPrivate; + +struct _GdlIconsPrivate { + int icon_size; + + GtkIconTheme *icon_theme; + GHashTable *icons; +}; + +GDL_CLASS_BOILERPLATE (GdlIcons, gdl_icons, GObject, G_TYPE_OBJECT); + +static void +gdl_icons_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_ICON_SIZE: + g_value_set_int (value, priv->icon_size); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdl_icons_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_ICON_SIZE: + priv->icon_size = g_value_get_int (value); + g_hash_table_destroy (priv->icons); + priv->icons = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) gdk_pixbuf_unref); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +theme_changed_cb (GtkIconTheme *theme, + gpointer user_data) +{ + GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (user_data); + + g_hash_table_destroy (priv->icons); + priv->icons = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) gdk_pixbuf_unref); +} + +static void +gdl_icons_dispose (GObject *object) +{ + GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (object); + + if (priv->icon_theme) { + /* Don't do that - look a GTK+ docs */ + /* g_object_unref (priv->icon_theme); */ + priv->icon_theme = NULL; + } + + if (priv->icons) { + g_hash_table_destroy (priv->icons); + priv->icons = NULL; + } +} + +static void +gdl_icons_class_init (GdlIconsClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + object_class->dispose = gdl_icons_dispose; + object_class->get_property = gdl_icons_get_property; + object_class->set_property = gdl_icons_set_property; + + g_object_class_install_property (object_class, PROP_ICON_SIZE, + g_param_spec_int ("icon-size", + _("Icon size"), + _("Icon size"), + 12, 256, 24, + G_PARAM_READWRITE)); + + g_type_class_add_private (object_class, sizeof (GdlIconsPrivate)); +} + +static void +gdl_icons_instance_init (GdlIcons *icons) +{ + GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (icons); + + priv->icon_theme = gtk_icon_theme_get_default (); + /* gtk_icon_theme_get_default() does not ref the returned object */ + /* but API docs state the you should NOT ref it */ + /* g_object_ref (priv->icon_theme);*/ + g_signal_connect_object (G_OBJECT (priv->icon_theme), "changed", + G_CALLBACK (theme_changed_cb), icons, 0); + priv->icons = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) gdk_pixbuf_unref); +} + +GdlIcons * +gdl_icons_new (int icon_size) +{ + return GDL_ICONS (g_object_new (GDL_TYPE_ICONS, + "icon-size", icon_size, + NULL)); +} + +GdkPixbuf * +gdl_icons_get_folder_icon (GdlIcons *icons) +{ + g_return_val_if_fail (icons != NULL, NULL); + g_return_val_if_fail (GDL_IS_ICONS (icons), NULL); + + return gdl_icons_get_mime_icon (icons, "application/directory-normal"); +} + +GdkPixbuf * +gdl_icons_get_uri_icon (GdlIcons *icons, + const char *uri) +{ + GnomeVFSFileInfo *info; + GdkPixbuf *pixbuf; + + g_return_val_if_fail (icons != NULL, NULL); + g_return_val_if_fail (GDL_IS_ICONS (icons), NULL); + g_return_val_if_fail (uri != NULL, NULL); + + info = gnome_vfs_file_info_new (); + gnome_vfs_get_file_info (uri, info, + GNOME_VFS_FILE_INFO_FOLLOW_LINKS | + GNOME_VFS_FILE_INFO_GET_MIME_TYPE | + GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE); + if (info->mime_type) + pixbuf = gdl_icons_get_mime_icon (icons, info->mime_type); + else + pixbuf = gdl_icons_get_mime_icon (icons, "gnome-fs-regular"); + gnome_vfs_file_info_unref (info); + + return pixbuf; +} + +GdkPixbuf * +gdl_icons_get_mime_icon (GdlIcons *icons, + const char *mime_type) +{ + GdkPixbuf *pixbuf; + char *icon_name; + + g_return_val_if_fail (icons != NULL, NULL); + g_return_val_if_fail (GDL_IS_ICONS (icons), NULL); + g_return_val_if_fail (mime_type != NULL, NULL); + + GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (icons); + + pixbuf = g_hash_table_lookup (priv->icons, mime_type); + if (pixbuf != NULL) { + g_object_ref (G_OBJECT (pixbuf)); + return pixbuf; + } + + if (!strcmp (mime_type, "application/directory-normal")) { + icon_name = g_strdup ("gnome-fs-directory"); + } else { + icon_name = gnome_icon_lookup (priv->icon_theme, + NULL, + NULL, + NULL, + NULL, + mime_type, + GNOME_ICON_LOOKUP_FLAGS_NONE, + NULL); + } + + if (!icon_name) { + /* Return regular icon if one doesn't exist for mime type. */ + if (!strcmp (mime_type, "gnome-fs-regular")) + return NULL; + else + return gdl_icons_get_mime_icon (icons, "gnome-fs-regular"); + } else { + if (!gtk_icon_theme_has_icon (priv->icon_theme, icon_name)) { + g_free (icon_name); + if (!strcmp (mime_type, "gnome-fs-regular")) + return NULL; + else + return gdl_icons_get_mime_icon (icons, "gnome-fs-regular"); + } else { + pixbuf = gtk_icon_theme_load_icon (priv->icon_theme, + icon_name, + priv->icon_size, + 0, /* lookup flags */ + NULL); + g_free (icon_name); + + if (pixbuf == NULL) { + if (!strcmp (mime_type, "gnome-fs-regular")) + return NULL; + else + return gdl_icons_get_mime_icon (icons, + "gnome-fs-regular"); + } + } + } + + g_hash_table_insert (priv->icons, g_strdup (mime_type), pixbuf); + g_object_ref (pixbuf); + + return pixbuf; +} diff --git a/src/libgdl/gdl-icons.h b/src/libgdl/gdl-icons.h new file mode 100644 index 000000000..79f3bba85 --- /dev/null +++ b/src/libgdl/gdl-icons.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gdl-icons.h + * + * Copyright (C) 2000-2001 JP Rosevear + * 2000 Dave Camp + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: JP Rosevear, Dave Camp, Jeroen Zwartepoorte + */ + +#ifndef _GDL_ICONS_H_ +#define _GDL_ICONS_H_ + +#include +#include + +G_BEGIN_DECLS + +#define GDL_TYPE_ICONS (gdl_icons_get_type ()) +#define GDL_ICONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_ICONS, GdlIcons)) +#define GDL_ICONS_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_ICONS, GdlIconsClass)) +#define GDL_IS_ICONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_ICONS)) +#define GDL_IS_ICONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GDL_TYPE_ICONS)) + +typedef struct _GdlIcons GdlIcons; +typedef struct _GdlIconsClass GdlIconsClass; + +struct _GdlIcons { + GObject parent; +}; + +struct _GdlIconsClass { + GObjectClass parent_class; +}; + +GType gdl_icons_get_type (void); +GdlIcons *gdl_icons_new (int icon_size); + +GdkPixbuf *gdl_icons_get_folder_icon (GdlIcons *icons); +GdkPixbuf *gdl_icons_get_uri_icon (GdlIcons *icons, + const char *uri); +GdkPixbuf *gdl_icons_get_mime_icon (GdlIcons *icons, + const char *mime_type); + +G_END_DECLS + +#endif /* _GDL_ICONS_H_ */ diff --git a/src/libgdl/gdl-switcher.c b/src/libgdl/gdl-switcher.c index eccd66ce2..24ec72126 100644 --- a/src/libgdl/gdl-switcher.c +++ b/src/libgdl/gdl-switcher.c @@ -55,7 +55,7 @@ static void gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *stock_id, const GdkPixbuf *pixbuf_icon, gint switcher_id); -static void gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id); +/* static void gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id); */ static void gdl_switcher_select_page (GdlSwitcher *switcher, gint switcher_id); static void gdl_switcher_select_button (GdlSwitcher *switcher, gint switcher_id); static void gdl_switcher_set_show_buttons (GdlSwitcher *switcher, gboolean show); @@ -514,7 +514,7 @@ gdl_switcher_expose (GtkWidget *widget, GdkEventExpose *event) } } return GDL_CALL_PARENT_WITH_DEFAULT (GTK_WIDGET_CLASS, expose_event, - (widget, event), FALSE); + (widget, event), FALSE); } static void @@ -678,11 +678,9 @@ gdl_switcher_select_page (GdlSwitcher *switcher, gint id) static void gdl_switcher_class_init (GdlSwitcherClass *klass) { - GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass); GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); - (void)notebook_class; container_class->forall = gdl_switcher_forall; container_class->remove = gdl_switcher_remove; @@ -763,11 +761,11 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, gtk_widget_show (hbox); if (stock_id) { - icon_widget = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON); + icon_widget = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU); } else if (pixbuf_icon) { icon_widget = gtk_image_new_from_pixbuf (pixbuf_icon); } else { - icon_widget = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON); + icon_widget = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU); } gtk_widget_show (icon_widget); @@ -810,6 +808,7 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, gtk_widget_queue_resize (GTK_WIDGET (switcher)); } +#if 0 static void gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id) { @@ -827,6 +826,7 @@ gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id) } gtk_widget_queue_resize (GTK_WIDGET (switcher)); } +#endif static void gdl_switcher_select_button (GdlSwitcher *switcher, gint switcher_id) diff --git a/src/libgdl/gdl.h b/src/libgdl/gdl.h new file mode 100644 index 000000000..e47dc310d --- /dev/null +++ b/src/libgdl/gdl.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 1999-2000 Dave Camp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GDL_H__ +#define __GDL_H__ + +#include "libgdl/gdl-tools.h" +#include "libgdl/gdl-dock-object.h" +#include "libgdl/gdl-dock-master.h" +#include "libgdl/gdl-dock.h" +#include "libgdl/gdl-dock-item.h" +#include "libgdl/gdl-dock-layout.h" +#include "libgdl/gdl-dock-paned.h" +#include "libgdl/gdl-dock-notebook.h" +#include "libgdl/gdl-dock-tablabel.h" +#include "libgdl/gdl-dock-bar.h" +#include "libgdl/gdl-combo-button.h" +#include "libgdl/gdl-switcher.h" + +#endif diff --git a/src/libgdl/libgdl.h b/src/libgdl/libgdl.h deleted file mode 100644 index 5ee84e1ae..000000000 --- a/src/libgdl/libgdl.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 1999-2000 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GDL_H__ -#define __GDL_H__ - -#include "libgdl/gdl-tools.h" -#include "libgdl/gdl-dock-object.h" -#include "libgdl/gdl-dock-master.h" -#include "libgdl/gdl-dock.h" -#include "libgdl/gdl-dock-item.h" -#include "libgdl/gdl-dock-paned.h" -#include "libgdl/gdl-dock-notebook.h" -#include "libgdl/gdl-dock-tablabel.h" -#include "libgdl/gdl-dock-bar.h" -#include "libgdl/gdl-switcher.h" - -#endif diff --git a/src/libgdl/libgdltypebuiltins.h b/src/libgdl/libgdltypebuiltins.h index 8be5decb1..f5e6ea17b 100644 --- a/src/libgdl/libgdltypebuiltins.h +++ b/src/libgdl/libgdltypebuiltins.h @@ -4,7 +4,7 @@ #ifndef __LIBGDLTYPEBUILTINS_H__ #define __LIBGDLTYPEBUILTINS_H__ 1 -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" G_BEGIN_DECLS diff --git a/src/libgdl/test-combo-button.c b/src/libgdl/test-combo-button.c new file mode 100644 index 000000000..35ce3fff3 --- /dev/null +++ b/src/libgdl/test-combo-button.c @@ -0,0 +1,111 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-combo-button.c + * + * Copyright (C) 2003 Jeroen Zwartepoorte + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "gdl-combo-button.h" + +static void +combo_button_activate_default_cb (GdlComboButton *combo, + gpointer data) +{ + g_message ("combo_button_activate_default_cb"); +} + +int +main (int argc, char **argv) +{ + GtkWidget *window, *hbox, *combo, *menu, *menuitem; + GdkPixbuf *icon; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + g_signal_connect (G_OBJECT (window), "delete_event", + G_CALLBACK (gtk_main_quit), NULL); + gtk_window_set_title (GTK_WINDOW (window), "Combo button test"); + gtk_window_set_resizable (GTK_WINDOW (window), FALSE); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (window), hbox); + + combo = gtk_button_new_from_stock (GTK_STOCK_OPEN); + gtk_button_set_relief (GTK_BUTTON (combo), GTK_RELIEF_NONE); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + + menu = gtk_menu_new (); + menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + gtk_widget_show_all (menu); + + combo = gdl_combo_button_new (); + gdl_combo_button_set_label (GDL_COMBO_BUTTON (combo), "Run"); + gdl_combo_button_set_menu (GDL_COMBO_BUTTON (combo), GTK_MENU (menu)); + icon = gtk_widget_render_icon (combo, GTK_STOCK_EXECUTE, + GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); + gdl_combo_button_set_icon (GDL_COMBO_BUTTON (combo), icon); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + + g_signal_connect (combo, "activate_default", + G_CALLBACK (combo_button_activate_default_cb), NULL); + + combo = gtk_button_new_from_stock (GTK_STOCK_SAVE); + gtk_button_set_relief (GTK_BUTTON (combo), GTK_RELIEF_NONE); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + + menu = gtk_menu_new (); + menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + gtk_widget_show_all (menu); + + combo = gdl_combo_button_new (); + gdl_combo_button_set_label (GDL_COMBO_BUTTON (combo), "Open"); + gdl_combo_button_set_menu (GDL_COMBO_BUTTON (combo), GTK_MENU (menu)); + icon = gtk_widget_render_icon (combo, GTK_STOCK_OPEN, + GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); + gdl_combo_button_set_icon (GDL_COMBO_BUTTON (combo), icon); + gtk_widget_set_sensitive (combo, FALSE); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + + g_signal_connect (combo, "activate_default", + G_CALLBACK (combo_button_activate_default_cb), NULL); + + menu = gtk_menu_new (); + combo = gdl_combo_button_new (); + gdl_combo_button_set_label (GDL_COMBO_BUTTON (combo), "Open"); + gdl_combo_button_set_menu (GDL_COMBO_BUTTON (combo), GTK_MENU (menu)); + icon = gtk_widget_render_icon (combo, GTK_STOCK_OPEN, + GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); + gdl_combo_button_set_icon (GDL_COMBO_BUTTON (combo), icon); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + + gtk_widget_show_all (window); + + gtk_main (); + + return 0; +} diff --git a/src/libgdl/test-dataview.c b/src/libgdl/test-dataview.c new file mode 100644 index 000000000..bc89cbd4f --- /dev/null +++ b/src/libgdl/test-dataview.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "gdl-data-view.h" +#include "gdl-data-model-test.h" + +int +main (int argc, char *argv[]) +{ + GtkWidget *win; + GtkWidget *view; + GdlDataModel *model; + GtkWidget *vbox; + + gtk_init (&argc, &argv); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size (GTK_WINDOW (win), 500, 200); + + vbox = gtk_vbox_new (FALSE, 5); + + view = gdl_data_view_new (); + + gtk_layout_set_hadjustment (GTK_LAYOUT (view), NULL); + gtk_layout_set_vadjustment (GTK_LAYOUT (view), NULL); + + + model = GDL_DATA_MODEL (gdl_data_model_test_new ()); + gdl_data_view_set_model (GDL_DATA_VIEW (view), + model); + + gtk_box_pack_start (GTK_BOX (vbox), view, TRUE, TRUE, 0); + + gtk_container_add (GTK_CONTAINER (win), vbox); + + gtk_widget_show_all (win); + gtk_widget_grab_focus (GTK_WIDGET (view)); + + gtk_main (); + + return 0; +} diff --git a/src/libgdl/test-dock.c b/src/libgdl/test-dock.c new file mode 100644 index 000000000..1e9c80111 --- /dev/null +++ b/src/libgdl/test-dock.c @@ -0,0 +1,311 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "gdl-tools.h" + +#include "gdl-dock.h" +#include "gdl-dock-item.h" +#include "gdl-dock-notebook.h" +#include "gdl-dock-layout.h" +#include "gdl-dock-placeholder.h" +#include "gdl-dock-bar.h" +#include "gdl-switcher.h" + +#include + +/* ---- end of debugging code */ + +static void +on_style_button_toggled (GtkRadioButton *button, GdlDock *dock) +{ + gboolean active; + GdlDockMaster *master = GDL_DOCK_OBJECT_GET_MASTER (dock); + GdlSwitcherStyle style = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), + "__style_id")); + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + if (active) { + g_object_set (master, "switcher-style", style, NULL); + } +} + +static GtkWidget * +create_style_button (GtkWidget *dock, GtkWidget *box, GtkWidget *group, + GdlSwitcherStyle style, const gchar *style_text) +{ + GdlSwitcherStyle current_style; + GtkWidget *button1; + GdlDockMaster *master = GDL_DOCK_OBJECT_GET_MASTER (dock); + + g_object_get (master, "switcher-style", ¤t_style, NULL); + button1 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (group), + style_text); + gtk_widget_show (button1); + g_object_set_data (G_OBJECT (button1), "__style_id", + GINT_TO_POINTER (style)); + if (current_style == style) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button1), TRUE); + } + g_signal_connect (button1, "toggled", + G_CALLBACK (on_style_button_toggled), + dock); + gtk_box_pack_start (GTK_BOX (box), button1, FALSE, FALSE, 0); + return button1; +} + +static GtkWidget * +create_styles_item (GtkWidget *dock) +{ + GtkWidget *vbox1; + GtkWidget *group; + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + + group = create_style_button (dock, vbox1, NULL, + GDL_SWITCHER_STYLE_ICON, "Only icon"); + group = create_style_button (dock, vbox1, group, + GDL_SWITCHER_STYLE_TEXT, "Only text"); + group = create_style_button (dock, vbox1, group, + GDL_SWITCHER_STYLE_BOTH, + "Both icons and texts"); + group = create_style_button (dock, vbox1, group, + GDL_SWITCHER_STYLE_TOOLBAR, + "Desktop toolbar style"); + group = create_style_button (dock, vbox1, group, + GDL_SWITCHER_STYLE_TABS, + "Notebook tabs"); + return vbox1; +} + +static GtkWidget * +create_item (const gchar *button_title) +{ + GtkWidget *vbox1; + GtkWidget *button1; + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + + button1 = gtk_button_new_with_label (button_title); + gtk_widget_show (button1); + gtk_box_pack_start (GTK_BOX (vbox1), button1, TRUE, TRUE, 0); + + return vbox1; +} + +/* creates a simple widget with a textbox inside */ +static GtkWidget * +create_text_item () +{ + GtkWidget *vbox1; + GtkWidget *scrolledwindow1; + GtkWidget *text; + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), + GTK_SHADOW_ETCHED_IN); + text = gtk_text_view_new (); + g_object_set (text, "wrap-mode", GTK_WRAP_WORD, NULL); + gtk_widget_show (text); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), text); + + return vbox1; +} + +static void +button_dump_cb (GtkWidget *button, gpointer data) +{ + /* Dump XML tree. */ + gdl_dock_layout_save_to_file (GDL_DOCK_LAYOUT (data), "layout.xml"); + g_spawn_command_line_async ("cat layout.xml", NULL); +} + +static void +run_layout_manager_cb (GtkWidget *w, gpointer data) +{ + GdlDockLayout *layout = GDL_DOCK_LAYOUT (data); + gdl_dock_layout_run_manager (layout); +} + +static void +save_layout_cb (GtkWidget *w, gpointer data) +{ + GdlDockLayout *layout = GDL_DOCK_LAYOUT (data); + GtkWidget *dialog, *hbox, *label, *entry; + gint response; + + dialog = gtk_dialog_new_with_buttons ("New Layout", + NULL, + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + NULL); + + hbox = gtk_hbox_new (FALSE, 8); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 8); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); + + label = gtk_label_new ("Name:"); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + entry = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); + + gtk_widget_show_all (hbox); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + if (response == GTK_RESPONSE_OK) { + const gchar *name = gtk_entry_get_text (GTK_ENTRY (entry)); + gdl_dock_layout_save_layout (layout, name); + } + + gtk_widget_destroy (dialog); +} + +int +main (int argc, char **argv) +{ + GtkWidget *item1, *item2, *item3; + GtkWidget *items [4]; + GtkWidget *win, *table, *button, *box; + int i; + GdlDockLayout *layout; + GtkWidget *dock, *dockbar; + + gtk_init (&argc, &argv); + + /*gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);*/ + + /* window creation */ + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + g_signal_connect (win, "delete_event", + G_CALLBACK (gtk_main_quit), NULL); + gtk_window_set_title (GTK_WINDOW (win), "Docking widget test"); + gtk_window_set_default_size (GTK_WINDOW (win), 400, 400); + + /* table */ + table = gtk_vbox_new (FALSE, 5); + gtk_container_add (GTK_CONTAINER (win), table); + gtk_container_set_border_width (GTK_CONTAINER (table), 10); + + /* create the dock */ + dock = gdl_dock_new (); + + /* ... and the layout manager */ + layout = gdl_dock_layout_new (GDL_DOCK (dock)); + + /* create the dockbar */ + dockbar = gdl_dock_bar_new (GDL_DOCK (dock)); + gdl_dock_bar_set_style(GDL_DOCK_BAR(dockbar), GDL_DOCK_BAR_TEXT); + + box = gtk_hbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (table), box, TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (box), dockbar, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (box), dock, TRUE, TRUE, 0); + + /* create the dock items */ + item1 = gdl_dock_item_new ("item1", "Item #1", GDL_DOCK_ITEM_BEH_LOCKED); + gtk_container_add (GTK_CONTAINER (item1), create_text_item ()); + gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (item1), + GDL_DOCK_TOP); + gtk_widget_show (item1); + + item2 = gdl_dock_item_new_with_stock ("item2", "Item #2: Select the switcher style for notebooks", + GTK_STOCK_EXECUTE, + GDL_DOCK_ITEM_BEH_NORMAL); + g_object_set (item2, "resize", FALSE, NULL); + gtk_container_add (GTK_CONTAINER (item2), create_styles_item (dock)); + gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (item2), + GDL_DOCK_RIGHT); + gtk_widget_show (item2); + + item3 = gdl_dock_item_new_with_stock ("item3", "Item #3 has accented characters (áéíóúñ)", + GTK_STOCK_CONVERT, + GDL_DOCK_ITEM_BEH_NORMAL | + GDL_DOCK_ITEM_BEH_CANT_CLOSE); + gtk_container_add (GTK_CONTAINER (item3), create_item ("Button 3")); + gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (item3), + GDL_DOCK_BOTTOM); + gtk_widget_show (item3); + + items [0] = gdl_dock_item_new_with_stock ("Item #4", "Item #4", + GTK_STOCK_JUSTIFY_FILL, + GDL_DOCK_ITEM_BEH_NORMAL | + GDL_DOCK_ITEM_BEH_CANT_ICONIFY); + gtk_container_add (GTK_CONTAINER (items [0]), create_text_item ()); + gtk_widget_show (items [0]); + gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (items [0]), GDL_DOCK_BOTTOM); + for (i = 1; i < 3; i++) { + gchar name[10]; + + snprintf (name, sizeof (name), "Item #%d", i + 4); + items [i] = gdl_dock_item_new_with_stock (name, name, GTK_STOCK_NEW, + GDL_DOCK_ITEM_BEH_NORMAL); + gtk_container_add (GTK_CONTAINER (items [i]), create_text_item ()); + gtk_widget_show (items [i]); + + gdl_dock_object_dock (GDL_DOCK_OBJECT (items [0]), + GDL_DOCK_OBJECT (items [i]), + GDL_DOCK_CENTER, NULL); + }; + + /* tests: manually dock and move around some of the items */ + gdl_dock_item_dock_to (GDL_DOCK_ITEM (item3), GDL_DOCK_ITEM (item1), + GDL_DOCK_TOP, -1); + + gdl_dock_item_dock_to (GDL_DOCK_ITEM (item2), GDL_DOCK_ITEM (item3), + GDL_DOCK_RIGHT, -1); + + gdl_dock_item_dock_to (GDL_DOCK_ITEM (item2), GDL_DOCK_ITEM (item3), + GDL_DOCK_LEFT, -1); + + gdl_dock_item_dock_to (GDL_DOCK_ITEM (item2), NULL, + GDL_DOCK_FLOATING, -1); + + box = gtk_hbox_new (TRUE, 5); + gtk_box_pack_end (GTK_BOX (table), box, FALSE, FALSE, 0); + + button = gtk_button_new_from_stock (GTK_STOCK_SAVE); + g_signal_connect (button, "clicked", + G_CALLBACK (save_layout_cb), layout); + gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0); + + button = gtk_button_new_with_label ("Layout Manager"); + g_signal_connect (button, "clicked", + G_CALLBACK (run_layout_manager_cb), layout); + gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0); + + button = gtk_button_new_with_label ("Dump XML"); + g_signal_connect (button, "clicked", + G_CALLBACK (button_dump_cb), layout); + gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0); + + gtk_widget_show_all (win); + + gdl_dock_placeholder_new ("ph1", GDL_DOCK_OBJECT (dock), GDL_DOCK_TOP, FALSE); + gdl_dock_placeholder_new ("ph2", GDL_DOCK_OBJECT (dock), GDL_DOCK_BOTTOM, FALSE); + gdl_dock_placeholder_new ("ph3", GDL_DOCK_OBJECT (dock), GDL_DOCK_LEFT, FALSE); + gdl_dock_placeholder_new ("ph4", GDL_DOCK_OBJECT (dock), GDL_DOCK_RIGHT, FALSE); + + gtk_main (); + + g_object_unref (layout); + + return 0; +} diff --git a/src/ui/dialog/dock-behavior.h b/src/ui/dialog/dock-behavior.h index b865af545..98c111719 100644 --- a/src/ui/dialog/dock-behavior.h +++ b/src/ui/dialog/dock-behavior.h @@ -21,7 +21,7 @@ #include "ui/widget/dock-item.h" -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" #include "behavior.h" diff --git a/src/ui/widget/dock-item.h b/src/ui/widget/dock-item.h index 79d69d862..1780b7525 100644 --- a/src/ui/widget/dock-item.h +++ b/src/ui/widget/dock-item.h @@ -19,7 +19,7 @@ #include #include -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" namespace Inkscape { namespace UI { diff --git a/src/ui/widget/dock.h b/src/ui/widget/dock.h index 5836cf83f..bd5685348 100644 --- a/src/ui/widget/dock.h +++ b/src/ui/widget/dock.h @@ -20,7 +20,7 @@ #include "ui/widget/dock-item.h" -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" namespace Inkscape { namespace UI { -- cgit v1.2.3 From 076ea1e5cfd8f4c78638e71405a7dda8de7aa17f Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 9 Jul 2011 15:48:49 +0100 Subject: Merge upstream GDL 0.7.9 changes (bzr r10431) --- src/libgdl/gdl-dock-item.c | 2 +- src/libgdl/gdl-tools.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index db31ade30..c8151fe95 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -301,7 +301,7 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) g_object_class, PROP_RESIZE, g_param_spec_boolean ("resize", _("Resizable"), _("If set, the dock item can be resized when " - "docked in a panel"), + "docked in a GtkPanel widget"), TRUE, G_PARAM_READWRITE)); diff --git a/src/libgdl/gdl-tools.h b/src/libgdl/gdl-tools.h index 2cc68c035..4e515b23b 100644 --- a/src/libgdl/gdl-tools.h +++ b/src/libgdl/gdl-tools.h @@ -79,9 +79,10 @@ G_BEGIN_DECLS #endif /* DO_GDL_TRACE */ -/** +/* * Class boilerplate and base class call macros copied from * bonobo/bonobo-macros.h. Original copyright follows. + * * * Author: * Darin Adler -- cgit v1.2.3 From f733c171b830be2914f2473dcac2ed5787ad8317 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 9 Jul 2011 15:58:25 +0100 Subject: Merge upstream GDL 0.7.10 changes (bzr r10432) --- src/libgdl/gdl-dock-item-grip.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 2101d9621..0c202812c 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -214,9 +214,11 @@ gdl_dock_item_grip_item_notify (GObject *master, ensure_title_and_icon_pixbuf (grip); } else if (strcmp (pspec->name, "long-name") == 0) { + if (grip->_priv->title_layout) { + g_object_unref (grip->_priv->title_layout); + grip->_priv->title_layout = NULL; + } g_free (grip->_priv->title); - g_object_unref (grip->_priv->title_layout); - grip->_priv->title_layout = NULL; grip->_priv->title = NULL; ensure_title_and_icon_pixbuf (grip); gtk_widget_queue_draw (GTK_WIDGET (grip)); -- cgit v1.2.3 From ec4f9f3344866d4a36d11cec8250289be6999f61 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 9 Jul 2011 16:19:38 +0100 Subject: Merge upstream GDL 2.23.90 changes (bzr r10433) --- src/libgdl/gdl-data-frame.h | 10 +++++----- src/libgdl/gdl-data-view.h | 12 ++++++------ src/libgdl/gdl-dock-item-grip.c | 4 ++-- src/libgdl/gdl-dock-item.c | 2 +- src/libgdl/gdl-dock-layout.c | 4 ++-- src/libgdl/gdl-dock-layout.h | 10 +++++----- src/libgdl/gdl-switcher.c | 23 +++++++++++++++++++---- 7 files changed, 40 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/libgdl/gdl-data-frame.h b/src/libgdl/gdl-data-frame.h index 740c38293..7daeb5b12 100644 --- a/src/libgdl/gdl-data-frame.h +++ b/src/libgdl/gdl-data-frame.h @@ -29,11 +29,11 @@ G_BEGIN_DECLS #define GDL_TYPE_DATA_FRAME (gdl_data_frame_get_type ()) -#define GDL_DATA_FRAME(obj) (GTK_CHECK_CAST ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrame)) -#define GDL_DATA_FRAME_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GDL_DATA_VIEW_FRAM, GdlDataFrame)) -#define GDL_IS_DATA_FRAME(obj) (GTK_CHECK_TYPE ((obj), GDL_TYPE_DATA_FRAME)) -#define GDL_IS_DATA_FRAME_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_FRAME)) -#define GDL_DATA_FRAME_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrameClass)) +#define GDL_DATA_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrame)) +#define GDL_DATA_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_DATA_VIEW_FRAM, GdlDataFrame)) +#define GDL_IS_DATA_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_FRAME)) +#define GDL_IS_DATA_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_FRAME)) +#define GDL_DATA_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrameClass)) typedef struct _GdlDataFrame GdlDataFrame; typedef struct _GdlDataFramePrivate GdlDataFramePrivate; diff --git a/src/libgdl/gdl-data-view.h b/src/libgdl/gdl-data-view.h index a29132074..3a5db02f4 100644 --- a/src/libgdl/gdl-data-view.h +++ b/src/libgdl/gdl-data-view.h @@ -29,11 +29,11 @@ G_BEGIN_DECLS #define GDL_TYPE_DATA_VIEW (gdl_data_view_get_type ()) -#define GDL_DATA_VIEW(obj) (GTK_CHECK_CAST ((obj), GDL_TYPE_DATA_VIEW, GdlDataView)) -#define GDL_DATA_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) -#define GDL_IS_DATA_VIEW(obj) (GTK_CHECK_TYPE ((obj), GDL_TYPE_DATA_VIEW)) -#define GDL_IS_DATA_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_VIEW)) -#define GDL_DATA_VIEW_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) +#define GDL_DATA_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_VIEW, GdlDataView)) +#define GDL_DATA_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) +#define GDL_IS_DATA_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_VIEW)) +#define GDL_IS_DATA_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_VIEW)) +#define GDL_DATA_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) typedef struct _GdlDataView GdlDataView; typedef struct _GdlDataViewClass GdlDataViewClass; @@ -53,7 +53,7 @@ struct _GdlDataViewClass { GtkLayoutClass parent_class; }; -GtkType gdl_data_view_get_type (void); +GType gdl_data_view_get_type (void); GtkWidget *gdl_data_view_new (void); void gdl_data_view_set_model (GdlDataView *view, GdlDataModel *model); diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 0c202812c..91b88e782 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -386,9 +386,9 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) G_CALLBACK (gdl_dock_item_grip_iconify_clicked), grip); gtk_widget_set_tooltip_text (grip->_priv->iconify_button, - _("Iconify")); + _("Iconify this dock")); gtk_widget_set_tooltip_text (grip->_priv->close_button, - _("Close")); + _("Close this dock")); } static void diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index c8151fe95..d2c36b18a 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -1460,7 +1460,7 @@ gdl_dock_item_dock (GdlDockObject *object, { /* Activate the page we just added */ GdlDockItem* notebook = GDL_DOCK_ITEM (gdl_dock_object_get_parent_object (requestor)); - gtk_notebook_set_page (GTK_NOTEBOOK (notebook->child), + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook->child), gtk_notebook_page_num (GTK_NOTEBOOK (notebook->child), GTK_WIDGET (requestor))); } diff --git a/src/libgdl/gdl-dock-layout.c b/src/libgdl/gdl-dock-layout.c index c3b0a4dac..a0f0a3e3a 100644 --- a/src/libgdl/gdl-dock-layout.c +++ b/src/libgdl/gdl-dock-layout.c @@ -715,9 +715,9 @@ gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) /* connect signals */ glade_xml_signal_connect_data (gui, "on_load_button_clicked", - GTK_SIGNAL_FUNC (load_layout_cb), ui_data); + G_CALLBACK (load_layout_cb), ui_data); glade_xml_signal_connect_data (gui, "on_delete_button_clicked", - GTK_SIGNAL_FUNC (delete_layout_cb), ui_data); + G_CALLBACK (delete_layout_cb), ui_data); g_signal_connect (container, "destroy", (GCallback) layout_ui_destroyed, NULL); diff --git a/src/libgdl/gdl-dock-layout.h b/src/libgdl/gdl-dock-layout.h index 2ce5d13b3..82dce5de8 100644 --- a/src/libgdl/gdl-dock-layout.h +++ b/src/libgdl/gdl-dock-layout.h @@ -31,11 +31,11 @@ G_BEGIN_DECLS /* standard macros */ #define GDL_TYPE_DOCK_LAYOUT (gdl_dock_layout_get_type ()) -#define GDL_DOCK_LAYOUT(object) (GTK_CHECK_CAST ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayout)) -#define GDL_DOCK_LAYOUT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) -#define GDL_IS_DOCK_LAYOUT(object) (GTK_CHECK_TYPE ((object), GDL_TYPE_DOCK_LAYOUT)) -#define GDL_IS_DOCK_LAYOUT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_LAYOUT)) -#define GDL_DOCK_LAYOUT_GET_CLASS(object) (GTK_CHECK_GET_CLASS ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) +#define GDL_DOCK_LAYOUT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayout)) +#define GDL_DOCK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) +#define GDL_IS_DOCK_LAYOUT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDL_TYPE_DOCK_LAYOUT)) +#define GDL_IS_DOCK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_LAYOUT)) +#define GDL_DOCK_LAYOUT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) /* data types & structures */ typedef struct _GdlDockLayout GdlDockLayout; diff --git a/src/libgdl/gdl-switcher.c b/src/libgdl/gdl-switcher.c index 24ec72126..c67b4464b 100644 --- a/src/libgdl/gdl-switcher.c +++ b/src/libgdl/gdl-switcher.c @@ -702,6 +702,15 @@ gdl_switcher_class_init (GdlSwitcherClass *klass) GDL_TYPE_SWITCHER_STYLE, GDL_SWITCHER_STYLE_BOTH, G_PARAM_READWRITE)); + + gtk_rc_parse_string ("style \"gdl-button-style\"\n" + "{\n" + "GtkWidget::focus-padding = 1\n" + "GtkWidget::focus-line-width = 1\n" + "xthickness = 0\n" + "ythickness = 0\n" + "}\n" + "widget \"*.gdl-button\" style \"gdl-button-style\""); } static void @@ -743,6 +752,7 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, const gchar *tooltips, const gchar *stock_id, const GdkPixbuf *pixbuf_icon, gint switcher_id) { + GtkWidget *event_box; GtkWidget *button_widget; GtkWidget *hbox; GtkWidget *icon_widget; @@ -750,6 +760,8 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, GtkWidget *arrow; button_widget = gtk_toggle_button_new (); + gtk_widget_set_name (button_widget, "gdl-button"); + gtk_button_set_relief (GTK_BUTTON(button_widget), GTK_RELIEF_HALF); if (switcher->priv->show) gtk_widget_show (button_widget); g_signal_connect (button_widget, "toggled", @@ -779,8 +791,11 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, } gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); gtk_widget_show (label_widget); - gtk_widget_set_tooltip_text (button_widget, tooltips); - + + + gtk_widget_set_tooltip_text (button_widget, + tooltips); + switch (INTERNAL_MODE (switcher)) { case GDL_SWITCHER_STYLE_TEXT: gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0); @@ -801,10 +816,10 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, switcher->priv->buttons = g_slist_append (switcher->priv->buttons, button_new (button_widget, label_widget, - icon_widget, + icon_widget, arrow, hbox, switcher_id)); + gtk_widget_set_parent (button_widget, GTK_WIDGET (switcher)); - gtk_widget_queue_resize (GTK_WIDGET (switcher)); } -- cgit v1.2.3 From e7672f3910efca2b9be29d8f6362578cb16cf59e Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 9 Jul 2011 19:44:28 +0100 Subject: Merge upstream GDL 2.24.0 changes (bzr r10434) --- src/libgdl/gdl-data-frame.c | 297 ------------------- src/libgdl/gdl-data-frame.h | 72 ----- src/libgdl/gdl-data-model-test.c | 240 ---------------- src/libgdl/gdl-data-model-test.h | 32 --- src/libgdl/gdl-data-model.c | 160 ----------- src/libgdl/gdl-data-model.h | 105 ------- src/libgdl/gdl-data-row.c | 604 --------------------------------------- src/libgdl/gdl-data-row.h | 90 ------ src/libgdl/gdl-data-view.c | 526 ---------------------------------- src/libgdl/gdl-data-view.h | 71 ----- src/libgdl/gdl-icons.c | 267 ----------------- src/libgdl/gdl-icons.h | 61 ---- src/libgdl/test-dataview.c | 43 --- 13 files changed, 2568 deletions(-) delete mode 100644 src/libgdl/gdl-data-frame.c delete mode 100644 src/libgdl/gdl-data-frame.h delete mode 100644 src/libgdl/gdl-data-model-test.c delete mode 100644 src/libgdl/gdl-data-model-test.h delete mode 100644 src/libgdl/gdl-data-model.c delete mode 100644 src/libgdl/gdl-data-model.h delete mode 100644 src/libgdl/gdl-data-row.c delete mode 100644 src/libgdl/gdl-data-row.h delete mode 100644 src/libgdl/gdl-data-view.c delete mode 100644 src/libgdl/gdl-data-view.h delete mode 100644 src/libgdl/gdl-icons.c delete mode 100644 src/libgdl/gdl-icons.h delete mode 100644 src/libgdl/test-dataview.c (limited to 'src') diff --git a/src/libgdl/gdl-data-frame.c b/src/libgdl/gdl-data-frame.c deleted file mode 100644 index d6fb19533..000000000 --- a/src/libgdl/gdl-data-frame.c +++ /dev/null @@ -1,297 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-i18n.h" -#include "gdl-tools.h" -#include - -#include "gdl-data-view.h" -#include "gdl-data-frame.h" -#include "gdl-data-model.h" -#include "gdl-data-row.h" - -struct _GdlDataFramePrivate { - GdkRectangle shadow_r; - GdkRectangle frame_r; - GdkRectangle titlebar_r; - GdkRectangle title_r; - GdkRectangle close_r; - GdkRectangle row_r; - - int shadow_offset; - int titlebar_height; - char *title; - - GdlDataRow *row; - - PangoLayout *layout; - - gboolean selected; -}; - -static void gdl_data_frame_class_init (GdlDataFrameClass *klass); -static void gdl_data_frame_instance_init (GdlDataFrame *obj); -static void gdl_data_frame_finalize (GObject *object); - -GDL_CLASS_BOILERPLATE (GdlDataFrame, gdl_data_frame, GObject, G_TYPE_OBJECT); - -#define PAD 2 -#define BORDER 1 - -#define CENTERY(r1, r2) { r1.y = ((r2.y + (r2.height / 2)) - (r1.height / 2)); } - -void -gdl_data_frame_layout (GdlDataFrame *frame) -{ - GdkPixbuf *close_pixbuf; - /* Sizes */ - if (frame->priv->row) { - gdl_data_row_get_size (frame->priv->row, - NULL, NULL, - &frame->priv->row_r.width, - &frame->priv->row_r.height); - } else { - frame->priv->row_r.height = frame->priv->row_r.width = 0; - } - - if (frame->priv->layout) { - pango_layout_get_pixel_size (frame->priv->layout, - &frame->priv->title_r.width, - &frame->priv->title_r.height); - } else { - frame->priv->title_r.width = frame->priv->title_r.height = 0; - } - - close_pixbuf = gdl_data_view_get_close_pixbuf (frame->view); - if (close_pixbuf) { - frame->priv->close_r.width = - gdk_pixbuf_get_width (close_pixbuf); - frame->priv->close_r.height = - gdk_pixbuf_get_width (close_pixbuf); - } else { - frame->priv->close_r.width = frame->priv->close_r.height = 0; - } - - frame->priv->titlebar_r.height = MAX (frame->priv->titlebar_height, - frame->priv->title_r.height); - frame->priv->titlebar_r.height = MAX (frame->priv->titlebar_r.height, - frame->priv->close_r.height); - - frame->priv->frame_r.width = 2 * BORDER + 3 * PAD + frame->priv->title_r.width + frame->priv->close_r.width; - frame->priv->frame_r.width = MAX (frame->priv->frame_r.width, - frame->priv->row_r.width + 2 * BORDER + 2 * PAD); - frame->priv->frame_r.height = frame->priv->row_r.height + frame->priv->titlebar_r.height + 2 * PAD + 2 * BORDER; - frame->priv->titlebar_r.width = frame->priv->frame_r.width - BORDER; - frame->priv->shadow_r.width = frame->priv->frame_r.width; - frame->priv->shadow_r.height = frame->priv->frame_r.height; - - /* Locations */ - frame->priv->frame_r.x = frame->area.x; - frame->priv->frame_r.y = frame->area.y; - - frame->priv->shadow_r.x = frame->priv->frame_r.x + frame->priv->shadow_offset; - frame->priv->shadow_r.y = frame->priv->frame_r.y + frame->priv->shadow_offset; - frame->priv->titlebar_r.x = frame->priv->frame_r.x + BORDER; - frame->priv->titlebar_r.y = frame->priv->frame_r.y + BORDER; - frame->priv->title_r.x = frame->priv->frame_r.x + BORDER + PAD; - CENTERY (frame->priv->title_r, frame->priv->titlebar_r); - frame->priv->close_r.x = (frame->priv->frame_r.x + frame->priv->frame_r.width) - (frame->priv->close_r.width + BORDER + PAD); - CENTERY (frame->priv->close_r, frame->priv->titlebar_r); - - if (frame->priv->row) { - frame->priv->row_r.x = frame->priv->frame_r.x + BORDER + PAD; - frame->priv->row_r.y = frame->priv->titlebar_r.y + frame->priv->titlebar_r.height + PAD; - gdl_data_row_layout (frame->priv->row, &frame->priv->row_r); - } else { - frame->priv->row_r.x = frame->priv->row_r.y = 0; - } - - frame->area.width = frame->priv->frame_r.width + frame->priv->shadow_offset; - frame->area.height = frame->priv->frame_r.height + frame->priv->shadow_offset; -} - -#if 0 /* not used */ -static void -change_layout (GdlDataFrame *frame) -{ - char *text = frame->priv->title ? frame->priv->title : "?"; - pango_layout_set_text (frame->priv->layout, text, strlen (text)); -} -#endif - -#define EXPLODE(r) (r).x, (r).y, (r).width, (r).height - -void -gdl_data_frame_draw (GdlDataFrame *frame, GdkDrawable *drawable, - GdkRectangle *expose_area) -{ - GdkRectangle inter; - guint8 state = - frame->priv->selected ? GTK_STATE_SELECTED : GTK_STATE_NORMAL; - - gdk_draw_rectangle (drawable, - GTK_WIDGET (frame->view)->style->dark_gc[state], - TRUE, - EXPLODE (frame->priv->shadow_r)); - gdk_draw_rectangle (drawable, - GTK_WIDGET (frame->view)->style->base_gc[GTK_STATE_NORMAL], - TRUE, - EXPLODE (frame->priv->frame_r)); - gdk_draw_rectangle (drawable, - GTK_WIDGET (frame->view)->style->black_gc, - FALSE, - EXPLODE (frame->priv->frame_r)); - gdk_draw_rectangle (drawable, - GTK_WIDGET (frame->view)->style->bg_gc[state], - TRUE, - EXPLODE (frame->priv->titlebar_r)); - gdk_draw_layout (drawable, - GTK_WIDGET (frame->view)->style->fg_gc[state], - frame->priv->title_r.x, frame->priv->title_r.y, - frame->priv->layout); - - if (gdk_rectangle_intersect (expose_area, &frame->priv->close_r, &inter)) { - GdkPixbuf *pixbuf = gdl_data_view_get_close_pixbuf (frame->view); - gdk_draw_pixbuf (drawable, NULL, pixbuf, - 0, 0, - inter.x - frame->priv->close_r.x, - inter.y - frame->priv->close_r.y, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - GDK_RGB_DITHER_NORMAL, 0, 0); - } - - if (frame->priv->row) { - if (gdk_rectangle_intersect (expose_area, &frame->priv->row_r, - &inter)) { - gdl_data_row_render (frame->priv->row, drawable, - &inter, - frame->priv->selected ? GTK_CELL_RENDERER_SELECTED : 0); - } - } -} - -void -gdl_data_frame_class_init (GdlDataFrameClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass *)klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = gdl_data_frame_finalize; -} - -void -gdl_data_frame_instance_init (GdlDataFrame *frame) -{ - frame->priv = g_new0 (GdlDataFramePrivate, 1); - frame->area.x = frame->area.y = 0; - frame->priv->shadow_offset = 3; - frame->priv->titlebar_height = 20; - - frame->area.height = frame->area.width = 100; -} - -void -gdl_data_frame_finalize (GObject *object) -{ - GdlDataFrame *frame = GDL_DATA_FRAME (object); - - if (frame->priv) { - g_free (frame->priv->title); - g_object_unref (frame->priv->layout); - g_object_unref (frame->priv->row); - - g_free (frame->priv); - frame->priv = NULL; - } - GDL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); -} - -void -gdl_data_frame_set_selected (GdlDataFrame *frame, - gboolean val) -{ - frame->priv->selected = val; - - gdk_window_invalidate_rect (GTK_LAYOUT (frame->view)->bin_window, - &frame->priv->frame_r, - TRUE); -} - -gboolean -gdl_data_frame_button_press (GdlDataFrame *frame, - GdkEventButton *event) -{ - return FALSE; -} - -void -gdl_data_frame_set_position (GdlDataFrame *frame, - int x, - int y) -{ - frame->area.x = x; - frame->area.y = y; - - gdl_data_frame_layout (frame); -} - -static void -setup_layout (GdlDataFrame *frame) -{ - PangoFontDescription *font_desc = - pango_font_description_copy (GTK_WIDGET (frame->view)->style->font_desc); - - pango_font_description_set_weight (font_desc, - PANGO_WEIGHT_BOLD); - - frame->priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (frame->view), - frame->priv->title ? frame->priv->title : "?"); - pango_layout_set_font_description (frame->priv->layout, - font_desc); - pango_font_description_free (font_desc); -} - - -GdlDataFrame * -gdl_data_frame_new (GdlDataView *view, - GdlDataRow *row) -{ - GdlDataFrame *frame; - frame = GDL_DATA_FRAME (g_object_new (GDL_TYPE_DATA_FRAME, NULL)); - - frame->view = view; - - frame->priv->row = row; - frame->priv->title = g_strdup (gdl_data_row_get_title (row)); - - setup_layout (frame); - - gdl_data_frame_layout (frame); - - return frame; -} diff --git a/src/libgdl/gdl-data-frame.h b/src/libgdl/gdl-data-frame.h deleted file mode 100644 index 7daeb5b12..000000000 --- a/src/libgdl/gdl-data-frame.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef GDL_DATA_FRAME_H -#define GDL_DATA_FRAME_H - -#include -#include - -G_BEGIN_DECLS - -#define GDL_TYPE_DATA_FRAME (gdl_data_frame_get_type ()) -#define GDL_DATA_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrame)) -#define GDL_DATA_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_DATA_VIEW_FRAM, GdlDataFrame)) -#define GDL_IS_DATA_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_FRAME)) -#define GDL_IS_DATA_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_FRAME)) -#define GDL_DATA_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDL_TYPE_DATA_FRAME, GdlDataFrameClass)) - -typedef struct _GdlDataFrame GdlDataFrame; -typedef struct _GdlDataFramePrivate GdlDataFramePrivate; -typedef struct _GdlDataFrameClass GdlDataFrameClass; - -struct _GdlDataFrame { - GObject parent; - - GdlDataView *view; - GdkRectangle area; - - GdlDataFramePrivate *priv; -}; - -struct _GdlDataFrameClass { - GObjectClass parent_class; -}; - -GType gdl_data_frame_get_type (void); -GdlDataFrame *gdl_data_frame_new (GdlDataView *view, - GdlDataRow *row); -void gdl_data_frame_layout (GdlDataFrame *frame); -void gdl_data_frame_draw (GdlDataFrame *item, - GdkDrawable *drawable, - GdkRectangle *expose_area); -void gdl_data_frame_set_selected (GdlDataFrame *frame, - gboolean val); -gboolean gdl_data_frame_button_press (GdlDataFrame *frame, - GdkEventButton *event); -void gdl_data_frame_set_position (GdlDataFrame *frame, - int x, - int y); - -G_END_DECLS - -#endif diff --git a/src/libgdl/gdl-data-model-test.c b/src/libgdl/gdl-data-model-test.c deleted file mode 100644 index ec6ed4d50..000000000 --- a/src/libgdl/gdl-data-model-test.c +++ /dev/null @@ -1,240 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-i18n.h" - -#include "gdl-data-model-test.h" -#include "gdl-data-model.h" - -#include -#include -#include - -GObjectClass *parent_class; - -typedef struct _DataItem { - char *name; - char *value; - char *path; - struct _DataItem *children; -} DataItem; - -DataItem data1[] = { - { "foo1", "foo1", "0:0", NULL}, - { "bar1", "bar1", "0:1", NULL }, - { "baz1", "baz1", "0:2", NULL }, - { NULL, NULL, NULL, NULL } - -}; -DataItem data2[] = { - { "foo2", "foo2", "1:0", NULL }, - { "bar2", "bar2", "1:1", NULL }, - { "baz2", "baz2", "1:2", NULL }, - { NULL, NULL, NULL, NULL } - -}; - -DataItem data5[] = { - { "1", "1", "2:2:1:0", NULL }, - { "2", "2", "2:2:1:1", NULL }, - { "3", "3", "2:2:1:2", NULL }, - { "4", "4", "2:2:1:3", NULL }, - { "5", "5", "2:2:1:4", NULL }, - { "6", "6", "2:2:1:5", NULL }, - { NULL, NULL, NULL, NULL } - -}; -DataItem data4[] = { - { "foo4", "foo4", "2:2:0", NULL }, - { "bar4", "[...]", "2:2:1", data5 }, - { "baz4", "baz4", "2:2:2", NULL }, - { NULL, NULL, NULL, NULL } - -}; -DataItem data3[] = { - { "foo foo", "foo3", "2:0", NULL }, - { "bar3", "1", "2:1", NULL }, - { "baz3", "{...}", "2:2", data4 }, - { NULL, NULL, NULL, NULL } - -}; - -DataItem root[] = { - { "test-data", "value1", "0", NULL } , - { "test-data2", "value2", "1", NULL } , - { "test-data3", "{...}", "2", data3 } , - { NULL, NULL, NULL } -}; - -static gboolean -get_iter (GdlDataModel *dm, GdlDataIter *iter, GtkTreePath *path) -{ - int *i = gtk_tree_path_get_indices (path); - int n = gtk_tree_path_get_depth (path); - DataItem *item; - - g_assert (i); - item = &root[*i++]; - - while (--n) { - item = &item->children[*i++]; - } - - iter->data1 = item; - - return TRUE; -} - -static GtkTreePath * -get_path (GdlDataModel *dm, GdlDataIter *iter) -{ - DataItem *item = iter->data1; - return gtk_tree_path_new_from_string (item->path); -} - -static void -get_name (GdlDataModel *dm, GdlDataIter *iter, char **name) -{ - DataItem *item = iter->data1; - *name = item->name; -} - -static void -get_value (GdlDataModel *dm, GdlDataIter *iter, GValue *value) -{ - DataItem *item = iter->data1; - if (strcmp (item->name, "bar3")) { - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, item->value); - } else { - g_value_init (value, G_TYPE_BOOLEAN); - g_value_set_boolean (value, !strcmp (item->value, "1")); - } -} - -static void -get_renderer (GdlDataModel *dm, GdlDataIter *iter, - GtkCellRenderer **renderer, char **field, - gboolean *is_editable) -{ - DataItem *item = iter->data1; - if (!strcmp (item->name, "bar3")) { - *renderer = g_object_new (gtk_cell_renderer_toggle_get_type (), - "activatable", TRUE, NULL); - *field = "active"; - } else { - *renderer = g_object_new (gtk_cell_renderer_text_get_type (), - "editable", TRUE, NULL); - *field = "text"; - } - *is_editable = (item->children == NULL); -} - -static gboolean -iter_next (GdlDataModel *dm, GdlDataIter *iter) -{ - DataItem *item = iter->data1; - item++; - if (item->name) { - iter->data1 = item; - return TRUE; - } else { - return FALSE; - } -} - -static gboolean -iter_children (GdlDataModel *dm, GdlDataIter *iter, GdlDataIter *parent) -{ - DataItem *item = parent->data1; - - item = &item->children[0]; - if (item) { - iter->data1 = item; - return TRUE; - } else { - return FALSE; - } -} - -static gboolean -iter_has_child (GdlDataModel *dm, GdlDataIter *iter) -{ - DataItem *item = iter->data1; - if (item->children) { - return TRUE; - } else { - return FALSE; - } -} - - -static void -gdl_data_model_test_instance_init (GdlDataModelTest *model) -{ -} - -static void -gdl_data_model_test_finalize (GObject *object) -{ - (*parent_class->finalize) (object); -} - -static void -gdl_data_model_test_class_init (GdlDataModelTestClass *klass) -{ - GObjectClass *object_class; - parent_class = g_type_class_peek_parent (klass); - object_class = (GObjectClass *)klass; - object_class->finalize = gdl_data_model_test_finalize; -} - -static void -gdl_data_model_test_data_model_init (GdlDataModelIface *iface) -{ - iface->get_iter = get_iter; - iface->get_path = get_path; - iface->get_name = get_name; - iface->get_value = get_value; - iface->get_renderer = get_renderer; - iface->iter_next = iter_next; - iface->iter_children = iter_children; - iface->iter_has_child = iter_has_child; -} - -GType -gdl_data_model_test_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo data_model_test_info = { - sizeof (GdlDataModelTestClass), - NULL, NULL, - (GClassInitFunc) gdl_data_model_test_class_init, - NULL, NULL, - sizeof (GdlDataModelTest), 0, - (GInstanceInitFunc) gdl_data_model_test_instance_init - }; - - static const GInterfaceInfo data_model_info = { - (GInterfaceInitFunc) gdl_data_model_test_data_model_init, - NULL, NULL - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "GdlDataModelTest", - &data_model_test_info, 0); - g_type_add_interface_static (type, - GDL_TYPE_DATA_MODEL, - &data_model_info); - } - return type; -} - -GdlDataModelTest * -gdl_data_model_test_new (void) -{ - return GDL_DATA_MODEL_TEST (g_object_new (gdl_data_model_test_get_type (), NULL)); -} diff --git a/src/libgdl/gdl-data-model-test.h b/src/libgdl/gdl-data-model-test.h deleted file mode 100644 index c8add8daf..000000000 --- a/src/libgdl/gdl-data-model-test.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef GDL_DATA_MODEL_TEST_H -#define GDL_DATA_MODEL_TEST_H - -#include -#include "gdl-data-model.h" - -G_BEGIN_DECLS - -#define GDL_TYPE_DATA_MODEL_TEST (gdl_data_model_test_get_type ()) -#define GDL_DATA_MODEL_TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_MODEL_TEST, GdlDataModelTest)) -#define GDL_IS_DATA_MODEL_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_MODEL_TEST)) - - -typedef struct _GdlDataModelTest GdlDataModelTest; -typedef struct _GdlDataModelTestClass GdlDataModelTestClass; - -struct _GdlDataModelTest { - GObject parent; - - int stamp; -}; - -struct _GdlDataModelTestClass { - GObjectClass parent_class; -}; - -GType gdl_data_model_test_get_type (void); -GdlDataModelTest *gdl_data_model_test_new (void); - -G_END_DECLS - -#endif diff --git a/src/libgdl/gdl-data-model.c b/src/libgdl/gdl-data-model.c deleted file mode 100644 index 69fbb93d5..000000000 --- a/src/libgdl/gdl-data-model.c +++ /dev/null @@ -1,160 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-data-model.h" - -gboolean -gdl_data_model_get_iter (GdlDataModel *dm, - GdlDataIter *iter, - GtkTreePath *path) -{ - g_return_val_if_fail (dm != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (path != NULL, FALSE); - g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_iter != NULL, - FALSE); - - return (*GDL_DATA_MODEL_GET_IFACE (dm)->get_iter) (dm, iter, path); -} - -GtkTreePath * -gdl_data_model_get_path (GdlDataModel *dm, - GdlDataIter *iter) -{ - g_return_val_if_fail (dm != NULL, NULL); - g_return_val_if_fail (iter != NULL, NULL); - g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_path != NULL, - NULL); - - return (*GDL_DATA_MODEL_GET_IFACE (dm)->get_path) (dm, iter); -} - -void -gdl_data_model_get_name (GdlDataModel *dm, - GdlDataIter *iter, - char **name) -{ - g_return_if_fail (dm != NULL); - g_return_if_fail (iter != NULL); - g_return_if_fail (name != NULL); - g_return_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_name != NULL); - - (*GDL_DATA_MODEL_GET_IFACE (dm)->get_name) (dm, iter, name); -} - -void -gdl_data_model_get_value (GdlDataModel *dm, - GdlDataIter *iter, - GValue *value) -{ - g_return_if_fail (dm != NULL); - g_return_if_fail (iter != NULL); - g_return_if_fail (value != NULL); - g_return_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_value != NULL); - - (*GDL_DATA_MODEL_GET_IFACE (dm)->get_value) (dm, iter, value); -} - -void -gdl_data_model_get_renderer (GdlDataModel *dm, - GdlDataIter *iter, - GtkCellRenderer **renderer, - char **field, - gboolean *is_editable) -{ - g_return_if_fail (dm != NULL); - g_return_if_fail (iter != NULL); - g_return_if_fail (renderer != NULL); - g_return_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->get_renderer != NULL); - - (*GDL_DATA_MODEL_GET_IFACE (dm)->get_renderer) (dm, iter, - renderer, field, - is_editable); -} - -gboolean -gdl_data_model_iter_next (GdlDataModel *dm, - GdlDataIter *iter) -{ - g_return_val_if_fail (dm != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->iter_next != NULL, FALSE); - - return (*GDL_DATA_MODEL_GET_IFACE (dm)->iter_next) (dm, iter); -} - -gboolean -gdl_data_model_iter_children (GdlDataModel *dm, - GdlDataIter *iter, - GdlDataIter *parent) -{ - g_return_val_if_fail (dm != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->iter_children != NULL, FALSE); - - return (*GDL_DATA_MODEL_GET_IFACE (dm)->iter_children) (dm, iter, parent); -} - -gboolean -gdl_data_model_iter_has_child (GdlDataModel *dm, - GdlDataIter *iter) -{ - g_return_val_if_fail (dm != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (GDL_DATA_MODEL_GET_IFACE (dm)->iter_has_child != NULL, FALSE); - - return (*GDL_DATA_MODEL_GET_IFACE (dm)->iter_has_child) (dm, iter); -} - -static void -gdl_data_model_base_init (gpointer g_class) -{ - static gboolean initialized = FALSE; - - if (!initialized) { - } -} - -GType -gdl_data_model_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (GdlDataModelIface), - gdl_data_model_base_init, - NULL, NULL, NULL, NULL, 0, 0, NULL - }; - - type = g_type_register_static (G_TYPE_INTERFACE, - "GdlDataModel", - &info, 0); - g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); - } - - return type; -} diff --git a/src/libgdl/gdl-data-model.h b/src/libgdl/gdl-data-model.h deleted file mode 100644 index 521a65d0c..000000000 --- a/src/libgdl/gdl-data-model.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef GDL_DATA_MODEL_H -#define GDL_DATA_MODEL_H - -#include -#include - -/* Using GtkTreePath to save time */ -#include -#include - -G_BEGIN_DECLS - -#define GDL_TYPE_DATA_MODEL (gdl_data_model_get_type ()) -#define GDL_DATA_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_MODEL, GdlDataModel)) -#define GDL_IS_DATA_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_MODEL)) -#define GDL_DATA_MODEL_GET_IFACE(obj) ((GdlDataModelIface *)g_type_interface_peek (((GTypeInstance *)GDL_DATA_MODEL (obj))->g_class, GDL_TYPE_DATA_MODEL)) - -typedef struct _GdlDataModel GdlDataModel; -typedef struct _GdlDataIter GdlDataIter; -typedef struct _GdlDataModelIface GdlDataModelIface; - -struct _GdlDataIter { - int stamp; - - gpointer data1; - gpointer data2; - gpointer data3; -}; - -struct _GdlDataModelIface { - GTypeInterface g_iface; - - /* Signals */ - void (*path_changed) (GdlDataModel *dm, GtkTreePath *path); - void (*path_inserted) (GdlDataModel *dm, GtkTreePath *path); - void (*path_deleted) (GdlDataModel *dm, GtkTreePath *path); - - /* Virtual Table */ - gboolean (*get_iter) (GdlDataModel *dm, GdlDataIter *iter, - GtkTreePath *path); - GtkTreePath* (*get_path) (GdlDataModel *dm, GdlDataIter *iter); - - void (*get_name) (GdlDataModel *dm, GdlDataIter *iter, - char **name); - void (*get_value) (GdlDataModel *dm, GdlDataIter *iter, - GValue *value); - void (*get_renderer) (GdlDataModel *dm, GdlDataIter *iter, - GtkCellRenderer **renderer, char **field, - gboolean *is_editable); - gboolean (*iter_next) (GdlDataModel *dm, GdlDataIter *iter); - gboolean (*iter_children) (GdlDataModel *dm, GdlDataIter *iter, - GdlDataIter *parent); - gboolean (*iter_has_child) (GdlDataModel *dm, GdlDataIter *iter); -}; - -GType gdl_data_model_get_type (void); -gboolean gdl_data_model_get_iter (GdlDataModel *dm, - GdlDataIter *iter, - GtkTreePath *path); -GtkTreePath *gdl_data_model_get_path (GdlDataModel *dm, - GdlDataIter *iter); -void gdl_data_model_get_name (GdlDataModel *dm, - GdlDataIter *iter, - char **name); -void gdl_data_model_get_value (GdlDataModel *dm, - GdlDataIter *iter, - GValue *value); -void gdl_data_model_get_renderer (GdlDataModel *dm, - GdlDataIter *iter, - GtkCellRenderer **renderer, - char **field, - gboolean *is_editable); -gboolean gdl_data_model_iter_next (GdlDataModel *dm, - GdlDataIter *iter); -gboolean gdl_data_model_iter_children (GdlDataModel *dm, - GdlDataIter *iter, - GdlDataIter *children); -gboolean gdl_data_model_iter_has_child (GdlDataModel *dm, - GdlDataIter *iter); - -G_END_DECLS - -#endif diff --git a/src/libgdl/gdl-data-row.c b/src/libgdl/gdl-data-row.c deleted file mode 100644 index 666c658fe..000000000 --- a/src/libgdl/gdl-data-row.c +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-i18n.h" -#include "gdl-tools.h" -#include "gdl-data-row.h" -#include "gdl-data-model.h" - -#include -#include - -struct _GdlDataRowPrivate { - GdlDataModel *model; - GtkTreePath *path; - GdlDataView *view; - - char *name; - - /* area_r - * +- title_r - * | +- name_r - * | +- sep_r - * +- data_r - * +- expand_r - * +- cell_r - */ - - GdkRectangle area_r; - - GdkRectangle title_r; - GdkRectangle name_r; - GdkRectangle sep_r; - - GdkRectangle data_r; - GdkRectangle expand_r; - GdkRectangle cell_r; - - gboolean multi; - GtkCellRenderer *cell; - GList *subrows; - - char *renderer_field; - - gboolean expanded; - gboolean focused; - gboolean editable; - - int split; - int child_split; - gboolean selected; -}; - -GDL_CLASS_BOILERPLATE (GdlDataRow, gdl_data_row, GObject, G_TYPE_OBJECT); - - -static void -expand (GdlDataRow *row) -{ - GdlDataIter iter; - gboolean valid; - - if (gdl_data_model_get_iter (row->priv->model, &iter, row->priv->path)) { - valid = gdl_data_model_iter_children (row->priv->model, - &iter, &iter); - while (valid) { - GdlDataRow *new_row; - GtkTreePath *path; - - path = gdl_data_model_get_path (row->priv->model, - &iter); - new_row = gdl_data_row_new (row->priv->view, - path); - row->priv->subrows = - g_list_prepend (row->priv->subrows, new_row); - gtk_tree_path_free (path); - - valid = gdl_data_model_iter_next (row->priv->model, - &iter); - } - row->priv->subrows = g_list_reverse (row->priv->subrows); - - row->priv->expanded = TRUE; - gdl_data_view_layout (GDL_DATA_VIEW (row->priv->view)); - gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); - } -} - -static void -contract (GdlDataRow *row) -{ - GList *l; - for (l = row->priv->subrows; l != NULL; l = l->next) { - g_object_unref (G_OBJECT (l->data)); - } - g_list_free (row->priv->subrows); - row->priv->subrows = NULL; - - row->priv->expanded = FALSE; - gdl_data_view_layout (GDL_DATA_VIEW (row->priv->view)); - gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); -} - -static void -load_path (GdlDataRow *row) -{ - GdlDataIter iter; - - /* Make sure the path has been unloaded */ - g_return_if_fail (row->priv->name == NULL); - g_return_if_fail (row->priv->cell == NULL); - - if (gdl_data_model_get_iter (row->priv->model, - &iter, row->priv->path)) { - GValue val = { 0, }; - char *str; - - gdl_data_model_get_name (row->priv->model, &iter, - &str); - row->priv->name = g_strdup (str); - - if (gdl_data_model_iter_has_child (row->priv->model, &iter)) { - row->priv->multi = TRUE; - } - - gdl_data_model_get_renderer (row->priv->model, &iter, - &row->priv->cell, - &str, - &row->priv->editable); - g_object_ref (GTK_OBJECT (row->priv->cell)); - gtk_object_sink (GTK_OBJECT (row->priv->cell)); - - row->priv->renderer_field = g_strdup (str); - gdl_data_model_get_value (row->priv->model, &iter, &val); - - g_object_set_property (G_OBJECT (row->priv->cell), - row->priv->renderer_field, - &val); - g_value_unset (&val); - } -} - -static void -unload_path (GdlDataRow *row) -{ - if (row->priv->renderer_field) { - g_free (row->priv->renderer_field); - row->priv->renderer_field = NULL; - } - - if (row->priv->name) { - g_free (row->priv->name); - row->priv->name = NULL; - } - - if (row->priv->cell) { - g_object_unref (row->priv->cell); - row->priv->cell = NULL; - } - - if (row->priv->subrows) { - GList *l; - for (l = row->priv->subrows; l != NULL; l = l->next) { - g_object_unref (G_OBJECT (l->data)); - } - g_list_free (row->priv->subrows); - row->priv->subrows = NULL; - } -} - -static void -gdl_data_row_instance_init (GdlDataRow *row) -{ - row->priv = g_new0 (GdlDataRowPrivate, 1); -} - -static void -gdl_data_row_finalize (GObject *object) -{ - GdlDataRow *row = GDL_DATA_ROW (object); - if (row->priv) { - unload_path (row); - - if (row->priv->path) { - gtk_tree_path_free (row->priv->path); - row->priv->path = NULL; - } - - - g_object_unref (row->priv->model); - - g_free (row->priv); - row->priv = NULL; - } -} - -static void -gdl_data_row_class_init (GdlDataRowClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*) klass; - gobject_class->finalize = gdl_data_row_finalize; - - parent_class = g_type_class_peek_parent (klass); -} - -GdlDataRow * -gdl_data_row_new (GdlDataView *view, - GtkTreePath *path) -{ - GdlDataRow *row; - - row = GDL_DATA_ROW (g_object_new (gdl_data_row_get_type (), - NULL)); - - row->priv->view = view; - row->priv->model = g_object_ref (view->model); - row->priv->path = gtk_tree_path_copy (path); - load_path (row); - - return row; -} - - -#define PAD 3 - -static void -layout_row (GdlDataRow *row, - int x, int y, int width, int height) -{ - PangoLayout *layout; - - /* sizes */ - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), - row->priv->name); - pango_layout_get_pixel_size (layout, - &row->priv->name_r.width, - &row->priv->name_r.height); - g_object_unref (layout); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), "="); - pango_layout_get_pixel_size (layout, - &row->priv->sep_r.width, - &row->priv->sep_r.height); - g_object_unref (layout); - - row->priv->title_r.width = - MAX (row->priv->name_r.width + row->priv->sep_r.width + PAD, - row->priv->split); - row->priv->title_r.height = - MAX (row->priv->name_r.height, row->priv->sep_r.width); - - if (row->priv->cell) { - gtk_cell_renderer_get_size (row->priv->cell, - GTK_WIDGET (row->priv->view), - NULL, NULL, NULL, - &row->priv->cell_r.width, - &row->priv->cell_r.height); - } else { - row->priv->cell_r.width = row->priv->cell_r.height = 0; - } - - row->priv->data_r.width = row->priv->cell_r.width; - row->priv->data_r.height = row->priv->cell_r.height; - - if (row->priv->multi) { - row->priv->expand_r.width = 10; - row->priv->expand_r.height = 10; - - row->priv->data_r.width += row->priv->expand_r.width; - row->priv->data_r.height = MAX (row->priv->expand_r.height, - row->priv->data_r.height); - - if (row->priv->expanded) { - GList *l; - int name_w = 0, data_w = 0; - for (l = row->priv->subrows; l != NULL; l = l->next) { - int w1, w2, h; - gdl_data_row_get_size (GDL_DATA_ROW (l->data), - &w1, &w2, NULL, &h); - name_w = MAX (name_w, w1); - data_w = MAX (data_w, w2); - row->priv->data_r.height += h; - } - row->priv->child_split = name_w; - row->priv->data_r.width = - MAX (name_w + data_w + 3 * PAD, - row->priv->data_r.width); - row->priv->data_r.height += 2 * PAD; - } - } - - row->priv->area_r.width = MAX (width, - row->priv->data_r.width + row->priv->title_r.width + PAD); - - row->priv->area_r.height = MAX (height, - (MAX (row->priv->data_r.height, - row->priv->title_r.height))); - - /* Positions */ - - row->priv->area_r.x = x; - row->priv->area_r.y = y; - - row->priv->title_r.x = x; - row->priv->title_r.y = y + ((row->priv->area_r.height) / 2) - (row->priv->title_r.height / 2); - - row->priv->name_r.x = x; - row->priv->name_r.y = y + ((row->priv->area_r.height) / 2) - (row->priv->name_r.height / 2); - - row->priv->sep_r.x = row->priv->title_r.x + row->priv->title_r.width - row->priv->sep_r.width; - row->priv->sep_r.y = y + ((row->priv->area_r.height) / 2) - (row->priv->sep_r.height / 2); - - row->priv->data_r.x = row->priv->title_r.x + row->priv->title_r.width + PAD; - row->priv->data_r.y = y; - - /* Readjust the data area size to fit */ - row->priv->data_r.width = row->priv->area_r.width - (row->priv->title_r.width + PAD); - row->priv->data_r.height = row->priv->area_r.height; - - if (row->priv->multi) { - row->priv->expand_r.x = row->priv->data_r.x; - row->priv->expand_r.y = row->priv->data_r.y + ((row->priv->cell_r.height) / 2) - (row->priv->expand_r.height / 2); - - row->priv->cell_r.y = row->priv->data_r.y; - row->priv->cell_r.height = MAX (row->priv->expand_r.height, row->priv->cell_r.height); - row->priv->cell_r.width = (row->priv->data_r.width - row->priv->expand_r.width); - - row->priv->cell_r.x = row->priv->expand_r.x + row->priv->expand_r.width; - } else { - row->priv->cell_r = row->priv->data_r; - } -} - -void -gdl_data_row_get_size (GdlDataRow *row, int *sep_width, - int *cell_width, int *total_width, int *height) -{ - layout_row (row, 0, 0, 0, 0); - - if (sep_width) { - *sep_width = row->priv->name_r.width + row->priv->sep_r.width + PAD; - } - - if (cell_width) *cell_width = row->priv->data_r.width; - if (total_width) *total_width = row->priv->area_r.width; - if (height) *height = row->priv->area_r.height; -} - -void -gdl_data_row_set_show_name (GdlDataRow *row, gboolean show_name) -{ -} - -void -gdl_data_row_layout (GdlDataRow *row, GdkRectangle *alloc) -{ - layout_row (row, alloc->x, alloc->y, alloc->width, alloc->height); - - if (row->priv->multi && row->priv->expanded) { - GList *l; - GdkRectangle sub; - sub.y = row->priv->expand_r.y + row->priv->expand_r.width + PAD; - sub.x = row->priv->data_r.x + PAD; - sub.width = row->priv->data_r.width - 2 * PAD; - sub.height = row->priv->data_r.height - 2 * PAD; - - for (l = row->priv->subrows; l != NULL; l = l->next) { - gdl_data_row_get_size (GDL_DATA_ROW (l->data), - NULL, NULL, NULL, &sub.height); - gdl_data_row_set_split (GDL_DATA_ROW (l->data), - row->priv->child_split); - gdl_data_row_layout (GDL_DATA_ROW (l->data), - &sub); - sub.y += sub.height; - } - } -} - -#if 0 -#define DRAWR(r) { gdk_draw_rectangle (drawable, GTK_WIDGET (row->priv->view)->style->text_gc[GTK_STATE_NORMAL],FALSE,row->priv->r.x,row->priv->r.y,row->priv->r.width, row->priv->r.height); } -#else -#define DRAWR(r) -#endif - - -void -gdl_data_row_render (GdlDataRow *row, GdkDrawable *drawable, - GdkRectangle *expose_area, - GtkCellRendererState flags) -{ - PangoLayout *layout; - - guint state = GTK_STATE_NORMAL; - - if (row->priv->selected) { - if (flags & GTK_CELL_RENDERER_SELECTED) - state = GTK_STATE_SELECTED; - else - state = GTK_STATE_ACTIVE; - gtk_paint_flat_box (GTK_WIDGET (row->priv->view)->style, - drawable, state, - GTK_SHADOW_NONE, expose_area, - GTK_WIDGET (row->priv->view), "cell_even", - row->priv->area_r.x, row->priv->area_r.y, - row->priv->area_r.width + 1, - row->priv->area_r.height + 1); - - } - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), - row->priv->name); - gdk_draw_layout (drawable, - GTK_WIDGET (row->priv->view)->style->text_gc[state], - row->priv->name_r.x, row->priv->name_r.y, layout); - g_object_unref (layout); - DRAWR(name_r); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (row->priv->view), "="); - gdk_draw_layout (drawable, - GTK_WIDGET (row->priv->view)->style->text_gc[state], - row->priv->sep_r.x, row->priv->sep_r.y, layout); - g_object_unref (layout); - DRAWR(sep_r); - DRAWR(title_r); - - if (row->priv->cell) { - if (row->priv->focused) { - gtk_paint_focus (GTK_WIDGET (row->priv->view)->style, - drawable, - GTK_WIDGET_STATE (GTK_WIDGET (row->priv->view)), - NULL, GTK_WIDGET (row->priv->view), - "treeview", - row->priv->cell_r.x - 1, - row->priv->cell_r.y - 1, - row->priv->cell_r.width + 2, - row->priv->cell_r.height + 2); - } - - gtk_cell_renderer_render (row->priv->cell, - drawable, GTK_WIDGET (row->priv->view), - &row->priv->area_r, - &row->priv->cell_r, - expose_area, - row->priv->selected ? GTK_CELL_RENDERER_SELECTED : 0); - DRAWR(cell_r); - } - if (row->priv->multi) { - gtk_paint_expander (GTK_WIDGET (row->priv->view)->style, - drawable, - GTK_WIDGET_STATE (GTK_WIDGET (row->priv->view)), - expose_area, - GTK_WIDGET (row->priv->view), - "gdldataview", - row->priv->expand_r.x + row->priv->expand_r.width / 2, - row->priv->expand_r.y + row->priv->expand_r.height / 2, - row->priv->expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED); - DRAWR(expand_r); - - if (row->priv->expanded) { - GList *l; - - for (l = row->priv->subrows; l != NULL; l = l->next) { - gdl_data_row_render (GDL_DATA_ROW (l->data), - drawable, - expose_area, flags); - } - } - gdk_draw_rectangle (drawable, - GTK_WIDGET (row->priv->view)->style->text_gc[GTK_STATE_NORMAL], - FALSE, - row->priv->data_r.x, - row->priv->data_r.y, - row->priv->data_r.width, - row->priv->data_r.height); - } - DRAWR(data_r); -} - - -GdlDataRow * -gdl_data_row_at (GdlDataRow *row, int x, int y) -{ - if (!GDL_POINT_IN (x, y, &row->priv->area_r)) { - return NULL; - } - - if (row->priv->multi && row->priv->expanded) { - GList *l; - for (l = row->priv->subrows; l != NULL; l = l->next) { - GdlDataRow *ret = gdl_data_row_at (GDL_DATA_ROW (l->data), x, y); - if (ret) - return ret; - } - } - - return row; -} - -static gboolean -button_press_event (GdlDataRow *row, GdkEventButton *event, - GtkCellEditable **editable_widget) -{ - if (editable_widget) - *editable_widget = NULL; - - if (GDL_POINT_IN (event->x, event->y, &row->priv->expand_r)) { - if (row->priv->expanded) - contract (row); - else - expand (row); - } - - if (GDL_POINT_IN (event->x, event->y, &row->priv->cell_r) - && row->priv->editable) { - g_return_val_if_fail (editable_widget, FALSE); - *editable_widget = gtk_cell_renderer_start_editing - (row->priv->cell, - (GdkEvent*)event, - GTK_WIDGET (row->priv->view), - "1:2:3", - &row->priv->area_r, - &row->priv->cell_r, - GTK_CELL_RENDERER_SELECTED); - } - - return FALSE; - -} - - -gboolean -gdl_data_row_event (GdlDataRow *row, GdkEvent *event, - GtkCellEditable **editable_widget) -{ - switch (((GdkEventAny *)event)->type) { - case GDK_BUTTON_PRESS: - return button_press_event (row, - (GdkEventButton *)event, - editable_widget); - default: - break; - } - return FALSE; -} - -void -gdl_data_row_get_cell_area (GdlDataRow *row, - GdkRectangle *rect) -{ - *rect = row->priv->cell_r; -} - -void -gdl_data_row_set_split (GdlDataRow *row, int split) -{ - row->priv->split = split; -} - -void -gdl_data_row_set_selected (GdlDataRow *row, gboolean selected) -{ - row->priv->selected = selected; - - /* FIXME: invalidate here */ - gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); -} - -void -gdl_data_row_set_focused (GdlDataRow *row, gboolean focused) -{ - row->priv->focused = focused; - - /* FIXME: invalidate here */ - gtk_widget_queue_draw (GTK_WIDGET (row->priv->view)); -} - -const char * -gdl_data_row_get_title (GdlDataRow *row) -{ - return row->priv->name; -} diff --git a/src/libgdl/gdl-data-row.h b/src/libgdl/gdl-data-row.h deleted file mode 100644 index d4928958d..000000000 --- a/src/libgdl/gdl-data-row.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef GDL_DATA_ROW_H -#define GDL_DATA_ROW_H - -#include - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define GDL_TYPE_DATA_ROW (gdl_data_row_get_type ()) -#define GDL_DATA_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_ROW, GdlDataRow)) -#define GDL_DATA_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DATA_ROW, GdlDataRowClass)) -#define GDL_IS_DATA_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_ROW)) -#define GDL_IS_DATA_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_ROW)) - -typedef struct _GdlDataRow GdlDataRow; -typedef struct _GdlDataRowClass GdlDataRowClass; -typedef struct _GdlDataRowPrivate GdlDataRowPrivate; - -struct _GdlDataRow { - GObject parent; - - GdlDataRowPrivate *priv; -}; - -struct _GdlDataRowClass { - GObjectClass parent_class; -}; - -GType gdl_data_row_get_type (void); -GdlDataRow *gdl_data_row_new (GdlDataView *view, - GtkTreePath *path); -void gdl_data_row_get_size (GdlDataRow *row, - int *text_w, - int *cell_w, - int *total_width, - int *height); -void gdl_data_row_set_show_name (GdlDataRow *row, - gboolean show_name); -void gdl_data_row_layout (GdlDataRow *row, - GdkRectangle *alloc); -void gdl_data_row_render (GdlDataRow *row, - GdkDrawable *drawable, - GdkRectangle *expose_area, - GtkCellRendererState flags); -GdlDataRow *gdl_data_row_at (GdlDataRow *row, - int x, - int y); -gboolean gdl_data_row_event (GdlDataRow *row, - GdkEvent *event, - GtkCellEditable **editable_widget); -void gdl_data_row_get_cell_area (GdlDataRow *row, - GdkRectangle *rect); -void gdl_data_row_set_split (GdlDataRow *row, - int split); -void gdl_data_row_set_selected (GdlDataRow *row, - gboolean selected); -void gdl_data_row_set_focused (GdlDataRow *row, - gboolean focused); -const char *gdl_data_row_get_title (GdlDataRow *row); - - -G_END_DECLS - -#endif diff --git a/src/libgdl/gdl-data-view.c b/src/libgdl/gdl-data-view.c deleted file mode 100644 index 81e1795f7..000000000 --- a/src/libgdl/gdl-data-view.c +++ /dev/null @@ -1,526 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-i18n.h" -#include "gdl-tools.h" -#include "gdl-data-view.h" -#include "gdl-data-frame.h" - -#include "tree-expand.xpm" -#include "tree-contract.xpm" - -struct _GdlDataViewPrivate { - GList *frames; - GList *rows; - GList *widgets; - - GdlDataFrame *selected_frame; - GdlDataRow *selected_row; - - GtkCellEditable *editable; - - GdkPixbuf *close_pixbuf; - GdkPixbuf *expand_pixbuf; - GdkPixbuf *contract_pixbuf; -}; - -typedef struct { - GtkWidget *widget; - int x, y, height, width; -} ChildWidget; - -static void gdl_data_view_instance_init (GdlDataView *dv); -static void gdl_data_view_class_init (GdlDataViewClass *klass); - -GDL_CLASS_BOILERPLATE (GdlDataView, gdl_data_view, GtkLayout, GTK_TYPE_LAYOUT); - - -#define GRID_SPACING 15 - -static void -paint_grid (GtkWidget *widget, GdkDrawable *drawable, - int offset_x, int offset_y, int width, int height) -{ - GdlDataView *dv; - int x; - int y; - - g_return_if_fail (GDL_IS_DATA_VIEW (widget)); - dv = GDL_DATA_VIEW (widget); - - x = offset_x + ((GRID_SPACING - (offset_x % GRID_SPACING)) % GRID_SPACING); - - /* Draw grid points */ - for (; x < width; x += GRID_SPACING) { - y = offset_y + ((GRID_SPACING - (offset_y % GRID_SPACING)) % GRID_SPACING); - - for (; y < height; y += GRID_SPACING) { - gdk_draw_point (drawable, - widget->style->fg_gc[GTK_WIDGET_STATE (widget)], - x, y); - } - } -} - -static void -expose_frames (GdlDataView *view, GdkEventExpose *event) -{ - GList *l; - - for (l = view->priv->frames; l != NULL; l = l->next) { - GdkRectangle intersect; - GdlDataFrame *frame = GDL_DATA_FRAME (l->data); - if (gdk_rectangle_intersect (&frame->area, - &event->area, - &intersect)) { - gdl_data_frame_draw (GDL_DATA_FRAME (l->data), - GTK_LAYOUT(view)->bin_window, - &intersect); - } - } -} - -static void -expose_widgets (GdlDataView *view, GdkEventExpose *event) -{ - GList *l; - - for (l = view->priv->widgets; l != NULL; l = l->next) { - ChildWidget *child = l->data; - gtk_container_propagate_expose (GTK_CONTAINER (view), - child->widget, event); - } -} - -static gboolean -gdl_data_view_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - if (GTK_WIDGET_DRAWABLE (widget)) { - if (event->window == GTK_LAYOUT (widget)->bin_window) { - paint_grid (widget, GTK_LAYOUT (widget)->bin_window, - event->area.x, event->area.y, - event->area.width, event->area.height); - expose_frames (GDL_DATA_VIEW (widget), event); - expose_widgets (GDL_DATA_VIEW (widget), event); - return TRUE; - } else { - GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); - } - } - - return FALSE; -} - -static GdlDataFrame * -frame_at (GdlDataView *dv, int x, int y) -{ - GList *l; - for (l = dv->priv->frames; l != NULL; l = l->next) { - GdlDataFrame *frame = l->data; - if (x >= frame->area.x && x <= frame->area.x + frame->area.width - && y >= frame->area.y && y <= frame->area.y + frame->area.height) { - return frame; - } - } - return NULL; -} - -static GdlDataRow * -row_at (GdlDataView *view, int x, int y) -{ - GList *l; - GdlDataRow *ret = NULL; - for (l = view->priv->rows; l != NULL; l = l->next) { - GdlDataRow *row = l->data; - ret = gdl_data_row_at (row, x, y); - if (ret) break; - } - return ret; -} - -static void -gdl_data_view_put (GdlDataView *view, GtkWidget *widget, - int x, int y, int width, int height) -{ - ChildWidget *child = g_new0 (ChildWidget, 1); - - child->widget = widget; - child->x = x; - child->y = y; - child->width = width; - child->height = height; - - view->priv->widgets = g_list_append (view->priv->widgets, child); - - if (GTK_WIDGET_REALIZED (view)) { - gtk_widget_set_parent_window (child->widget, - GTK_LAYOUT (view)->bin_window); - } - - gtk_widget_set_parent (child->widget, GTK_WIDGET (view)); -} - -static void -stop_editing (GdlDataView *dv) -{ - if (dv->priv->editable) { - gtk_cell_editable_editing_done (dv->priv->editable); - gtk_cell_editable_remove_widget (dv->priv->editable); - } -} - -static void -remove_widget_cb (GtkCellEditable *cell_editable, GdlDataView *view) -{ - if (view->priv->editable) { - view->priv->editable = NULL; - gdl_data_row_set_focused (view->priv->selected_row, FALSE); - gtk_widget_grab_focus (GTK_WIDGET (view)); - gtk_container_remove (GTK_CONTAINER (view), - GTK_WIDGET (cell_editable)); - } -} - -static gboolean -button_press_event_cb (GdlDataView *dv, GdkEventButton *event, gpointer data) -{ - GdlDataFrame *frame; - GdlDataRow *row; - gboolean ret = FALSE; - - stop_editing (dv); - - if (event->type == GDK_BUTTON_PRESS) { - frame = frame_at (dv, event->x, event->y); - if (frame) { - if (dv->priv->selected_frame) { - gdl_data_frame_set_selected (dv->priv->selected_frame, FALSE); - } - gdl_data_frame_set_selected (frame, TRUE); - dv->priv->selected_frame = frame; - } - - row = row_at (dv, event->x, event->y); - if (row) { - GtkCellEditable *editable; - - if (dv->priv->selected_row) { - gdl_data_row_set_selected (dv->priv->selected_row, - FALSE); - } - dv->priv->selected_row = row; - gdl_data_row_set_selected (row, TRUE); - ret = gdl_data_row_event (row, (GdkEvent*)event, - &editable); - if (editable) { - GdkRectangle area; - dv->priv->editable = editable; - gtk_cell_editable_start_editing (editable, - (GdkEvent*)event); - - gdl_data_row_get_cell_area (row, &area); - gdl_data_view_put (dv, - GTK_WIDGET (editable), - area.x, - area.y, - area.width, - area.height); - - gtk_widget_grab_focus (GTK_WIDGET (editable)); - dv->priv->editable = editable; - gdl_data_row_set_focused (row, TRUE); - - g_signal_connect - (G_OBJECT (editable), - "remove_widget", - G_CALLBACK (remove_widget_cb), dv); - } - } - } - - return ret; -} - -static void -gdl_data_view_instance_init (GdlDataView *dv) -{ - GTK_WIDGET_SET_FLAGS (dv, GTK_CAN_FOCUS); - dv->priv = g_new0 (GdlDataViewPrivate, 1); - - g_signal_connect (G_OBJECT (dv), "button_press_event", - G_CALLBACK (button_press_event_cb), - NULL); - - dv->priv->close_pixbuf = gtk_widget_render_icon (GTK_WIDGET (dv), - "gtk-close", - GTK_ICON_SIZE_MENU, - "gdl-data-view-close"); - - dv->priv->expand_pixbuf = - gdk_pixbuf_new_from_xpm_data ((const char **)tree_expand_xpm); - - dv->priv->contract_pixbuf = - gdk_pixbuf_new_from_xpm_data ((const char **)tree_contract_xpm); -} - -static void -gdl_data_view_realize (GtkWidget *widget) -{ - GList *l; - GdlDataView *view = GDL_DATA_VIEW (widget); - - GDL_CALL_PARENT (GTK_WIDGET_CLASS, realize, (widget)); - - for (l = view->priv->widgets; l != NULL; l = l->next) { - ChildWidget *child = l->data; - gtk_widget_set_parent_window (child->widget, - GTK_LAYOUT (view)->bin_window); - } -} - -static void -gdl_data_view_size_request (GtkWidget *widget, GtkRequisition *req) -{ - GList *l; - - req->width = req->height = 0; - - for (l = GDL_DATA_VIEW (widget)->priv->widgets; l != NULL; l = l->next) { - GtkRequisition child_req; - ChildWidget *child = l->data; - - gtk_widget_size_request (child->widget, &child_req); - } -} - - -static void -gdl_data_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc) -{ - GdlDataView *view = GDL_DATA_VIEW (widget); - GList *l; -; - for (l = view->priv->widgets; l != NULL; l = l->next) { - ChildWidget *child = l->data; - GtkAllocation child_alloc; - - child_alloc.x = child->x; - child_alloc.y = child->y; - child_alloc.width = child->width; - child_alloc.height = child->height; - - gtk_widget_size_allocate (child->widget, &child_alloc); - } - GDL_CALL_PARENT (GTK_WIDGET_CLASS, size_allocate, (widget, alloc)); -} - -static void -gdl_data_view_forall (GtkContainer *container, gboolean include_internals, - GtkCallback callback, gpointer callback_data) -{ - GdlDataView *view = GDL_DATA_VIEW (container); - GList *l; - - for (l = view->priv->widgets; l != NULL; l = l->next) { - ChildWidget *child = l->data; - (*callback) (child->widget, callback_data); - } -} - -static void -gdl_data_view_remove (GtkContainer *container, GtkWidget *widget) -{ - GList *l; - GdlDataView *view = GDL_DATA_VIEW (container); - - for (l = view->priv->widgets; l != NULL; l = l->next) { - ChildWidget *child = l->data; - if (child->widget == widget) { - gtk_widget_unparent (widget); - view->priv->widgets = - g_list_remove_link (view->priv->widgets, l); - g_list_free_1 (l); - g_free (child); - return; - } - } -} - -static void -gdl_data_view_destroy (GtkObject *obj) -{ - GdlDataView *dv = GDL_DATA_VIEW (obj); - - stop_editing (dv); - - if (dv->priv) { - GList *l; - for (l = dv->priv->frames; l != NULL; l = l->next) { - g_object_unref (G_OBJECT (l->data)); - } - g_list_free (dv->priv->frames); - - g_object_unref (dv->priv->close_pixbuf); - g_object_unref (dv->priv->expand_pixbuf); - g_object_unref (dv->priv->contract_pixbuf); - - g_free (dv->priv); - dv->priv = NULL; - } - GDL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (obj)); -} - -static void -gdl_data_view_class_init (GdlDataViewClass *klass) -{ - GtkObjectClass *object_class = (GtkObjectClass *)klass; - GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - GtkContainerClass *container_class = (GtkContainerClass *)klass; - - parent_class = gtk_type_class (GTK_TYPE_LAYOUT); - - container_class->forall = gdl_data_view_forall; - container_class->remove = gdl_data_view_remove; - - widget_class->expose_event = gdl_data_view_expose; - widget_class->realize = gdl_data_view_realize; - /* FIXME: unrealize */ - widget_class->size_request = gdl_data_view_size_request; - widget_class->size_allocate = gdl_data_view_size_allocate; - object_class->destroy = gdl_data_view_destroy; - - gtk_widget_class_install_style_property (widget_class, - g_param_spec_int ("expander-size", - _("Expander Size"), - _("Size of the expander arrow."), - 0, - G_MAXINT, - 10, - G_PARAM_READABLE)); -} - -GtkWidget * -gdl_data_view_new (void) -{ - GdlDataView *dv; - dv = g_object_new (gdl_data_view_get_type (), NULL); - return GTK_WIDGET (dv); -} - -void -gdl_data_view_set_model (GdlDataView *dv, GdlDataModel *model) -{ - GtkTreePath *path; - GdlDataIter iter; - gboolean iter_valid; - int x = 5; - - dv->model = model; - - path = gtk_tree_path_new_from_string ("0"); - - iter_valid = gdl_data_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - while (iter_valid) { - GdlDataFrame *frame; - GdlDataRow *row; - - path = gdl_data_model_get_path (model, &iter); - - row = gdl_data_row_new (dv, path); - frame = gdl_data_frame_new (dv, row); - gdl_data_frame_set_position (frame, x, 5); - - dv->priv->frames = g_list_append (dv->priv->frames, - frame); - dv->priv->rows = g_list_append (dv->priv->rows, row); - - gtk_tree_path_free (path); - - x += 150; - - iter_valid = gdl_data_model_iter_next (model, &iter); - } -} - -void -gdl_data_view_layout (GdlDataView *view) -{ - GList *l; - for (l = view->priv->frames; l != NULL; l = l->next) { - gdl_data_frame_layout (GDL_DATA_FRAME (l->data)); - } -} - -GdkPixbuf * -gdl_data_view_get_close_pixbuf (GdlDataView *view) -{ - return view->priv->close_pixbuf; -} - -void -gdl_data_view_set_close_pixbuf (GdlDataView *view, GdkPixbuf *pixbuf) -{ - if (view->priv->close_pixbuf) { - g_object_unref (view->priv->close_pixbuf); - } - - view->priv->close_pixbuf = g_object_ref (pixbuf); -} - -GdkPixbuf * -gdl_data_view_get_expand_pixbuf (GdlDataView *view) -{ - return view->priv->expand_pixbuf; -} - -void -gdl_data_view_set_expand_pixbuf (GdlDataView *view, GdkPixbuf *pixbuf) -{ - if (view->priv->expand_pixbuf) { - g_object_unref (view->priv->expand_pixbuf); - } - - view->priv->expand_pixbuf = g_object_ref (pixbuf); -} - -GdkPixbuf * -gdl_data_view_get_contract_pixbuf (GdlDataView *view) -{ - return view->priv->contract_pixbuf; -} - -void -gdl_data_view_set_contract_pixbuf (GdlDataView *view, GdkPixbuf *pixbuf) -{ - if (view->priv->contract_pixbuf) { - g_object_unref (view->priv->contract_pixbuf); - } - - view->priv->contract_pixbuf = g_object_ref (pixbuf); -} diff --git a/src/libgdl/gdl-data-view.h b/src/libgdl/gdl-data-view.h deleted file mode 100644 index 3a5db02f4..000000000 --- a/src/libgdl/gdl-data-view.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2001 Dave Camp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef GDL_DATA_VIEW_H -#define GDL_DATA_VIEW_H - -#include -#include - -G_BEGIN_DECLS - -#define GDL_TYPE_DATA_VIEW (gdl_data_view_get_type ()) -#define GDL_DATA_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DATA_VIEW, GdlDataView)) -#define GDL_DATA_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) -#define GDL_IS_DATA_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DATA_VIEW)) -#define GDL_IS_DATA_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DATA_VIEW)) -#define GDL_DATA_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDL_TYPE_DATA_VIEW, GdlDataViewClass)) - -typedef struct _GdlDataView GdlDataView; -typedef struct _GdlDataViewClass GdlDataViewClass; -typedef struct _GdlDataViewPrivate GdlDataViewPrivate; - -#define GDL_POINT_IN(x1,y1,r) ((x1) >= (r)->x && x1 < (r)->x + (r)->width && (y1) >= (r)->y && y1 < (r)->y + (r)->height) - -struct _GdlDataView { - GtkLayout layout; - - GdlDataModel *model; - - GdlDataViewPrivate *priv; -}; - -struct _GdlDataViewClass { - GtkLayoutClass parent_class; -}; - -GType gdl_data_view_get_type (void); -GtkWidget *gdl_data_view_new (void); -void gdl_data_view_set_model (GdlDataView *view, - GdlDataModel *model); -void gdl_data_view_layout (GdlDataView *view); -GdkPixbuf *gdl_data_view_get_close_pixbuf (GdlDataView *view); -void gdl_data_view_set_close_pixbuf (GdlDataView *view, - GdkPixbuf *pixbuf); -GdkPixbuf *gdl_data_view_get_expand_pixbuf (GdlDataView *view); -void gdl_data_view_set_expand_pixbuf (GdlDataView *view, - GdkPixbuf *pixbuf); -GdkPixbuf *gdl_data_view_get_contract_pixbuf (GdlDataView *view); -void gdl_data_view_set_contract_pixbuf (GdlDataView *view, - GdkPixbuf *pixbuf); - -#endif diff --git a/src/libgdl/gdl-icons.c b/src/libgdl/gdl-icons.c deleted file mode 100644 index 2af2a8a9a..000000000 --- a/src/libgdl/gdl-icons.c +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gdl-icons.c - * - * Copyright (C) 2000-2001 Dave Camp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Dave Camp, Jeroen Zwartepoorte - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-i18n.h" -#include "gdl-tools.h" -#include -#include -#include -#include "gdl-icons.h" - -enum { - PROP_BOGUS, - PROP_ICON_SIZE, -}; - -#define GDL_ICONS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDL_TYPE_ICONS, GdlIconsPrivate)) - -typedef struct _GdlIconsPrivate GdlIconsPrivate; - -struct _GdlIconsPrivate { - int icon_size; - - GtkIconTheme *icon_theme; - GHashTable *icons; -}; - -GDL_CLASS_BOILERPLATE (GdlIcons, gdl_icons, GObject, G_TYPE_OBJECT); - -static void -gdl_icons_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_ICON_SIZE: - g_value_set_int (value, priv->icon_size); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdl_icons_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_ICON_SIZE: - priv->icon_size = g_value_get_int (value); - g_hash_table_destroy (priv->icons); - priv->icons = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) gdk_pixbuf_unref); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -theme_changed_cb (GtkIconTheme *theme, - gpointer user_data) -{ - GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (user_data); - - g_hash_table_destroy (priv->icons); - priv->icons = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) gdk_pixbuf_unref); -} - -static void -gdl_icons_dispose (GObject *object) -{ - GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (object); - - if (priv->icon_theme) { - /* Don't do that - look a GTK+ docs */ - /* g_object_unref (priv->icon_theme); */ - priv->icon_theme = NULL; - } - - if (priv->icons) { - g_hash_table_destroy (priv->icons); - priv->icons = NULL; - } -} - -static void -gdl_icons_class_init (GdlIconsClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = gdl_icons_dispose; - object_class->get_property = gdl_icons_get_property; - object_class->set_property = gdl_icons_set_property; - - g_object_class_install_property (object_class, PROP_ICON_SIZE, - g_param_spec_int ("icon-size", - _("Icon size"), - _("Icon size"), - 12, 256, 24, - G_PARAM_READWRITE)); - - g_type_class_add_private (object_class, sizeof (GdlIconsPrivate)); -} - -static void -gdl_icons_instance_init (GdlIcons *icons) -{ - GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (icons); - - priv->icon_theme = gtk_icon_theme_get_default (); - /* gtk_icon_theme_get_default() does not ref the returned object */ - /* but API docs state the you should NOT ref it */ - /* g_object_ref (priv->icon_theme);*/ - g_signal_connect_object (G_OBJECT (priv->icon_theme), "changed", - G_CALLBACK (theme_changed_cb), icons, 0); - priv->icons = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) gdk_pixbuf_unref); -} - -GdlIcons * -gdl_icons_new (int icon_size) -{ - return GDL_ICONS (g_object_new (GDL_TYPE_ICONS, - "icon-size", icon_size, - NULL)); -} - -GdkPixbuf * -gdl_icons_get_folder_icon (GdlIcons *icons) -{ - g_return_val_if_fail (icons != NULL, NULL); - g_return_val_if_fail (GDL_IS_ICONS (icons), NULL); - - return gdl_icons_get_mime_icon (icons, "application/directory-normal"); -} - -GdkPixbuf * -gdl_icons_get_uri_icon (GdlIcons *icons, - const char *uri) -{ - GnomeVFSFileInfo *info; - GdkPixbuf *pixbuf; - - g_return_val_if_fail (icons != NULL, NULL); - g_return_val_if_fail (GDL_IS_ICONS (icons), NULL); - g_return_val_if_fail (uri != NULL, NULL); - - info = gnome_vfs_file_info_new (); - gnome_vfs_get_file_info (uri, info, - GNOME_VFS_FILE_INFO_FOLLOW_LINKS | - GNOME_VFS_FILE_INFO_GET_MIME_TYPE | - GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE); - if (info->mime_type) - pixbuf = gdl_icons_get_mime_icon (icons, info->mime_type); - else - pixbuf = gdl_icons_get_mime_icon (icons, "gnome-fs-regular"); - gnome_vfs_file_info_unref (info); - - return pixbuf; -} - -GdkPixbuf * -gdl_icons_get_mime_icon (GdlIcons *icons, - const char *mime_type) -{ - GdkPixbuf *pixbuf; - char *icon_name; - - g_return_val_if_fail (icons != NULL, NULL); - g_return_val_if_fail (GDL_IS_ICONS (icons), NULL); - g_return_val_if_fail (mime_type != NULL, NULL); - - GdlIconsPrivate *priv = GDL_ICONS_GET_PRIVATE (icons); - - pixbuf = g_hash_table_lookup (priv->icons, mime_type); - if (pixbuf != NULL) { - g_object_ref (G_OBJECT (pixbuf)); - return pixbuf; - } - - if (!strcmp (mime_type, "application/directory-normal")) { - icon_name = g_strdup ("gnome-fs-directory"); - } else { - icon_name = gnome_icon_lookup (priv->icon_theme, - NULL, - NULL, - NULL, - NULL, - mime_type, - GNOME_ICON_LOOKUP_FLAGS_NONE, - NULL); - } - - if (!icon_name) { - /* Return regular icon if one doesn't exist for mime type. */ - if (!strcmp (mime_type, "gnome-fs-regular")) - return NULL; - else - return gdl_icons_get_mime_icon (icons, "gnome-fs-regular"); - } else { - if (!gtk_icon_theme_has_icon (priv->icon_theme, icon_name)) { - g_free (icon_name); - if (!strcmp (mime_type, "gnome-fs-regular")) - return NULL; - else - return gdl_icons_get_mime_icon (icons, "gnome-fs-regular"); - } else { - pixbuf = gtk_icon_theme_load_icon (priv->icon_theme, - icon_name, - priv->icon_size, - 0, /* lookup flags */ - NULL); - g_free (icon_name); - - if (pixbuf == NULL) { - if (!strcmp (mime_type, "gnome-fs-regular")) - return NULL; - else - return gdl_icons_get_mime_icon (icons, - "gnome-fs-regular"); - } - } - } - - g_hash_table_insert (priv->icons, g_strdup (mime_type), pixbuf); - g_object_ref (pixbuf); - - return pixbuf; -} diff --git a/src/libgdl/gdl-icons.h b/src/libgdl/gdl-icons.h deleted file mode 100644 index 79f3bba85..000000000 --- a/src/libgdl/gdl-icons.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gdl-icons.h - * - * Copyright (C) 2000-2001 JP Rosevear - * 2000 Dave Camp - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: JP Rosevear, Dave Camp, Jeroen Zwartepoorte - */ - -#ifndef _GDL_ICONS_H_ -#define _GDL_ICONS_H_ - -#include -#include - -G_BEGIN_DECLS - -#define GDL_TYPE_ICONS (gdl_icons_get_type ()) -#define GDL_ICONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_ICONS, GdlIcons)) -#define GDL_ICONS_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_ICONS, GdlIconsClass)) -#define GDL_IS_ICONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_ICONS)) -#define GDL_IS_ICONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GDL_TYPE_ICONS)) - -typedef struct _GdlIcons GdlIcons; -typedef struct _GdlIconsClass GdlIconsClass; - -struct _GdlIcons { - GObject parent; -}; - -struct _GdlIconsClass { - GObjectClass parent_class; -}; - -GType gdl_icons_get_type (void); -GdlIcons *gdl_icons_new (int icon_size); - -GdkPixbuf *gdl_icons_get_folder_icon (GdlIcons *icons); -GdkPixbuf *gdl_icons_get_uri_icon (GdlIcons *icons, - const char *uri); -GdkPixbuf *gdl_icons_get_mime_icon (GdlIcons *icons, - const char *mime_type); - -G_END_DECLS - -#endif /* _GDL_ICONS_H_ */ diff --git a/src/libgdl/test-dataview.c b/src/libgdl/test-dataview.c deleted file mode 100644 index bc89cbd4f..000000000 --- a/src/libgdl/test-dataview.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "gdl-data-view.h" -#include "gdl-data-model-test.h" - -int -main (int argc, char *argv[]) -{ - GtkWidget *win; - GtkWidget *view; - GdlDataModel *model; - GtkWidget *vbox; - - gtk_init (&argc, &argv); - - win = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (win), 500, 200); - - vbox = gtk_vbox_new (FALSE, 5); - - view = gdl_data_view_new (); - - gtk_layout_set_hadjustment (GTK_LAYOUT (view), NULL); - gtk_layout_set_vadjustment (GTK_LAYOUT (view), NULL); - - - model = GDL_DATA_MODEL (gdl_data_model_test_new ()); - gdl_data_view_set_model (GDL_DATA_VIEW (view), - model); - - gtk_box_pack_start (GTK_BOX (vbox), view, TRUE, TRUE, 0); - - gtk_container_add (GTK_CONTAINER (win), vbox); - - gtk_widget_show_all (win); - gtk_widget_grab_focus (GTK_WIDGET (view)); - - gtk_main (); - - return 0; -} -- cgit v1.2.3 From 3fb6de18c5d4b6a5f4fb08dfdb94cb39e8cd3844 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 9 Jul 2011 20:07:46 +0100 Subject: Merge upstream GDL 2.26.0 changes (bzr r10435) --- src/libgdl/gdl-combo-button.h | 4 +- src/libgdl/gdl-dock-bar.h | 1 - src/libgdl/gdl-dock-item-grip.c | 99 ++++++++------- src/libgdl/gdl-dock-item.c | 261 ++++++++++++++++++++++++++++++++++------ src/libgdl/gdl-dock.c | 2 + src/libgdl/gdl-stock.c | 2 +- src/libgdl/gdl-switcher.c | 2 +- 7 files changed, 283 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/libgdl/gdl-combo-button.h b/src/libgdl/gdl-combo-button.h index 6e80af0b6..2f9c3ca2c 100644 --- a/src/libgdl/gdl-combo-button.h +++ b/src/libgdl/gdl-combo-button.h @@ -21,9 +21,7 @@ #ifndef _GDL_COMBO_BUTTON_H_ #define _GDL_COMBO_BUTTON_H_ -#include -#include -#include +#include G_BEGIN_DECLS diff --git a/src/libgdl/gdl-dock-bar.h b/src/libgdl/gdl-dock-bar.h index 798dded20..ca6da1d26 100644 --- a/src/libgdl/gdl-dock-bar.h +++ b/src/libgdl/gdl-dock-bar.h @@ -23,7 +23,6 @@ #define __GDL_DOCK_BAR_H__ #include -#include "libgdl/gdl-dock.h" G_BEGIN_DECLS diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 91b88e782..7f7d17ab2 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -42,7 +42,7 @@ struct _GdlDockItemGripPrivate { }; GDL_CLASS_BOILERPLATE (GdlDockItemGrip, gdl_dock_item_grip, - GtkContainer, GTK_TYPE_CONTAINER); + GtkContainer, GTK_TYPE_CONTAINER); /* must be called after size_allocate */ static void @@ -122,7 +122,7 @@ ensure_title_and_icon_pixbuf (GdlDockItemGrip *grip) static gint gdl_dock_item_grip_expose (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { GdlDockItemGrip *grip; GdkRectangle title_area; @@ -172,7 +172,7 @@ gdl_dock_item_grip_expose (GtkWidget *widget, 0, 0, pixbuf_rect.x, pixbuf_rect.y, pixbuf_rect.width, pixbuf_rect.height, GDK_RGB_DITHER_NONE, 0, 0); - } + } } if (gdk_rectangle_intersect (&title_area, &event->area, &expose_area)) { @@ -221,15 +221,15 @@ gdl_dock_item_grip_item_notify (GObject *master, g_free (grip->_priv->title); grip->_priv->title = NULL; ensure_title_and_icon_pixbuf (grip); - gtk_widget_queue_draw (GTK_WIDGET (grip)); + gtk_widget_queue_draw (GTK_WIDGET (grip)); } else if (strcmp (pspec->name, "behavior") == 0) { - cursor = FALSE; + cursor = FALSE; if (grip->_priv->close_button) { if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item)) { gtk_widget_hide (GTK_WIDGET (grip->_priv->close_button)); } else { gtk_widget_show (GTK_WIDGET (grip->_priv->close_button)); - cursor = TRUE; + cursor = TRUE; } } if (grip->_priv->iconify_button) { @@ -237,10 +237,10 @@ gdl_dock_item_grip_item_notify (GObject *master, gtk_widget_hide (GTK_WIDGET (grip->_priv->iconify_button)); } else { gtk_widget_show (GTK_WIDGET (grip->_priv->iconify_button)); - cursor = TRUE; + cursor = TRUE; } } - if (grip->title_window && !cursor) + if (grip->title_window && !cursor) gdk_window_set_cursor (grip->title_window, NULL); } @@ -301,9 +301,9 @@ gdl_dock_item_grip_set_property (GObject *object, g_signal_connect (grip->item, "notify::stock-id", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); - g_signal_connect (grip->item, "notify::behavior", - G_CALLBACK (gdl_dock_item_grip_item_notify), - grip); + g_signal_connect (grip->item, "notify::behavior", + G_CALLBACK (gdl_dock_item_grip_item_notify), + grip); if (!GDL_DOCK_ITEM_CANT_CLOSE (grip->item) && grip->_priv->close_button) gtk_widget_show (grip->_priv->close_button); @@ -353,6 +353,7 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) grip->_priv->icon_pixbuf = NULL; grip->_priv->title_layout = NULL; + /* create the close button */ gtk_widget_push_composite_child (); grip->_priv->close_button = gtk_button_new (); gtk_widget_pop_composite_child (); @@ -369,6 +370,7 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) g_signal_connect (G_OBJECT (grip->_priv->close_button), "clicked", G_CALLBACK (gdl_dock_item_grip_close_clicked), grip); + /* create the iconify button */ gtk_widget_push_composite_child (); grip->_priv->iconify_button = gtk_button_new (); gtk_widget_pop_composite_child (); @@ -385,6 +387,7 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) g_signal_connect (G_OBJECT (grip->_priv->iconify_button), "clicked", G_CALLBACK (gdl_dock_item_grip_iconify_clicked), grip); + /* set tooltips on the buttons */ gtk_widget_set_tooltip_text (grip->_priv->iconify_button, _("Iconify this dock")); gtk_widget_set_tooltip_text (grip->_priv->close_button, @@ -426,15 +429,14 @@ gdl_dock_item_grip_realize (GtkWidget *widget) gdk_window_set_user_data (grip->title_window, widget); - if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item)) - cursor = NULL; - else if (GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) - cursor = NULL; - else - cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item) && + GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) + cursor = NULL; + else + cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_HAND2); gdk_window_set_cursor (grip->title_window, cursor); - if (cursor) + if (cursor) gdk_cursor_unref (cursor); } } @@ -497,15 +499,17 @@ gdl_dock_item_grip_size_request (GtkWidget *widget, pango_layout_get_pixel_size (grip->_priv->title_layout, NULL, &layout_height); gtk_widget_size_request (grip->_priv->close_button, &child_requisition); - - requisition->width += child_requisition.width; layout_height = MAX (layout_height, child_requisition.height); + if (GTK_WIDGET_VISIBLE (grip->_priv->close_button)) { + requisition->width += child_requisition.width; + } gtk_widget_size_request (grip->_priv->iconify_button, &child_requisition); - - requisition->width += child_requisition.width; layout_height = MAX (layout_height, child_requisition.height); - + if (GTK_WIDGET_VISIBLE (grip->_priv->iconify_button)) { + requisition->width += child_requisition.width; + } + requisition->height += layout_height; if (grip->_priv->icon_pixbuf) { @@ -579,33 +583,35 @@ gdl_dock_item_grip_size_allocate (GtkWidget *widget, child_allocation.x = allocation->x + allocation->width - container->border_width; child_allocation.y = allocation->y + container->border_width; - gtk_widget_size_request (grip->_priv->close_button, &button_requisition); - - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) - child_allocation.x -= button_requisition.width; + if (GTK_WIDGET_VISIBLE (grip->_priv->close_button)) { + gtk_widget_size_request (grip->_priv->close_button, &button_requisition); - child_allocation.width = button_requisition.width; - child_allocation.height = button_requisition.height; - - gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x += button_requisition.width; + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) + child_allocation.x -= button_requisition.width; + child_allocation.width = button_requisition.width; + child_allocation.height = button_requisition.height; + + gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); - gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition); + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + child_allocation.x += button_requisition.width; + } - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) - child_allocation.x -= button_requisition.width; + if (GTK_WIDGET_VISIBLE (grip->_priv->iconify_button)) { + gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition); - child_allocation.width = button_requisition.width; - child_allocation.height = button_requisition.height; + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) + child_allocation.x -= button_requisition.width; - gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); + child_allocation.width = button_requisition.width; + child_allocation.height = button_requisition.height; - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x += button_requisition.width; + gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + child_allocation.x += button_requisition.width; + } if (grip->title_window) { GdkRectangle area; @@ -712,6 +718,15 @@ gdl_dock_item_grip_class_init (GdlDockItemGripClass *klass) gdl_stock_init (); } +/* ----- Public interface ----- */ + +/** + * gdl_dock_item_grip_new: + * @item: The dock item that will "own" this grip widget. + * + * Creates a new GDL dock item grip object. + * Returns: The newly created dock item grip widget. + **/ GtkWidget * gdl_dock_item_grip_new (GdlDockItem *item) { diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index d2c36b18a..86f729c61 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -281,6 +281,16 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) /* properties */ + /** + * GdlDockItem:orientation: + * + * The orientation of the docking item. If the orientation is set to + * #GTK_ORIENTATION_VERTICAL, the grip widget will be shown along + * the top of the edge of item (if it is not hidden). If the + * orientation is set to #GTK_ORIENTATION_HORIZONTAL, the grip + * widget will be shown down the left edge of the item (even if the + * widget text direction is set to RTL). + */ g_object_class_install_property ( g_object_class, PROP_ORIENTATION, g_param_spec_enum ("orientation", _("Orientation"), @@ -339,6 +349,12 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) /* signals */ + /** + * GdlDockItem::dock-drag-begin: + * @item: The dock item which is being dragged. + * + * Signals that the dock item has begun to be dragged. + **/ gdl_dock_item_signals [DOCK_DRAG_BEGIN] = g_signal_new ("dock-drag-begin", G_TYPE_FROM_CLASS (klass), @@ -349,7 +365,15 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) gdl_marshal_VOID__VOID, G_TYPE_NONE, 0); - + + /** + * GdlDockItem::dock-drag-motion: + * @item: The dock item which is being dragged. + * @x: The x-position that the dock item has been dragged to. + * @y: The y-position that the dock item has been dragged to. + * + * Signals that a dock item dragging motion event has occured. + **/ gdl_dock_item_signals [DOCK_DRAG_MOTION] = g_signal_new ("dock-drag-motion", G_TYPE_FROM_CLASS (klass), @@ -363,6 +387,14 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) G_TYPE_INT, G_TYPE_INT); + /** + * GdlDockItem::dock-drag-end: + * @item: The dock item which is no longer being dragged. + * @cancel: This value is set to TRUE if the drag was cancelled by + * the user. #cancel is set to FALSE if the drag was accepted. + * + * Signals that the dock item dragging has ended. + **/ gdl_dock_item_signals [DOCK_DRAG_END] = g_signal_new ("dock_drag_end", G_TYPE_FROM_CLASS (klass), @@ -1401,60 +1433,64 @@ gdl_dock_item_dock (GdlDockObject *object, if (parent) gdl_dock_object_freeze (parent); - /* ref ourselves since we could be destroyed when detached */ + if (new_parent) { + /* ref ourselves since we could be destroyed when detached */ g_object_ref (object); GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_REFLOW); gdl_dock_object_detach (object, FALSE); - } - /* freeze the new parent, so reduce won't get called before it's - actually added to our parent */ - gdl_dock_object_freeze (new_parent); + /* freeze the new parent, so reduce won't get called before it's + actually added to our parent */ + gdl_dock_object_freeze (new_parent); - /* bind the new parent to our master, so the following adds work */ - gdl_dock_object_bind (new_parent, G_OBJECT (GDL_DOCK_OBJECT_GET_MASTER (object))); + /* bind the new parent to our master, so the following adds work */ + gdl_dock_object_bind (new_parent, G_OBJECT (GDL_DOCK_OBJECT_GET_MASTER (object))); - /* add the objects */ - if (add_ourselves_first) { - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); - splitpos = available_space - pref_size; - } else { - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); - splitpos = pref_size; - } + /* add the objects */ + if (add_ourselves_first) { + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); + splitpos = available_space - pref_size; + } else { + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); + splitpos = pref_size; + } - /* add the new parent to the parent */ - if (parent) - gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (new_parent)); + /* add the new parent to the parent */ + if (parent) + gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (new_parent)); - /* show automatic object */ - if (gtk_widget_get_visible (GTK_WIDGET (object))) - { - gtk_widget_show (GTK_WIDGET (new_parent)); - GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_IN_REFLOW); + /* show automatic object */ + if (gtk_widget_get_visible (GTK_WIDGET (object))) + { + gtk_widget_show (GTK_WIDGET (new_parent)); + GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_IN_REFLOW); + } gdl_dock_object_thaw (new_parent); + + /* use extra docking parameter */ + if (position != GDL_DOCK_CENTER && other_data && + G_VALUE_HOLDS (other_data, G_TYPE_UINT)) { + + g_object_set (G_OBJECT (new_parent), + "position", g_value_get_uint (other_data), + NULL); + } else if (splitpos > 0 && splitpos < available_space) { + g_object_set (G_OBJECT (new_parent), "position", splitpos, NULL); + } + + g_object_unref (object); } - else // If the parent is already a DockNotebook, we don't need - // to create a new one. + else + { + /* If the parent is already a DockNotebook, we don't need + to create a new one. */ gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (requestor)); - - /* use extra docking parameter */ - if (position != GDL_DOCK_CENTER && other_data && - G_VALUE_HOLDS (other_data, G_TYPE_UINT)) { - - g_object_set (G_OBJECT (new_parent), - "position", g_value_get_uint (other_data), - NULL); - } else if (splitpos > 0 && splitpos < available_space) { - g_object_set (G_OBJECT (new_parent), "position", splitpos, NULL); } - g_object_unref (object); - requestor_parent = gdl_dock_object_get_parent_object (requestor); if (GDL_IS_DOCK_NOTEBOOK (requestor_parent)) { @@ -1665,6 +1701,17 @@ gdl_dock_item_real_set_orientation (GdlDockItem *item, /* ----- Public interface ----- */ +/** + * gdl_dock_item_new: + * @name: Unique name for identifying the dock object. + * @long_name: Human readable name for the dock object. + * @behavior: General behavior for the dock item (i.e. whether it can + * float, if it's locked, etc.), as specified by + * #GdlDockItemBehavior flags. + * + * Creates a new dock item widget. + * Returns: The newly created dock item grip widget. + **/ GtkWidget * gdl_dock_item_new (const gchar *name, const gchar *long_name, @@ -1682,6 +1729,18 @@ gdl_dock_item_new (const gchar *name, return GTK_WIDGET (item); } +/** + * gdl_dock_item_new_with_stock: + * @name: Unique name for identifying the dock object. + * @long_name: Human readable name for the dock object. + * @stock_id: Stock icon for the dock object. + * @behavior: General behavior for the dock item (i.e. whether it can + * float, if it's locked, etc.), as specified by + * #GdlDockItemBehavior flags. + * + * Creates a new dock item grip widget with a given stock id. + * Returns: The newly created dock item grip widget. + **/ GtkWidget * gdl_dock_item_new_with_stock (const gchar *name, const gchar *long_name, @@ -1724,6 +1783,15 @@ gdl_dock_item_new_with_pixbuf_icon (const gchar *name, } /* convenient function (and to preserve source compat) */ +/** + * gdl_dock_item_dock_to: + * @item: The dock item that will be relocated to the dock position. + * @target: The dock item that will be used as the point of reference. + * @position: The position to dock #item, relative to #target. + * @docking_param: This value is unused, and will be ignored. + * + * Relocates a dock item to a new location relative to another dock item. + **/ void gdl_dock_item_dock_to (GdlDockItem *item, GdlDockItem *target, @@ -1761,6 +1829,18 @@ gdl_dock_item_dock_to (GdlDockItem *item, position, NULL); } +/** + * gdl_dock_item_set_orientation: + * @item: The dock item which will get it's orientation set. + * @orientation: The orientation to set the item to. If the orientation + * is set to #GTK_ORIENTATION_VERTICAL, the grip widget will be shown + * along the top of the edge of item (if it is not hidden). If the + * orientation is set to #GTK_ORIENTATION_HORIZONTAL, the grip widget + * will be shown down the left edge of the item (even if the widget + * text direction is set to RTL). + * + * This function sets the layout of the dock item. + **/ void gdl_dock_item_set_orientation (GdlDockItem *item, GtkOrientation orientation) @@ -1785,6 +1865,16 @@ gdl_dock_item_set_orientation (GdlDockItem *item, } } +/** + * gdl_dock_item_get_tablabel: + * @item: The dock item from which to get the tab label widget. + * + * Gets the current tab label widget. Note that this label widget is + * only visible when the "switcher-style" property of the #GdlDockMaster + * is set to #GDL_SWITCHER_STYLE_TABS + * + * Returns: Returns the tab label widget. + **/ GtkWidget * gdl_dock_item_get_tablabel (GdlDockItem *item) { @@ -1794,6 +1884,15 @@ gdl_dock_item_get_tablabel (GdlDockItem *item) return item->_priv->tab_label; } +/** + * gdl_dock_item_set_tablabel: + * @item: The dock item which will get it's tab label widget set. + * @tablabel: The widget that will become the tab label. + * + * Replaces the current tab label widget with another widget. Note that + * this label widget is only visible when the "switcher-style" property + * of the #GdlDockMaster is set to #GDL_SWITCHER_STYLE_TABS + **/ void gdl_dock_item_set_tablabel (GdlDockItem *item, GtkWidget *tablabel) @@ -1825,6 +1924,12 @@ gdl_dock_item_set_tablabel (GdlDockItem *item, } } +/** + * gdl_dock_item_hide_grip: + * @item: The dock item to hide the grip of. + * + * This function hides the dock item's grip widget. + **/ void gdl_dock_item_hide_grip (GdlDockItem *item) { @@ -1836,6 +1941,12 @@ gdl_dock_item_hide_grip (GdlDockItem *item) g_warning ("Grips always show unless GDL_DOCK_ITEM_BEH_NO_GRIP is set\n" ); } +/** + * gdl_dock_item_show_grip: + * @item: The dock item to show the grip of. + * + * This function shows the dock item's grip widget. + **/ void gdl_dock_item_show_grip (GdlDockItem *item) { @@ -1847,6 +1958,14 @@ gdl_dock_item_show_grip (GdlDockItem *item) } /* convenient function (and to preserve source compat) */ +/** + * gdl_dock_item_bind: + * @item: The item to bind. + * @dock: The #GdlDock widget to bind it to. Note that this widget must + * be a type of #GdlDock. + * + * Binds this dock item to a new dock master. + **/ void gdl_dock_item_bind (GdlDockItem *item, GtkWidget *dock) @@ -1859,6 +1978,12 @@ gdl_dock_item_bind (GdlDockItem *item, } /* convenient function (and to preserve source compat) */ +/** + * gdl_dock_item_unbind: + * @item: The item to unbind. + * + * Unbinds this dock item from it's dock master. + **/ void gdl_dock_item_unbind (GdlDockItem *item) { @@ -1867,6 +1992,15 @@ gdl_dock_item_unbind (GdlDockItem *item) gdl_dock_object_unbind (GDL_DOCK_OBJECT (item)); } +/** + * gdl_dock_item_hide_item: + * @item: The dock item to hide. + * + * This function hides the dock item. When dock items are hidden they + * are completely removed from the layout. + * + * The dock item close button causes the panel to be hidden. + **/ void gdl_dock_item_hide_item (GdlDockItem *item) { @@ -1928,6 +2062,15 @@ gdl_dock_item_hide_item (GdlDockItem *item) gdl_dock_object_thaw (GDL_DOCK_OBJECT (item)); } +/** + * gdl_dock_item_iconify_item: + * @item: The dock item to iconify. + * + * This function iconifies the dock item. When dock items are iconified + * they are hidden, and appear only as icons in dock bars. + * + * The dock item iconify button causes the panel to be iconified. + **/ void gdl_dock_item_iconify_item (GdlDockItem *item) { @@ -1937,6 +2080,13 @@ gdl_dock_item_iconify_item (GdlDockItem *item) gdl_dock_item_hide_item (item); } +/** + * gdl_dock_item_show_item: + * @item: The dock item to show. + * + * This function shows the dock item. When dock items are shown, they + * are displayed in their normal layout position. + **/ void gdl_dock_item_show_item (GdlDockItem *item) { @@ -1988,18 +2138,41 @@ gdl_dock_item_show_item (GdlDockItem *item) gtk_widget_show (GTK_WIDGET (item)); } +/** + * gdl_dock_item_lock: + * @item: The dock item to lock. + * + * This function locks the dock item. When locked the dock item cannot + * be dragged around and it doesn't show a grip. + **/ void gdl_dock_item_lock (GdlDockItem *item) { g_object_set (item, "locked", TRUE, NULL); } +/** + * gdl_dock_item_unlock: + * @item: The dock item to unlock. + * + * This function unlocks the dock item. When unlocked the dock item can + * be dragged around and can show a grip. + **/ void gdl_dock_item_unlock (GdlDockItem *item) { g_object_set (item, "locked", FALSE, NULL); } +/** + * gdl_dock_item_set_default_position: + * @item: The dock item + * @reference: The GdlDockObject which is the default dock for @item + * + * This method has only an effect when you add you dock_item with + * GDL_DOCK_ITEM_BEH_NEVER_FLOATING. In this case you have to assign + * it a default position. + **/ void gdl_dock_item_set_default_position (GdlDockItem *item, GdlDockObject *reference) @@ -2026,6 +2199,14 @@ gdl_dock_item_set_default_position (GdlDockItem *item, } } +/** + * gdl_dock_item_preferred_size: + * @item: The dock item to get the preferred size of. + * @req: A pointer to a #GtkRequisition into which the preferred size + * will be written. + * + * Gets the preferred size of the dock item in pixels. + **/ void gdl_dock_item_preferred_size (GdlDockItem *item, GtkRequisition *req) diff --git a/src/libgdl/gdl-dock.c b/src/libgdl/gdl-dock.c index d80a47a1f..3b0dc4e6b 100644 --- a/src/libgdl/gdl-dock.c +++ b/src/libgdl/gdl-dock.c @@ -1139,6 +1139,8 @@ gdl_dock_select_larger_item (GdlDockItem *dock_item_1, return ((size_1.width * size_1.height) >= (size_2.width * size_2.height)? dock_item_1 : dock_item_2); + } else if (placement == GDL_DOCK_NONE) { + return dock_item_1; } else { g_warning ("Should not reach here: %s:%d", __FUNCTION__, __LINE__); } diff --git a/src/libgdl/gdl-stock.c b/src/libgdl/gdl-stock.c index dc86e523b..4cb7bf929 100644 --- a/src/libgdl/gdl-stock.c +++ b/src/libgdl/gdl-stock.c @@ -59,7 +59,7 @@ icon_set_from_data (GtkIconSet *set, pixbuf = gdk_pixbuf_new_from_inline (data_size, icon_data, FALSE, &err); if (err) { - g_warning ("%s",err->message); + g_warning ("%s", err->message); g_error_free (err); err = NULL; g_object_unref (source); diff --git a/src/libgdl/gdl-switcher.c b/src/libgdl/gdl-switcher.c index c67b4464b..fea3218ae 100644 --- a/src/libgdl/gdl-switcher.c +++ b/src/libgdl/gdl-switcher.c @@ -216,7 +216,7 @@ button_toggled_callback (GtkToggleButton *toggle_button, static int layout_buttons (GdlSwitcher *switcher) { - GtkRequisition client_requisition; + GtkRequisition client_requisition = {0,}; GtkAllocation *allocation = & GTK_WIDGET (switcher)->allocation; GdlSwitcherStyle switcher_style; gboolean icons_only; -- cgit v1.2.3 From 55fd3861b1b1cc012225ce351bc7f4bfa891e740 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 10 Jul 2011 01:56:02 +0100 Subject: Merge upstream GDL: GNOME_2_30_0 (bzr r10436) --- src/libgdl/Makefile_insert | 4 +- src/libgdl/gdl-combo-button.c | 383 --------------------- src/libgdl/gdl-combo-button.h | 63 ---- src/libgdl/gdl-dock-item-button-image.c | 169 +++++++++ src/libgdl/gdl-dock-item-button-image.h | 70 ++++ src/libgdl/gdl-dock-item-grip.c | 584 +++++++++++++++++--------------- src/libgdl/gdl-dock-item-grip.h | 33 +- src/libgdl/gdl-dock-item.c | 47 +++ src/libgdl/gdl-dock-item.h | 19 +- src/libgdl/gdl-dock-layout.c | 208 +++++++----- src/libgdl/gdl-dock-master.c | 2 + src/libgdl/gdl-dock-master.h | 9 + src/libgdl/gdl-dock-notebook.c | 6 +- src/libgdl/gdl-dock-object.h | 2 +- src/libgdl/gdl-dock-paned.c | 1 + src/libgdl/gdl-dock-placeholder.c | 5 +- src/libgdl/gdl-dock-placeholder.h | 2 +- src/libgdl/gdl-dock.c | 15 - src/libgdl/gdl-stock.c | 126 ------- src/libgdl/gdl-stock.h | 37 -- src/libgdl/gdl-switcher.c | 206 +++-------- src/libgdl/gdl-switcher.h | 24 +- src/libgdl/gdl.h | 33 +- src/libgdl/test-dock.c | 3 + 24 files changed, 861 insertions(+), 1190 deletions(-) delete mode 100644 src/libgdl/gdl-combo-button.c delete mode 100644 src/libgdl/gdl-combo-button.h create mode 100644 src/libgdl/gdl-dock-item-button-image.c create mode 100644 src/libgdl/gdl-dock-item-button-image.h delete mode 100644 src/libgdl/gdl-stock.c delete mode 100644 src/libgdl/gdl-stock.h (limited to 'src') diff --git a/src/libgdl/Makefile_insert b/src/libgdl/Makefile_insert index 2276aa801..e151fd5d6 100644 --- a/src/libgdl/Makefile_insert +++ b/src/libgdl/Makefile_insert @@ -16,7 +16,6 @@ libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-tablabel.h \ libgdl/gdl-dock-placeholder.h \ libgdl/gdl-dock-bar.h \ - libgdl/gdl-stock.h \ libgdl/gdl-stock-icons.h \ libgdl/gdl-i18n.h \ libgdl/gdl-i18n.c \ @@ -24,6 +23,8 @@ libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-master.c \ libgdl/gdl-dock.c \ libgdl/gdl-dock-item.c \ + libgdl/gdl-dock-item-button-image.c \ + libgdl/gdl-dock-item-button-image.h \ libgdl/gdl-dock-item-grip.h \ libgdl/gdl-dock-item-grip.c \ libgdl/gdl-dock-notebook.c \ @@ -31,7 +32,6 @@ libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-tablabel.c \ libgdl/gdl-dock-placeholder.c \ libgdl/gdl-dock-bar.c \ - libgdl/gdl-stock.c \ libgdl/gdl-switcher.h \ libgdl/gdl-switcher.c \ libgdl/gdl-win32.h \ diff --git a/src/libgdl/gdl-combo-button.c b/src/libgdl/gdl-combo-button.c deleted file mode 100644 index 6414a8110..000000000 --- a/src/libgdl/gdl-combo-button.c +++ /dev/null @@ -1,383 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * gdl-combo-button.c - * - * Copyright (C) 2003 Jeroen Zwartepoorte - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "gdl-tools.h" -#include "gdl-combo-button.h" - -struct _GdlComboButtonPrivate { - GtkWidget *default_button; - GtkWidget *image; - GtkWidget *label; - GtkWidget *menu_button; - GtkWidget *menu; - gboolean menu_popped_up; -}; - -GDL_CLASS_BOILERPLATE (GdlComboButton, gdl_combo_button, GtkHBox, GTK_TYPE_HBOX); - -static void -default_button_clicked_cb (GtkButton *button, - gpointer user_data) -{ - GdlComboButton *combo; - GdlComboButtonPrivate *priv; - - combo = GDL_COMBO_BUTTON (user_data); - priv = combo->priv; - - if (!priv->menu_popped_up) - g_signal_emit_by_name (G_OBJECT (combo), - "activate-default", NULL); -} - -static gboolean -default_button_press_event_cb (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - - if (event->type == GDK_BUTTON_PRESS && event->button == 1) { - GTK_BUTTON (priv->menu_button)->button_down = TRUE; - gtk_button_pressed (GTK_BUTTON (priv->menu_button)); - } - - return FALSE; -} - -static gboolean -default_button_release_event_cb (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - - if (event->button == 1) { - gtk_button_released (GTK_BUTTON (priv->menu_button)); - } - - return FALSE; -} - -static gboolean -button_enter_notify_cb (GtkWidget *widget, - GdkEventCrossing *event, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - - if (event->detail != GDK_NOTIFY_INFERIOR) { - GTK_BUTTON (priv->default_button)->in_button = TRUE; - GTK_BUTTON (priv->menu_button)->in_button = TRUE; - gtk_button_enter (GTK_BUTTON (priv->default_button)); - gtk_button_enter (GTK_BUTTON (priv->menu_button)); - } - - return TRUE; -} - -static gboolean -button_leave_notify_cb (GtkWidget *widget, - GdkEventCrossing *event, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - - if (priv->menu_popped_up) - return TRUE; - - if (event->detail != GDK_NOTIFY_INFERIOR) { - GTK_BUTTON (priv->default_button)->in_button = FALSE; - GTK_BUTTON (priv->menu_button)->in_button = FALSE; - gtk_button_leave (GTK_BUTTON (priv->default_button)); - gtk_button_leave (GTK_BUTTON (priv->menu_button)); - } - - return TRUE; -} - -static void -menu_position_func (GtkMenu *menu, - gint *x_return, - gint *y_return, - gboolean *push_in, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - GtkAllocation *allocation; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - allocation = &(priv->default_button->allocation); - - gdk_window_get_origin (priv->default_button->window, x_return, y_return); - - *x_return += allocation->x; - *y_return += allocation->height; -} - -static gboolean -menu_button_press_event_cb (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - - if (event->type == GDK_BUTTON_PRESS && - (event->button == 1 || event->button == 3)) { - GTK_BUTTON (priv->menu_button)->button_down = TRUE; - - gtk_button_pressed (GTK_BUTTON (priv->menu_button)); - - priv->menu_popped_up = TRUE; - gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, - menu_position_func, combo_button, - event->button, event->time); - } - - return TRUE; -} - -static void -menu_deactivate_cb (GtkMenuShell *menu_shell, - gpointer user_data) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (user_data); - priv = combo_button->priv; - - priv->menu_popped_up = FALSE; - - GTK_BUTTON (priv->menu_button)->button_down = FALSE; - GTK_BUTTON (priv->menu_button)->in_button = FALSE; - GTK_BUTTON (priv->default_button)->in_button = FALSE; - gtk_button_leave (GTK_BUTTON (priv->menu_button)); - gtk_button_leave (GTK_BUTTON (priv->default_button)); - gtk_button_clicked (GTK_BUTTON (priv->menu_button)); -} - -static void -menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - GdlComboButton *combo_button; - - combo_button = GDL_COMBO_BUTTON (widget); - - g_signal_handlers_disconnect_by_func (G_OBJECT (menu), - menu_deactivate_cb, - combo_button); - combo_button->priv->menu = NULL; -} - -static void -gdl_combo_button_destroy (GtkObject *object) -{ - GdlComboButton *combo_button; - GdlComboButtonPrivate *priv; - - combo_button = GDL_COMBO_BUTTON (object); - priv = combo_button->priv; - - if (priv) { - g_free (priv); - combo_button->priv = NULL; - } - - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void -gdl_combo_button_class_init (GdlComboButtonClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = g_type_class_peek_parent (klass); - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - - object_class->destroy = gdl_combo_button_destroy; - - g_signal_new ("activate-default", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdlComboButtonClass, activate_default), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -gdl_combo_button_instance_init (GdlComboButton *combo_button) -{ - GdlComboButtonPrivate *priv; - GtkWidget *hbox, *align, *arrow; - - priv = g_new (GdlComboButtonPrivate, 1); - combo_button->priv = priv; - - priv->menu = NULL; - priv->menu_popped_up = FALSE; - - priv->default_button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (priv->default_button), GTK_RELIEF_NONE); - - /* Following code copied from gtk_button_construct_child. */ - priv->label = gtk_label_new (""); - gtk_label_set_use_underline (GTK_LABEL (priv->label), TRUE); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->label), - priv->default_button); - - priv->image = gtk_image_new (); - hbox = gtk_hbox_new (FALSE, 2); - - align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - - gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0); - gtk_box_pack_end (GTK_BOX (hbox), priv->label, FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (priv->default_button), align); - gtk_container_add (GTK_CONTAINER (align), hbox); - /* End copied block. */ - - gtk_box_pack_start (GTK_BOX (combo_button), priv->default_button, - FALSE, FALSE, 0); - gtk_widget_show_all (priv->default_button); - - priv->menu_button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (priv->menu_button), GTK_RELIEF_NONE); - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (priv->menu_button), arrow); - gtk_box_pack_start (GTK_BOX (combo_button), priv->menu_button, FALSE, - FALSE, 0); - gtk_widget_show_all (priv->menu_button); - - /* Default button. */ - g_signal_connect (G_OBJECT (priv->default_button), "clicked", - G_CALLBACK (default_button_clicked_cb), combo_button); - g_signal_connect (G_OBJECT (priv->default_button), "button_press_event", - G_CALLBACK (default_button_press_event_cb), combo_button); - g_signal_connect (G_OBJECT (priv->default_button), "button_release_event", - G_CALLBACK (default_button_release_event_cb), combo_button); - g_signal_connect (G_OBJECT (priv->default_button), "enter_notify_event", - G_CALLBACK (button_enter_notify_cb), combo_button); - g_signal_connect (G_OBJECT (priv->default_button), "leave_notify_event", - G_CALLBACK (button_leave_notify_cb), combo_button); - - /* Menu button. */ - g_signal_connect (G_OBJECT (priv->menu_button), "button_press_event", - G_CALLBACK (menu_button_press_event_cb), combo_button); - g_signal_connect (G_OBJECT (priv->menu_button), "enter_notify_event", - G_CALLBACK (button_enter_notify_cb), combo_button); - g_signal_connect (G_OBJECT (priv->menu_button), "leave_notify_event", - G_CALLBACK (button_leave_notify_cb), combo_button); -} - -GtkWidget * -gdl_combo_button_new (void) -{ - GtkWidget *combo_button; - - combo_button = GTK_WIDGET (g_object_new (GDL_TYPE_COMBO_BUTTON, NULL)); - - return combo_button; -} - -void -gdl_combo_button_set_icon (GdlComboButton *combo_button, - GdkPixbuf *pixbuf) -{ - GdlComboButtonPrivate *priv; - - g_return_if_fail (GDL_IS_COMBO_BUTTON (combo_button)); - g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); - - priv = combo_button->priv; - - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf); -} - -void -gdl_combo_button_set_label (GdlComboButton *combo_button, - const gchar *label) -{ - GdlComboButtonPrivate *priv; - - g_return_if_fail (GDL_IS_COMBO_BUTTON (combo_button)); - g_return_if_fail (label != NULL); - - priv = combo_button->priv; - - gtk_label_set_text (GTK_LABEL (priv->label), label); -} - -void -gdl_combo_button_set_menu (GdlComboButton *combo_button, - GtkMenu *menu) -{ - GdlComboButtonPrivate *priv; - - g_return_if_fail (GDL_IS_COMBO_BUTTON (combo_button)); - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = combo_button->priv; - - if (priv->menu != NULL) - gtk_menu_detach (GTK_MENU (priv->menu)); - - priv->menu = GTK_WIDGET (menu); - if (menu == NULL) - return; - - gtk_menu_attach_to_widget (menu, GTK_WIDGET (combo_button), menu_detacher); - - g_signal_connect (G_OBJECT (menu), "deactivate", - G_CALLBACK (menu_deactivate_cb), combo_button); -} diff --git a/src/libgdl/gdl-combo-button.h b/src/libgdl/gdl-combo-button.h deleted file mode 100644 index 2f9c3ca2c..000000000 --- a/src/libgdl/gdl-combo-button.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * gdl-combo-button.h - * - * Copyright (C) 2003 Jeroen Zwartepoorte - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _GDL_COMBO_BUTTON_H_ -#define _GDL_COMBO_BUTTON_H_ - -#include - -G_BEGIN_DECLS - -#define GDL_TYPE_COMBO_BUTTON (gdl_combo_button_get_type ()) -#define GDL_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_COMBO_BUTTON, GdlComboButton)) -#define GDL_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_COMBO_BUTTON, GdlComboButtonClass)) -#define GDL_IS_COMBO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_COMBO_BUTTON)) -#define GDL_IS_COMBO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GDL_TYPE_COMBO_BUTTON)) - -typedef struct _GdlComboButton GdlComboButton; -typedef struct _GdlComboButtonPrivate GdlComboButtonPrivate; -typedef struct _GdlComboButtonClass GdlComboButtonClass; - -struct _GdlComboButton { - GtkHBox parent; - - GdlComboButtonPrivate *priv; -}; - -struct _GdlComboButtonClass { - GtkHBoxClass parent_class; - - /* Signals. */ - void (* activate_default) (GdlComboButton *combo_button); -}; - -GType gdl_combo_button_get_type (void); -GtkWidget *gdl_combo_button_new (void); - -void gdl_combo_button_set_icon (GdlComboButton *combo_button, - GdkPixbuf *pixbuf); -void gdl_combo_button_set_label (GdlComboButton *combo_button, - const gchar *label); -void gdl_combo_button_set_menu (GdlComboButton *combo_button, - GtkMenu *menu); - -G_END_DECLS - -#endif /* _GDL_COMBO_BUTTON_H_ */ diff --git a/src/libgdl/gdl-dock-item-button-image.c b/src/libgdl/gdl-dock-item-button-image.c new file mode 100644 index 000000000..f115c652c --- /dev/null +++ b/src/libgdl/gdl-dock-item-button-image.c @@ -0,0 +1,169 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * gdl-dock-item-button-image.c + * + * Author: Joel Holdsworth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gdl-dock-item-button-image.h" + +#include +#include "gdl-tools.h" + +#define ICON_SIZE 12 + +GDL_CLASS_BOILERPLATE (GdlDockItemButtonImage, + gdl_dock_item_button_image, + GtkWidget, GTK_TYPE_WIDGET); + +static gint +gdl_dock_item_button_image_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GdlDockItemButtonImage *button_image; + GtkStyle *style; + GdkColor *color; + + g_return_val_if_fail (widget != NULL, 0); + button_image = GDL_DOCK_ITEM_BUTTON_IMAGE (widget); + + cairo_t *cr = gdk_cairo_create (event->window); + cairo_translate (cr, event->area.x, event->area.y); + + /* Set up the pen */ + cairo_set_line_width(cr, 1.0); + + style = gtk_widget_get_style (widget); + g_return_if_fail (style != NULL); + color = &style->fg[GTK_STATE_NORMAL]; + cairo_set_source_rgba(cr, color->red / 65535.0, + color->green / 65535.0, color->blue / 65535.0, 0.55); + + /* Draw the icon border */ + cairo_move_to (cr, 10.5, 2.5); + cairo_arc (cr, 10.5, 4.5, 2, -0.5 * M_PI, 0); + cairo_line_to (cr, 12.5, 10.5); + cairo_arc (cr, 10.5, 10.5, 2, 0, 0.5 * M_PI); + cairo_line_to (cr, 4.5, 12.5); + cairo_arc (cr, 4.5, 10.5, 2, 0.5 * M_PI, M_PI); + cairo_line_to (cr, 2.5, 4.5); + cairo_arc (cr, 4.5, 4.5, 2, M_PI, 1.5 * M_PI); + cairo_close_path (cr); + + cairo_stroke (cr); + + /* Draw the icon */ + cairo_new_path (cr); + + switch(button_image->image_type) { + case GDL_DOCK_ITEM_BUTTON_IMAGE_CLOSE: + cairo_move_to (cr, 4.0, 5.5); + cairo_line_to (cr, 4.0, 5.5); + cairo_line_to (cr, 6.0, 7.5); + cairo_line_to (cr, 4.0, 9.5); + cairo_line_to (cr, 5.5, 11.0); + cairo_line_to (cr, 7.5, 9.0); + cairo_line_to (cr, 9.5, 11.0); + cairo_line_to (cr, 11.0, 9.5); + cairo_line_to (cr, 9.0, 7.5); + cairo_line_to (cr, 11.0, 5.5); + cairo_line_to (cr, 9.5, 4.0); + cairo_line_to (cr, 7.5, 6.0); + cairo_line_to (cr, 5.5, 4.0); + cairo_close_path (cr); + break; + + case GDL_DOCK_ITEM_BUTTON_IMAGE_ICONIFY: + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { + cairo_move_to (cr, 4.5, 7.5); + cairo_line_to (cr, 10.0, 4.75); + cairo_line_to (cr, 10.0, 10.25); + cairo_close_path (cr); + } else { + cairo_move_to (cr, 10.5, 7.5); + cairo_line_to (cr, 5, 4.75); + cairo_line_to (cr, 5, 10.25); + cairo_close_path (cr); + } + break; + + default: + break; + } + + cairo_fill (cr); + + /* Finish up */ + cairo_destroy (cr); + + return 0; +} + +static void +gdl_dock_item_button_image_instance_init ( + GdlDockItemButtonImage *button_image) +{ + GTK_WIDGET_SET_FLAGS (button_image, GTK_NO_WINDOW); +} + +static void +gdl_dock_item_button_image_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + g_return_if_fail (GDL_IS_DOCK_ITEM_BUTTON_IMAGE (widget)); + g_return_if_fail (requisition != NULL); + + requisition->width = ICON_SIZE; + requisition->height = ICON_SIZE; +} + +static void +gdl_dock_item_button_image_class_init ( + GdlDockItemButtonImageClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + widget_class->expose_event = + gdl_dock_item_button_image_expose; + widget_class->size_request = + gdl_dock_item_button_image_size_request; +} + +/* ----- Public interface ----- */ + +/** + * gdl_dock_item_button_image_new: + * @param image_type: Specifies what type of image the widget should + * display + * + * Creates a new GDL dock button image object. + * Returns: The newly created dock item button image widget. + **/ +GtkWidget* +gdl_dock_item_button_image_new (GdlDockItemButtonImageType image_type) +{ + GdlDockItemButtonImage *button_image = g_object_new ( + GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, NULL); + button_image->image_type = image_type; + + return GTK_WIDGET (button_image); +} diff --git a/src/libgdl/gdl-dock-item-button-image.h b/src/libgdl/gdl-dock-item-button-image.h new file mode 100644 index 000000000..ce0c6faaf --- /dev/null +++ b/src/libgdl/gdl-dock-item-button-image.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * gdl-dock-item-button-image.h + * + * Author: Joel Holdsworth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GDL_DOCK_ITEM_BUTTON_IMAGE_H_ +#define _GDL_DOCK_ITEM_BUTTON_IMAGE_H_ + +#include + +G_BEGIN_DECLS + +/* Standard Macros */ +#define GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE \ + (gdl_dock_item_button_image_get_type()) +#define GDL_DOCK_ITEM_BUTTON_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, GdlDockItemButtonImage)) +#define GDL_DOCK_ITEM_BUTTON_IMAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, GdlDockItemButtonImageClass)) +#define GDL_IS_DOCK_ITEM_BUTTON_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE)) +#define GDL_IS_DOCK_ITEM_BUTTON_IMAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE)) +#define GDL_DOCK_ITEM_BUTTON_IMAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, GdlDockItemButtonImageClass)) + +/* Data Types & Structures */ +typedef enum { + GDL_DOCK_ITEM_BUTTON_IMAGE_CLOSE, + GDL_DOCK_ITEM_BUTTON_IMAGE_ICONIFY +} GdlDockItemButtonImageType; + +typedef struct _GdlDockItemButtonImage GdlDockItemButtonImage; +typedef struct _GdlDockItemButtonImageClass GdlDockItemButtonImageClass; + +struct _GdlDockItemButtonImage { + GtkWidget parent; + + GdlDockItemButtonImageType image_type; +}; + +struct _GdlDockItemButtonImageClass { + GtkWidgetClass parent_class; +}; + +/* Data Public Functions */ +GType gdl_dock_item_button_image_get_type (void); +GtkWidget *gdl_dock_item_button_image_new ( + GdlDockItemButtonImageType image_type); + +G_END_DECLS + +#endif /* _GDL_DOCK_ITEM_BUTTON_IMAGE_H_ */ diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 7f7d17ab2..c5eb6f370 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -1,13 +1,30 @@ /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/** +/* * gdl-dock-item-grip.c * - * Based on bonobo-dock-item-grip. Original copyright notice follows. + * Author: Michael Meeks Copyright (C) 2002 Sun Microsystems, Inc. + * + * Based on BonoboDockItemGrip. Original copyright notice follows. + * + * Copyright (C) 1998 Ettore Perazzoli + * Copyright (C) 1998 Elliot Lee + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * All rights reserved. * - * Author: - * Michael Meeks + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * Copyright (C) 2002 Sun Microsystems, Inc. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H @@ -20,10 +37,12 @@ #include #include "gdl-dock-item.h" #include "gdl-dock-item-grip.h" -#include "gdl-stock.h" +#include "gdl-dock-item-button-image.h" +#include "gdl-switcher.h" #include "gdl-tools.h" #define ALIGN_BORDER 5 +#define DRAG_HANDLE_SIZE 10 enum { PROP_0, @@ -31,93 +50,64 @@ enum { }; struct _GdlDockItemGripPrivate { + GtkWidget *label; + GtkWidget *close_button; GtkWidget *iconify_button; - - gboolean icon_pixbuf_valid; - GdkPixbuf *icon_pixbuf; - - gchar *title; - PangoLayout *title_layout; + + gboolean handle_shown; }; GDL_CLASS_BOILERPLATE (GdlDockItemGrip, gdl_dock_item_grip, GtkContainer, GTK_TYPE_CONTAINER); - -/* must be called after size_allocate */ -static void -gdl_dock_item_grip_get_title_area (GdlDockItemGrip *grip, - GdkRectangle *area) -{ - GtkWidget *widget = GTK_WIDGET (grip); - gint border = GTK_CONTAINER (grip)->border_width; - gint alloc_height; - - area->width = (widget->allocation.width - 2 * border - ALIGN_BORDER); - - pango_layout_get_pixel_size (grip->_priv->title_layout, NULL, &alloc_height); - - alloc_height = MAX (grip->_priv->close_button->allocation.height, alloc_height); - alloc_height = MAX (grip->_priv->iconify_button->allocation.height, alloc_height); - if (gtk_widget_get_visible (grip->_priv->close_button)) { - area->width -= grip->_priv->close_button->allocation.width; - } - if (gtk_widget_get_visible (grip->_priv->iconify_button)) { - area->width -= grip->_priv->iconify_button->allocation.width; - } - - area->x = widget->allocation.x + border + ALIGN_BORDER; - area->y = widget->allocation.y + border; - area->height = alloc_height; - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - area->x += (widget->allocation.width - 2 * border) - area->width; -} - -static void -ensure_title_and_icon_pixbuf (GdlDockItemGrip *grip) + +GtkWidget* +gdl_dock_item_create_label_widget(GdlDockItemGrip *grip) { - gchar *stock_id; + GtkHBox *label_box; + GtkImage *image; + GtkLabel *label; + gchar *stock_id = NULL; + gchar *title = NULL; GdkPixbuf *pixbuf; + + label_box = (GtkHBox*)gtk_hbox_new (FALSE, 0); - g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (grip)); - - /* get long name property from the dock object */ - if (!grip->_priv->title) { - g_object_get (G_OBJECT (grip->item), "long-name", &grip->_priv->title, NULL); - if (!grip->_priv->title) - grip->_priv->title = g_strdup (""); - } - - /* retrieve stock pixbuf, if any */ - if (!grip->_priv->icon_pixbuf_valid) { - g_object_get (G_OBJECT (grip->item), "stock-id", &stock_id, NULL); + g_object_get (G_OBJECT (grip->item), "stock-id", &stock_id, NULL); + g_object_get (G_OBJECT (grip->item), "pixbuf-icon", &pixbuf, NULL); + if(stock_id) { + image = GTK_IMAGE(gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU)); - if (stock_id) { - grip->_priv->icon_pixbuf = gtk_widget_render_icon (GTK_WIDGET (grip), - stock_id, - GTK_ICON_SIZE_MENU, ""); - g_free (stock_id); - grip->_priv->icon_pixbuf_valid = TRUE; - } + gtk_widget_show (GTK_WIDGET(image)); + gtk_box_pack_start(GTK_BOX(label_box), GTK_WIDGET(image), FALSE, TRUE, 0); + + g_free (stock_id); + } + else if (pixbuf) { + image = GTK_IMAGE(gtk_image_new_from_pixbuf (pixbuf)); + + gtk_widget_show (GTK_WIDGET(image)); + gtk_box_pack_start(GTK_BOX(label_box), GTK_WIDGET(image), FALSE, TRUE, 0); } - - /* retrieve pixbuf icon, if any */ - if (!grip->_priv->icon_pixbuf_valid) { - g_object_get (G_OBJECT (grip->item), "pixbuf-icon", &pixbuf, NULL); - if (pixbuf) { - grip->_priv->icon_pixbuf = pixbuf; - grip->_priv->icon_pixbuf_valid = TRUE; + g_object_get (G_OBJECT (grip->item), "long-name", &title, NULL); + if (title) { + label = GTK_LABEL(gtk_label_new(title)); + gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END); + gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_widget_show (GTK_WIDGET(label)); + + if (gtk_widget_get_direction (GTK_WIDGET(grip)) == GTK_TEXT_DIR_RTL) { + gtk_box_pack_end(GTK_BOX(label_box), GTK_WIDGET(label), TRUE, TRUE, 1); + } else { + gtk_box_pack_start(GTK_BOX(label_box), GTK_WIDGET(label), TRUE, TRUE, 1); } + + g_free(title); } - - /* create layout: the actual text is reset at size_allocate */ - if (!grip->_priv->title_layout) { - grip->_priv->title_layout = gtk_widget_create_pango_layout (GTK_WIDGET (grip), - grip->_priv->title); - pango_layout_set_single_paragraph_mode (grip->_priv->title_layout, TRUE); - } + + return GTK_WIDGET(label_box); } static gint @@ -125,6 +115,14 @@ gdl_dock_item_grip_expose (GtkWidget *widget, GdkEventExpose *event) { GdlDockItemGrip *grip; +/*<<<<<<< HEAD */ + GdkRectangle handle_area; + GdkRectangle expose_area; + + grip = GDL_DOCK_ITEM_GRIP (widget); + + if(grip->_priv->handle_shown) { +/*======= GdkRectangle title_area; GdkRectangle expose_area; GdkGC *bg_style; @@ -134,11 +132,11 @@ gdl_dock_item_grip_expose (GtkWidget *widget, gint text_y; grip = GDL_DOCK_ITEM_GRIP (widget); - gdl_dock_item_grip_get_title_area (grip, &title_area); + gdl_dock_item_grip_get_title_area (grip, &title_area); */ /* draw background, highlight it if the dock item or any of its * descendants have focus */ - bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ? +/* bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ? gtk_widget_get_style (widget)->dark_gc[widget->state] : gtk_widget_get_style (widget)->mid_gc[widget->state]); @@ -148,51 +146,35 @@ gdl_dock_item_grip_expose (GtkWidget *widget, if (grip->_priv->icon_pixbuf) { GdkRectangle pixbuf_rect; +>>>>>>> gdl-2.26.0-with-inkscape */ - pixbuf_rect.width = gdk_pixbuf_get_width (grip->_priv->icon_pixbuf); - pixbuf_rect.height = gdk_pixbuf_get_height (grip->_priv->icon_pixbuf); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { - pixbuf_rect.x = title_area.x + title_area.width - pixbuf_rect.width; + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { + handle_area.x = widget->allocation.x; + handle_area.y = widget->allocation.y; + handle_area.width = DRAG_HANDLE_SIZE; + handle_area.height = widget->allocation.height; } else { - pixbuf_rect.x = title_area.x; - title_area.x += pixbuf_rect.width + 1; + handle_area.x = widget->allocation.x + widget->allocation.width + - DRAG_HANDLE_SIZE; + handle_area.y = widget->allocation.y; + handle_area.width = DRAG_HANDLE_SIZE; + handle_area.height = widget->allocation.height; } - /* shrink title area by the pixbuf width plus a 1px spacing */ - title_area.width -= pixbuf_rect.width + 1; - pixbuf_rect.y = title_area.y + (title_area.height - pixbuf_rect.height) / 2; - - if (gdk_rectangle_intersect (&event->area, &pixbuf_rect, &expose_area)) { - GdkGC *gc; - GtkStyle *style; - - style = gtk_widget_get_style (widget); - gc = style->bg_gc[widget->state]; - gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), gc, - grip->_priv->icon_pixbuf, - 0, 0, pixbuf_rect.x, pixbuf_rect.y, - pixbuf_rect.width, pixbuf_rect.height, - GDK_RGB_DITHER_NONE, 0, 0); - } - } - if (gdk_rectangle_intersect (&title_area, &event->area, &expose_area)) { - pango_layout_get_pixel_size (grip->_priv->title_layout, &layout_width, - &layout_height); + if (gdk_rectangle_intersect (&handle_area, &event->area, &expose_area)) { - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - text_x = title_area.x + title_area.width - layout_width; - else - text_x = title_area.x; - - text_y = title_area.y + (title_area.height - layout_height) / 2; - - gtk_paint_layout (widget->style, widget->window, widget->state, TRUE, - &expose_area, widget, NULL, text_x, text_y, - grip->_priv->title_layout); + gtk_paint_handle (widget->style, widget->window, widget->state, + GTK_SHADOW_NONE, &expose_area, widget, + "handlebox", handle_area.x, handle_area.y, + handle_area.width, handle_area.height, + GTK_ORIENTATION_VERTICAL); + + } + } return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); -} +} static void gdl_dock_item_grip_item_notify (GObject *master, @@ -205,23 +187,12 @@ gdl_dock_item_grip_item_notify (GObject *master, grip = GDL_DOCK_ITEM_GRIP (data); - if (strcmp (pspec->name, "stock-id") == 0) { - if (grip->_priv->icon_pixbuf) { - g_object_unref (grip->_priv->icon_pixbuf); - grip->_priv->icon_pixbuf = NULL; - } - grip->_priv->icon_pixbuf_valid = FALSE; - ensure_title_and_icon_pixbuf (grip); - - } else if (strcmp (pspec->name, "long-name") == 0) { - if (grip->_priv->title_layout) { - g_object_unref (grip->_priv->title_layout); - grip->_priv->title_layout = NULL; - } - g_free (grip->_priv->title); - grip->_priv->title = NULL; - ensure_title_and_icon_pixbuf (grip); - gtk_widget_queue_draw (GTK_WIDGET (grip)); + if ((strcmp (pspec->name, "stock-id") == 0) || + (strcmp (pspec->name, "long-name") == 0)) { + + gdl_dock_item_grip_set_label (grip, + gdl_dock_item_create_label_widget(grip)); + } else if (strcmp (pspec->name, "behavior") == 0) { cursor = FALSE; if (grip->_priv->close_button) { @@ -250,20 +221,13 @@ static void gdl_dock_item_grip_destroy (GtkObject *object) { GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (object); - + if (grip->_priv) { GdlDockItemGripPrivate *priv = grip->_priv; - if (priv->title_layout) { - g_object_unref (priv->title_layout); - priv->title_layout = NULL; - } - g_free (priv->title); - priv->title = NULL; - - if (priv->icon_pixbuf) { - g_object_unref (priv->icon_pixbuf); - priv->icon_pixbuf = NULL; + if (priv->label) { + gtk_widget_unparent(grip->_priv->label); + priv->label = NULL; } if (grip->item) @@ -275,7 +239,7 @@ gdl_dock_item_grip_destroy (GtkObject *object) grip->_priv = NULL; g_free (priv); } - + GDL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); } @@ -331,10 +295,34 @@ static void gdl_dock_item_grip_iconify_clicked (GtkWidget *widget, GdlDockItemGrip *grip) { + GtkWidget *parent; + (void)widget; g_return_if_fail (grip->item != NULL); - gdl_dock_item_iconify_item (grip->item); + parent = gtk_widget_get_parent (GTK_WIDGET (grip->item)); + if (GDL_IS_SWITCHER (parent)) + { + /* Note: We can not use gtk_container_foreach (parent) here because + * during iconificatoin, the internal children changes in parent. + * Instead we keep a list of items to iconify and iconify them + * one by one. + */ + GList *node; + GList *items = + gtk_container_get_children (GTK_CONTAINER (parent)); + for (node = items; node != NULL; node = node->next) + { + GdlDockItem *item = GDL_DOCK_ITEM (node->data); + if (!GDL_DOCK_ITEM_CANT_ICONIFY (item)) + gdl_dock_item_iconify_item (item); + } + g_list_free (items); + } + else + { + gdl_dock_item_iconify_item (grip->item); + } /* Workaround to unhighlight the iconify button. */ GTK_BUTTON (grip->_priv->iconify_button)->in_button = FALSE; @@ -349,10 +337,9 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) gtk_widget_set_has_window (GTK_WIDGET (grip), FALSE); grip->_priv = g_new0 (GdlDockItemGripPrivate, 1); - grip->_priv->icon_pixbuf_valid = FALSE; - grip->_priv->icon_pixbuf = NULL; - grip->_priv->title_layout = NULL; - + grip->_priv->label = NULL; + grip->_priv->handle_shown = FALSE; + /* create the close button */ gtk_widget_push_composite_child (); grip->_priv->close_button = gtk_button_new (); @@ -363,7 +350,7 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) gtk_button_set_relief (GTK_BUTTON (grip->_priv->close_button), GTK_RELIEF_NONE); gtk_widget_show (grip->_priv->close_button); - image = gtk_image_new_from_stock (GDL_STOCK_CLOSE, GTK_ICON_SIZE_MENU); + image = gdl_dock_item_button_image_new(GDL_DOCK_ITEM_BUTTON_IMAGE_CLOSE); gtk_container_add (GTK_CONTAINER (grip->_priv->close_button), image); gtk_widget_show (image); @@ -380,7 +367,7 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) gtk_button_set_relief (GTK_BUTTON (grip->_priv->iconify_button), GTK_RELIEF_NONE); gtk_widget_show (grip->_priv->iconify_button); - image = gtk_image_new_from_stock (GDL_STOCK_MENU_RIGHT, GTK_ICON_SIZE_MENU); + image = gdl_dock_item_button_image_new(GDL_DOCK_ITEM_BUTTON_IMAGE_ICONIFY); gtk_container_add (GTK_CONTAINER (grip->_priv->iconify_button), image); gtk_widget_show (image); @@ -401,33 +388,36 @@ gdl_dock_item_grip_realize (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->realize (widget); + g_return_if_fail (grip->_priv != NULL); + if (!grip->title_window) { GdkWindowAttr attributes; - GdkRectangle area; GdkCursor *cursor; - ensure_title_and_icon_pixbuf (grip); - gdl_dock_item_grip_get_title_area (grip, &area); - - attributes.x = area.x; - attributes.y = area.y; - attributes.width = area.width; - attributes.height = area.height; - attributes.window_type = GDK_WINDOW_TEMP; - attributes.wclass = GDK_INPUT_ONLY; - attributes.override_redirect = TRUE; - attributes.event_mask = (GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_MOTION_MASK | - gtk_widget_get_events (widget)); + g_return_if_fail (grip->_priv->label != NULL); + + attributes.x = grip->_priv->label->allocation.x; + attributes.y = grip->_priv->label->allocation.y; + attributes.width = grip->_priv->label->allocation.width; + attributes.height = grip->_priv->label->allocation.height; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = GDK_ALL_EVENTS_MASK; grip->title_window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, - (GDK_WA_X | - GDK_WA_Y | - GDK_WA_NOREDIR)); + &attributes, (GDK_WA_X | GDK_WA_Y)); + + gdk_window_set_user_data (grip->title_window, grip); + + /* Unref the ref from parent realize for NO_WINDOW */ + g_object_unref (widget->window); + + /* Need to ref widget->window, because parent unrealize unrefs it */ + widget->window = g_object_ref (grip->title_window); + GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW); - gdk_window_set_user_data (grip->title_window, widget); + /* Unset the background so as to make the colour match the parent window */ + gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, NULL); if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item) && GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) @@ -447,6 +437,7 @@ gdl_dock_item_grip_unrealize (GtkWidget *widget) GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (widget); if (grip->title_window) { + GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW); gdk_window_set_user_data (grip->title_window, NULL); gdk_window_destroy (grip->title_window); grip->title_window = NULL; @@ -484,7 +475,7 @@ gdl_dock_item_grip_size_request (GtkWidget *widget, GtkRequisition child_requisition; GtkContainer *container; GdlDockItemGrip *grip; - gint layout_height; + gint layout_height = 0; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (requisition != NULL); @@ -492,11 +483,11 @@ gdl_dock_item_grip_size_request (GtkWidget *widget, container = GTK_CONTAINER (widget); grip = GDL_DOCK_ITEM_GRIP (widget); - requisition->width = container->border_width * 2 + ALIGN_BORDER; + requisition->width = container->border_width * 2/* + ALIGN_BORDER*/; requisition->height = container->border_width * 2; - ensure_title_and_icon_pixbuf (grip); - pango_layout_get_pixel_size (grip->_priv->title_layout, NULL, &layout_height); + if(grip->_priv->handle_shown) + requisition->width += DRAG_HANDLE_SIZE; gtk_widget_size_request (grip->_priv->close_button, &child_requisition); layout_height = MAX (layout_height, child_requisition.height); @@ -509,54 +500,12 @@ gdl_dock_item_grip_size_request (GtkWidget *widget, if (GTK_WIDGET_VISIBLE (grip->_priv->iconify_button)) { requisition->width += child_requisition.width; } - - requisition->height += layout_height; - - if (grip->_priv->icon_pixbuf) { - requisition->width += gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; - } -} - -#define ELLIPSIS "..." - -static void -ellipsize_layout (PangoLayout *layout, gint width) -{ - PangoLayoutLine *line; - PangoLayout *ell; - gint h, w, ell_w, x; - GString *text; - - if (width <= 0) { - pango_layout_set_text (layout, "", -1); - return; - } - - pango_layout_get_pixel_size (layout, &w, &h); - if (w <= width) return; + + gtk_widget_size_request (grip->_priv->label, &child_requisition); + requisition->width += child_requisition.width; + layout_height = MAX (layout_height, child_requisition.height); - /* calculate ellipsis width */ - ell = pango_layout_copy (layout); - pango_layout_set_text (ell, ELLIPSIS, -1); - pango_layout_get_pixel_size (ell, &ell_w, NULL); - g_object_unref (ell); - - if (width < ell_w) { - /* not even ellipsis fits, so hide the text */ - pango_layout_set_text (layout, "", -1); - return; - } - - /* shrink total available width by the width of the ellipsis */ - width -= ell_w; - line = pango_layout_get_line (layout, 0); - text = g_string_new (pango_layout_get_text (layout)); - if (pango_layout_line_x_to_index (line, width * PANGO_SCALE, &x, NULL)) { - g_string_set_size (text, x); - g_string_append (text, ELLIPSIS); - pango_layout_set_text (layout, text->str, -1); - } - g_string_free (text, TRUE); + requisition->height += layout_height; } static void @@ -565,9 +514,10 @@ gdl_dock_item_grip_size_allocate (GtkWidget *widget, { GdlDockItemGrip *grip; GtkContainer *container; - GtkRequisition button_requisition; + GtkRequisition close_requisition = { 0, }; + GtkRequisition iconify_requisition = { 0, }; GtkAllocation child_allocation; - memset(&button_requisition, 0, sizeof(button_requisition)); + GdkRectangle label_area; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (allocation != NULL); @@ -577,59 +527,96 @@ gdl_dock_item_grip_size_allocate (GtkWidget *widget, GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); + gtk_widget_size_request (grip->_priv->close_button, + &close_requisition); + gtk_widget_size_request (grip->_priv->iconify_button, + &iconify_requisition); + + /* Calculate the Minimum Width where buttons will fit */ + int min_width = close_requisition.width + iconify_requisition.width + + container->border_width * 2; + if(grip->_priv->handle_shown) + min_width += DRAG_HANDLE_SIZE; + const gboolean space_for_buttons = (allocation->width >= min_width); + + /* Set up the rolling child_allocation rectangle */ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x = allocation->x + container->border_width + ALIGN_BORDER; + child_allocation.x = container->border_width/* + ALIGN_BORDER*/; else - child_allocation.x = allocation->x + allocation->width - container->border_width; - child_allocation.y = allocation->y + container->border_width; + child_allocation.x = allocation->width - container->border_width; + child_allocation.y = container->border_width; + /* Layout Close Button */ if (GTK_WIDGET_VISIBLE (grip->_priv->close_button)) { - gtk_widget_size_request (grip->_priv->close_button, &button_requisition); - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) - child_allocation.x -= button_requisition.width; - - child_allocation.width = button_requisition.width; - child_allocation.height = button_requisition.height; + if(space_for_buttons) { + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) + child_allocation.x -= close_requisition.width; + + child_allocation.width = close_requisition.width; + child_allocation.height = close_requisition.height; + } else { + child_allocation.width = 0; + } gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x += button_requisition.width; + child_allocation.x += close_requisition.width; } + /* Layout Iconify Button */ if (GTK_WIDGET_VISIBLE (grip->_priv->iconify_button)) { - gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition); - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) - child_allocation.x -= button_requisition.width; + if(space_for_buttons) { + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) + child_allocation.x -= iconify_requisition.width; - child_allocation.width = button_requisition.width; - child_allocation.height = button_requisition.height; + child_allocation.width = iconify_requisition.width; + child_allocation.height = iconify_requisition.height; + } else { + child_allocation.width = 0; + } gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x += button_requisition.width; + child_allocation.x += iconify_requisition.width; } - if (grip->title_window) { - GdkRectangle area; + /* Layout the Grip Handle*/ + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { + child_allocation.width = child_allocation.x; + child_allocation.x = container->border_width/* + ALIGN_BORDER*/; - /* set layout text */ - ensure_title_and_icon_pixbuf (grip); - pango_layout_set_text (grip->_priv->title_layout, grip->_priv->title, -1); - - gdl_dock_item_grip_get_title_area (grip, &area); - - gdk_window_move_resize (grip->title_window, - area.x, area.y, area.width, area.height); - - if (grip->_priv->icon_pixbuf) - area.width -= gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; + if(grip->_priv->handle_shown) { + child_allocation.x += DRAG_HANDLE_SIZE; + child_allocation.width -= DRAG_HANDLE_SIZE; + } + + } else { + child_allocation.width = allocation->width - + (child_allocation.x - allocation->x)/* - ALIGN_BORDER*/; - /* ellipsize title if it doesn't fit the title area */ - ellipsize_layout (grip->_priv->title_layout, area.width); + if(grip->_priv->handle_shown) + child_allocation.width -= DRAG_HANDLE_SIZE; + } + + if(child_allocation.width < 0) + child_allocation.width = 0; + + child_allocation.y = container->border_width; + child_allocation.height = allocation->height - container->border_width * 2; + if(grip->_priv->label) { + gtk_widget_size_allocate (grip->_priv->label, &child_allocation); + } + + if (grip->title_window) { + gdk_window_move_resize (grip->title_window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); } } @@ -646,9 +633,8 @@ static void gdl_dock_item_grip_remove (GtkContainer *container, GtkWidget *widget) { - (void)container; (void)widget; - g_warning ("gtk_container_remove not implemented for GdlDockItemGrip"); + gdl_dock_item_grip_set_label (GDL_DOCK_ITEM_GRIP (container), NULL); } static void @@ -660,12 +646,17 @@ gdl_dock_item_grip_forall (GtkContainer *container, GdlDockItemGrip *grip; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (container)); - grip = GDL_DOCK_ITEM_GRIP (container); + + if (grip->_priv) { + if(grip->_priv->label) { + (* callback) (grip->_priv->label, callback_data); + } - if (include_internals) { - (* callback) (grip->_priv->close_button, callback_data); - (* callback) (grip->_priv->iconify_button, callback_data); + if (include_internals) { + (* callback) (grip->_priv->close_button, callback_data); + (* callback) (grip->_priv->iconify_button, callback_data); + } } } @@ -713,9 +704,12 @@ gdl_dock_item_grip_class_init (GdlDockItemGripClass *klass) _("Dockitem which 'owns' this grip"), GDL_TYPE_DOCK_ITEM, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); +} - /* initialize stock images */ - gdl_stock_init (); +static void +gdl_dock_item_grip_showhide_handle (GdlDockItemGrip *grip) +{ + gtk_widget_queue_resize (GTK_WIDGET (grip)); } /* ----- Public interface ----- */ @@ -735,3 +729,61 @@ gdl_dock_item_grip_new (GdlDockItem *item) return GTK_WIDGET (grip); } + +/** + * gdl_dock_item_grip_set_label: + * @grip: The grip that will get it's label widget set. + * @label: The widget that will become the label. + * + * Replaces the current label widget with another widget. + **/ +void +gdl_dock_item_grip_set_label (GdlDockItemGrip *grip, + GtkWidget *label) +{ + g_return_if_fail (grip != NULL); + + if (grip->_priv->label) { + gtk_widget_unparent(grip->_priv->label); + g_object_unref (grip->_priv->label); + grip->_priv->label = NULL; + } + + if (label) { + g_object_ref (label); + gtk_widget_set_parent (label, GTK_WIDGET (grip)); + gtk_widget_show (label); + grip->_priv->label = label; + } +} +/** + * gdl_dock_item_grip_hide_handle: + * @item: The dock item grip to hide the handle of. + * + * This function hides the dock item's grip widget handle hatching. + **/ +void +gdl_dock_item_grip_hide_handle (GdlDockItemGrip *grip) +{ + g_return_if_fail (grip != NULL); + if (grip->_priv->handle_shown) { + grip->_priv->handle_shown = FALSE; + gdl_dock_item_grip_showhide_handle (grip); + }; +} + +/** + * gdl_dock_item_grip_show_handle: + * @grip: The dock item grip to show the handle of. + * + * This function shows the dock item's grip widget handle hatching. + **/ +void +gdl_dock_item_grip_show_handle (GdlDockItemGrip *grip) +{ + g_return_if_fail (grip != NULL); + if (!grip->_priv->handle_shown) { + grip->_priv->handle_shown = TRUE; + gdl_dock_item_grip_showhide_handle (grip); + }; +} diff --git a/src/libgdl/gdl-dock-item-grip.h b/src/libgdl/gdl-dock-item-grip.h index 4dfdd7ab3..a44ef91fb 100644 --- a/src/libgdl/gdl-dock-item-grip.h +++ b/src/libgdl/gdl-dock-item-grip.h @@ -1,13 +1,30 @@ /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/** +/* * gdl-dock-item-grip.h - * - * Based on bonobo-dock-item-grip. Original copyright notice follows. * - * Author: - * Michael Meeks + * Author: Michael Meeks Copyright (C) 2002 Sun Microsystems, Inc. * - * Copyright (C) 2002 Sun Microsystems, Inc. + * Based on BonoboDockItemGrip. Original copyright notice follows. + * + * Copyright (C) 1998 Ettore Perazzoli + * Copyright (C) 1998 Elliot Lee + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ #ifndef _GDL_DOCK_ITEM_GRIP_H_ @@ -50,6 +67,10 @@ struct _GdlDockItemGripClass { GType gdl_dock_item_grip_get_type (void); GtkWidget *gdl_dock_item_grip_new (GdlDockItem *item); +void gdl_dock_item_grip_set_label (GdlDockItemGrip *grip, + GtkWidget *label); +void gdl_dock_item_grip_hide_handle (GdlDockItemGrip *grip); +void gdl_dock_item_grip_show_handle (GdlDockItemGrip *grip); G_END_DECLS diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index 86f729c61..0c0d765df 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -163,6 +163,7 @@ enum { DOCK_DRAG_BEGIN, DOCK_DRAG_MOTION, DOCK_DRAG_END, + SELECTED, MOVE_FOCUS_CHILD, LAST_SIGNAL }; @@ -407,6 +408,22 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) 1, G_TYPE_BOOLEAN); + /** + * GdlDockItem::selected: + * + * Signals that this dock has been selected from a switcher. + */ + gdl_dock_item_signals [SELECTED] = + g_signal_new ("selected", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + gdl_dock_item_signals [MOVE_FOCUS_CHILD] = g_signal_new ("move_focus_child", G_TYPE_FROM_CLASS (klass), @@ -1924,6 +1941,23 @@ gdl_dock_item_set_tablabel (GdlDockItem *item, } } +/** + * gdl_dock_item_get_grip: + * @item: The dock item from which to to get the grip of. + * + * This function returns the dock item's grip label widget. + * + * Returns: Returns the current label widget. + **/ +GtkWidget * +gdl_dock_item_get_grip(GdlDockItem *item) +{ + g_return_if_fail (item != NULL); + g_return_val_if_fail (GDL_IS_DOCK_ITEM (item), NULL); + + return item->_priv->grip; +} + /** * gdl_dock_item_hide_grip: * @item: The dock item to hide the grip of. @@ -1957,6 +1991,19 @@ gdl_dock_item_show_grip (GdlDockItem *item) }; } +/** + * gdl_dock_item_notify_selected: + * @item: the dock item to emit a selected signal on. + * + * This function emits the selected signal. It is to be used by #GdlSwitcher + * to let clients know that this item has been switched to. + **/ +void +gdl_dock_item_notify_selected (GdlDockItem *item) +{ + g_signal_emit (item, gdl_dock_item_signals [SELECTED], 0); +} + /* convenient function (and to preserve source compat) */ /** * gdl_dock_item_bind: diff --git a/src/libgdl/gdl-dock-item.h b/src/libgdl/gdl-dock-item.h index 6c0029d13..d97fdf6fd 100644 --- a/src/libgdl/gdl-dock-item.h +++ b/src/libgdl/gdl-dock-item.h @@ -93,17 +93,16 @@ struct _GdlDockItemClass { gboolean has_grip; /* virtuals */ - void (* dock_drag_begin) (GdlDockItem *item); - void (* dock_drag_motion) (GdlDockItem *item, - gint x, - gint y); - void (* dock_drag_end) (GdlDockItem *item, - gboolean cancelled); + void (* dock_drag_begin) (GdlDockItem *item); + void (* dock_drag_motion) (GdlDockItem *item, + gint x, + gint y); + void (* dock_drag_end) (GdlDockItem *item, + gboolean cancelled); void (* move_focus_child) (GdlDockItem *item, GtkDirectionType direction); - - void (* set_orientation) (GdlDockItem *item, - GtkOrientation orientation); + void (* set_orientation) (GdlDockItem *item, + GtkOrientation orientation); }; /* additional macros */ @@ -163,8 +162,10 @@ void gdl_dock_item_set_orientation (GdlDockItem *item, GtkWidget *gdl_dock_item_get_tablabel (GdlDockItem *item); void gdl_dock_item_set_tablabel (GdlDockItem *item, GtkWidget *tablabel); +GtkWidget *gdl_dock_item_get_grip (GdlDockItem *item); void gdl_dock_item_hide_grip (GdlDockItem *item); void gdl_dock_item_show_grip (GdlDockItem *item); +void gdl_dock_item_notify_selected (GdlDockItem *item); /* bind and unbind items to a dock */ void gdl_dock_item_bind (GdlDockItem *item, diff --git a/src/libgdl/gdl-dock-layout.c b/src/libgdl/gdl-dock-layout.c index a0f0a3e3a..7c5279507 100644 --- a/src/libgdl/gdl-dock-layout.c +++ b/src/libgdl/gdl-dock-layout.c @@ -28,7 +28,6 @@ #include #include #include -#include #include "gdl-dock-layout.h" #include "gdl-tools.h" @@ -48,7 +47,7 @@ enum { #define LAYOUT_ELEMENT_NAME "layout" #define NAME_ATTRIBUTE_NAME "name" -#define LAYOUT_GLADE_FILE "layout.glade" +#define LAYOUT_UI_FILE "layout.ui" enum { COLUMN_NAME, @@ -548,20 +547,23 @@ master_locked_notify_cb (GdlDockMaster *master, } } -static GladeXML * -load_interface (const gchar *top_widget) +static GtkBuilder * +load_interface () { - GladeXML *gui; + GtkBuilder *gui; gchar *gui_file; + GError* error = NULL; /* load ui */ - gui_file = g_build_filename (GDL_GLADEDIR, LAYOUT_GLADE_FILE, NULL); - gui = glade_xml_new (gui_file, top_widget, GETTEXT_PACKAGE); + gui_file = g_build_filename (GDL_UIDIR, LAYOUT_UI_FILE, NULL); + gui = gtk_builder_new(); + gtk_builder_add_from_file (gui, gui_file, &error); g_free (gui_file); - if (!gui) { - /* FIXME: pop up an error dialog */ + if (error) { g_warning (_("Could not load layout user interface file '%s'"), - LAYOUT_GLADE_FILE); + LAYOUT_UI_FILE); + g_object_unref (gui); + g_error_free (error); return NULL; }; return gui; @@ -570,8 +572,8 @@ load_interface (const gchar *top_widget) static GtkWidget * gdl_dock_layout_construct_items_ui (GdlDockLayout *layout) { - GladeXML *gui; - GtkWidget *container; + GtkBuilder *gui; + GtkWidget *dialog; GtkWidget *items_list; GtkCellRenderer *renderer; GtkTreeViewColumn *column; @@ -579,23 +581,23 @@ gdl_dock_layout_construct_items_ui (GdlDockLayout *layout) GdlDockLayoutUIData *ui_data; /* load the interface if it wasn't provided */ - gui = load_interface ("items_vbox"); + gui = load_interface (); if (!gui) return NULL; /* get the container */ - container = glade_xml_get_widget (gui, "items_vbox"); + dialog = GTK_WIDGET (gtk_builder_get_object (gui, "layout_dialog")); ui_data = g_new0 (GdlDockLayoutUIData, 1); ui_data->layout = layout; g_object_add_weak_pointer (G_OBJECT (layout), (gpointer *) &ui_data->layout); - g_object_set_data (G_OBJECT (container), "ui_data", ui_data); + g_object_set_data (G_OBJECT (dialog), "ui_data", ui_data); /* get ui widget references */ - ui_data->locked_check = glade_xml_get_widget (gui, "locked_check"); - items_list = glade_xml_get_widget (gui, "items_list"); + ui_data->locked_check = GTK_WIDGET (gtk_builder_get_object (gui, "locked_check")); + items_list = GTK_WIDGET (gtk_builder_get_object(gui, "items_list")); /* locked check connections */ g_signal_connect (ui_data->locked_check, "toggled", @@ -629,11 +631,11 @@ gdl_dock_layout_construct_items_ui (GdlDockLayout *layout) gtk_tree_view_append_column (GTK_TREE_VIEW (items_list), column); /* connect signals */ - g_signal_connect (container, "destroy", (GCallback) layout_ui_destroyed, NULL); + g_signal_connect (dialog, "destroy", (GCallback) layout_ui_destroyed, NULL); g_object_unref (gui); - return container; + return dialog; } static void @@ -671,22 +673,24 @@ cell_edited_cb (GtkCellRendererText *cell, static GtkWidget * gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) { - GladeXML *gui; + GtkBuilder *gui; GtkWidget *container; GtkWidget *layouts_list; GtkCellRenderer *renderer; GtkTreeViewColumn *column; + GtkWidget *load_button; + GtkWidget *delete_button; GdlDockLayoutUIData *ui_data; /* load the interface if it wasn't provided */ - gui = load_interface ("layouts_vbox"); + gui = load_interface (); if (!gui) return NULL; /* get the container */ - container = glade_xml_get_widget (gui, "layouts_vbox"); + container = GTK_WIDGET (gtk_builder_get_object(gui, "layouts_vbox")); ui_data = g_new0 (GdlDockLayoutUIData, 1); ui_data->layout = layout; @@ -695,7 +699,7 @@ gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) g_object_set_data (G_OBJECT (container), "ui-data", ui_data); /* get ui widget references */ - layouts_list = glade_xml_get_widget (gui, "layouts_list"); + layouts_list = GTK_WIDGET (gtk_builder_get_object(gui, "layouts_list")); /* set models */ gtk_tree_view_set_model (GTK_TREE_VIEW (layouts_list), @@ -714,10 +718,12 @@ gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) ui_data->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (layouts_list)); /* connect signals */ - glade_xml_signal_connect_data (gui, "on_load_button_clicked", - G_CALLBACK (load_layout_cb), ui_data); - glade_xml_signal_connect_data (gui, "on_delete_button_clicked", - G_CALLBACK (delete_layout_cb), ui_data); + load_button = GTK_WIDGET (gtk_builder_get_object(gui, "load_button")); + delete_button = GTK_WIDGET (gtk_builder_get_object(gui, "delete_button")); + + g_signal_connect (load_button, "clicked", (GCallback) load_layout_cb, ui_data); + g_signal_connect (delete_button, "clicked", (GCallback) delete_layout_cb, ui_data); + g_signal_connect (container, "destroy", (GCallback) layout_ui_destroyed, NULL); @@ -726,31 +732,6 @@ gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) return container; } -static GtkWidget * -gdl_dock_layout_construct_ui (GdlDockLayout *layout) -{ - GtkWidget *container, *child; - - container = gtk_notebook_new (); - gtk_widget_show (container); - - child = gdl_dock_layout_construct_items_ui (layout); - if (child) - gtk_notebook_append_page (GTK_NOTEBOOK (container), - child, - gtk_label_new (_("Dock items"))); - - child = gdl_dock_layout_construct_layouts_ui (layout); - if (child) - gtk_notebook_append_page (GTK_NOTEBOOK (container), - child, - gtk_label_new (_("Saved layouts"))); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (container), 0); - - return container; -} - /* ----- Save & Load layout functions --------- */ #define GDL_DOCK_PARAM_CONSTRUCTION(p) \ @@ -1095,6 +1076,13 @@ gdl_dock_layout_save (GdlDockMaster *master, /* ----- Public interface ----- */ +/** + * gdl_dock_layout_new: + * @dock: The dock item. + * Creates a new #GdlDockLayout + * + * Returns: New #GdlDockLayout item. + */ GdlDockLayout * gdl_dock_layout_new (GdlDock *dock) { @@ -1133,6 +1121,15 @@ gdl_dock_layout_layout_changed_cb (GdlDockMaster *master, } } + +/** + * gdl_dock_layout_attach: + * @layout: The layout item + * @master: The master item to which the layout will be attached + * + * Attach the @layout to the @master and delete the reference to + * the master that the layout attached previously + */ void gdl_dock_layout_attach (GdlDockLayout *layout, GdlDockMaster *master) @@ -1159,6 +1156,17 @@ gdl_dock_layout_attach (GdlDockLayout *layout, update_items_model (layout); } +/** +* gdl_dock_layout_load_layout: +* @layout: The dock item. +* @name: The name of the layout to load. +* +* Loads the layout with the given name to the memory. +* This will set #GdlDockLayout:dirty to %TRUE. +* +* See also gdl_dock_layout_load_from_file() +* Returns: %TRUE if layout successfully loaded else %FALSE +*/ gboolean gdl_dock_layout_load_layout (GdlDockLayout *layout, const gchar *name) @@ -1188,6 +1196,17 @@ gdl_dock_layout_load_layout (GdlDockLayout *layout, return FALSE; } +/** +* gdl_dock_layout_save_layout: +* @layout: The dock item. +* @name: The name of the layout to save. +* +* Saves the @layout with the given name to the memory. +* This will set #GdlDockLayout:dirty to %TRUE. +* +* See also gdl_dock_layout_save_to_file(). +*/ + void gdl_dock_layout_save_layout (GdlDockLayout *layout, const gchar *name) @@ -1224,6 +1243,15 @@ gdl_dock_layout_save_layout (GdlDockLayout *layout, g_object_notify (G_OBJECT (layout), "dirty"); } +/** +* gdl_dock_layout_delete_layout: +* @layout: The dock item. +* @name: The name of the layout to delete. +* +* Deletes the layout with the given name from the memory. +* This will set #GdlDockLayout:dirty to %TRUE. +*/ + void gdl_dock_layout_delete_layout (GdlDockLayout *layout, const gchar *name) @@ -1245,10 +1273,17 @@ gdl_dock_layout_delete_layout (GdlDockLayout *layout, } } +/** +* gdl_dock_layout_run_manager: +* @layout: The dock item. +* +* Runs the layout manager. +*/ + void gdl_dock_layout_run_manager (GdlDockLayout *layout) { - GtkWidget *dialog, *container; + GtkWidget *dialog; GtkWidget *parent = NULL; g_return_if_fail (layout != NULL); @@ -1257,28 +1292,24 @@ gdl_dock_layout_run_manager (GdlDockLayout *layout) /* not attached to a dock yet */ return; - container = gdl_dock_layout_construct_ui (layout); - if (!container) - return; - - parent = GTK_WIDGET (gdl_dock_master_get_controller (layout->master)); - if (parent) - parent = gtk_widget_get_toplevel (parent); - - dialog = gtk_dialog_new_with_buttons (_("Layout managment"), - parent ? GTK_WINDOW (parent) : NULL, - GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 300); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), container); + dialog = gdl_dock_layout_construct_items_ui (layout); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } +/** +* gdl_dock_layout_load_from_file: +* @layout: The layout item. +* @filename: The name of the file to load. +* +* Loads the layout from file with the given @filename. +* This will set #GdlDockLayout:dirty to %FALSE. +* +* Returns: %TRUE if @layout successfully loaded else %FALSE +*/ + gboolean gdl_dock_layout_load_from_file (GdlDockLayout *layout, const gchar *filename) @@ -1311,6 +1342,16 @@ gdl_dock_layout_load_from_file (GdlDockLayout *layout, return retval; } +/** + * gdl_dock_layout_save_to_file: + * @layout: The layout item. + * @filename: Name of the file we want to save in layout + * + * This function saves the current layout in XML format to + * the file with the given @filename. + * + * Returns: %TRUE if @layout successfuly save to the file, otherwise %FALSE. + */ gboolean gdl_dock_layout_save_to_file (GdlDockLayout *layout, const gchar *filename) @@ -1340,6 +1381,13 @@ gdl_dock_layout_save_to_file (GdlDockLayout *layout, return retval; } +/** + * gdl_dock_layout_is_dirty: + * @layout: The layout item. + * + * Checks whether the XML tree in memory is different from the file where the layout was saved. + * Returns: %TRUE is the layout in the memory is different from the file, else %FALSE. + */ gboolean gdl_dock_layout_is_dirty (GdlDockLayout *layout) { @@ -1377,28 +1425,6 @@ gdl_dock_layout_get_layouts (GdlDockLayout *layout, return retval; } -GtkWidget * -gdl_dock_layout_get_ui (GdlDockLayout *layout) -{ - GtkWidget *ui; - - g_return_val_if_fail (layout != NULL, NULL); - ui = gdl_dock_layout_construct_ui (layout); - - return ui; -} - -GtkWidget * -gdl_dock_layout_get_items_ui (GdlDockLayout *layout) -{ - GtkWidget *ui; - - g_return_val_if_fail (layout != NULL, NULL); - ui = gdl_dock_layout_construct_items_ui (layout); - - return ui; -} - GtkWidget * gdl_dock_layout_get_layouts_ui (GdlDockLayout *layout) { diff --git a/src/libgdl/gdl-dock-master.c b/src/libgdl/gdl-dock-master.c index 78cbf69ec..57d0618ec 100644 --- a/src/libgdl/gdl-dock-master.c +++ b/src/libgdl/gdl-dock-master.c @@ -31,6 +31,8 @@ #include "gdl-dock-master.h" #include "gdl-dock.h" #include "gdl-dock-item.h" +#include "gdl-dock-notebook.h" +#include "gdl-switcher.h" #include "libgdlmarshal.h" #include "libgdltypebuiltins.h" #ifdef WIN32 diff --git a/src/libgdl/gdl-dock-master.h b/src/libgdl/gdl-dock-master.h index 3268e68b5..266ca7ee4 100644 --- a/src/libgdl/gdl-dock-master.h +++ b/src/libgdl/gdl-dock-master.h @@ -44,6 +44,15 @@ typedef struct _GdlDockMaster GdlDockMaster; typedef struct _GdlDockMasterClass GdlDockMasterClass; typedef struct _GdlDockMasterPrivate GdlDockMasterPrivate; +typedef enum { + GDL_SWITCHER_STYLE_TEXT, + GDL_SWITCHER_STYLE_ICON, + GDL_SWITCHER_STYLE_BOTH, + GDL_SWITCHER_STYLE_TOOLBAR, + GDL_SWITCHER_STYLE_TABS, + GDL_SWITCHER_STYLE_NONE +} GdlSwitcherStyle; + struct _GdlDockMaster { GObject object; diff --git a/src/libgdl/gdl-dock-notebook.c b/src/libgdl/gdl-dock-notebook.c index f6e0aeeef..3db3fab3f 100644 --- a/src/libgdl/gdl-dock-notebook.c +++ b/src/libgdl/gdl-dock-notebook.c @@ -270,7 +270,7 @@ gdl_dock_notebook_switch_page_cb (GtkNotebook *nb, { GdlDockNotebook *notebook; GtkWidget *tablabel; - (void)page_num; + GdlDockItem *item; notebook = GDL_DOCK_NOTEBOOK (data); @@ -293,6 +293,10 @@ gdl_dock_notebook_switch_page_cb (GtkNotebook *nb, GDL_DOCK_OBJECT (notebook)->master) g_signal_emit_by_name (GDL_DOCK_OBJECT (notebook)->master, "layout-changed"); + + /* Signal that a new dock item has been selected */ + item = GDL_DOCK_ITEM (gtk_notebook_get_nth_page (nb, page_num)); + gdl_dock_item_notify_selected (item); } static void diff --git a/src/libgdl/gdl-dock-object.h b/src/libgdl/gdl-dock-object.h index 6ac36a44c..d1c27ffbd 100644 --- a/src/libgdl/gdl-dock-object.h +++ b/src/libgdl/gdl-dock-object.h @@ -221,7 +221,7 @@ GType gdl_dock_object_set_type_for_nick (const gchar *nick, __PRETTY_FUNCTION__, \ G_OBJECT_TYPE_NAME (object), object, \ G_OBJECT (object)->ref_count, \ - (GTK_IS_OBJECT (object) && GTK_OBJECT_FLOATING (object)) ? "(float)" : "", \ + (GTK_IS_OBJECT (object) && g_object_is_floating (object)) ? "(float)" : "", \ GDL_IS_DOCK_OBJECT (object) ? GDL_DOCK_OBJECT (object)->freeze_count : -1, \ ##args); } G_STMT_END diff --git a/src/libgdl/gdl-dock-paned.c b/src/libgdl/gdl-dock-paned.c index 5d0ac17ed..141770aa2 100644 --- a/src/libgdl/gdl-dock-paned.c +++ b/src/libgdl/gdl-dock-paned.c @@ -710,6 +710,7 @@ gdl_dock_paned_dock (GdlDockObject *object, } else { gdl_dock_item_show_grip (GDL_DOCK_ITEM (requestor)); + gtk_widget_show (GTK_WIDGET (requestor)); GDL_DOCK_OBJECT_SET_FLAGS (requestor, GDL_DOCK_ATTACHED); } } diff --git a/src/libgdl/gdl-dock-placeholder.c b/src/libgdl/gdl-dock-placeholder.c index 33934e2e0..7a86ebe81 100644 --- a/src/libgdl/gdl-dock-placeholder.c +++ b/src/libgdl/gdl-dock-placeholder.c @@ -30,6 +30,7 @@ #include "gdl-tools.h" #include "gdl-dock-placeholder.h" #include "gdl-dock-item.h" +#include "gdl-dock-paned.h" #include "gdl-dock-master.h" #include "libgdltypebuiltins.h" @@ -494,7 +495,7 @@ gdl_dock_placeholder_dock (GdlDockObject *object, GdlDockObject *toplevel; if (!gdl_dock_object_is_bound (GDL_DOCK_OBJECT (ph))) { - g_warning ("%s",_("Attempt to dock a dock object to an unbound placeholder")); + g_warning ("%s", _("Attempt to dock a dock object to an unbound placeholder")); return; } @@ -543,7 +544,7 @@ gdl_dock_placeholder_present (GdlDockObject *object, /* ----- Public interface ----- */ GtkWidget * -gdl_dock_placeholder_new (gchar *name, +gdl_dock_placeholder_new (const gchar *name, GdlDockObject *object, GdlDockPlacement position, gboolean sticky) diff --git a/src/libgdl/gdl-dock-placeholder.h b/src/libgdl/gdl-dock-placeholder.h index aeb55da67..c7e57e204 100644 --- a/src/libgdl/gdl-dock-placeholder.h +++ b/src/libgdl/gdl-dock-placeholder.h @@ -55,7 +55,7 @@ struct _GdlDockPlaceholderClass { GType gdl_dock_placeholder_get_type (void); -GtkWidget *gdl_dock_placeholder_new (gchar *name, +GtkWidget *gdl_dock_placeholder_new (const gchar *name, GdlDockObject *object, GdlDockPlacement position, gboolean sticky); diff --git a/src/libgdl/gdl-dock.c b/src/libgdl/gdl-dock.c index 3b0dc4e6b..47a4f5b3d 100644 --- a/src/libgdl/gdl-dock.c +++ b/src/libgdl/gdl-dock.c @@ -349,21 +349,6 @@ gdl_dock_constructor (GType type, g_signal_connect (dock, "notify::long-name", (GCallback) gdl_dock_notify_cb, NULL); - /* set transient for the first dock if that is a non-floating dock */ - controller = gdl_dock_master_get_controller (master); - if (controller && GDL_IS_DOCK (controller)) { - gboolean first_is_floating; - g_object_get (controller, "floating", &first_is_floating, NULL); - if (!first_is_floating) { - GtkWidget *toplevel = - gtk_widget_get_toplevel (GTK_WIDGET (controller)); - - if (GTK_IS_WINDOW (toplevel)) - gtk_window_set_transient_for (GTK_WINDOW (dock->_priv->window), - GTK_WINDOW (toplevel)); - } - } - gtk_container_add (GTK_CONTAINER (dock->_priv->window), GTK_WIDGET (dock)); g_signal_connect (dock->_priv->window, "delete_event", diff --git a/src/libgdl/gdl-stock.c b/src/libgdl/gdl-stock.c deleted file mode 100644 index 4cb7bf929..000000000 --- a/src/libgdl/gdl-stock.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * gdl-stock.c - * - * Copyright (C) 2003 Jeroen Zwartepoorte - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "gdl-stock.h" -#include "gdl-stock-icons.h" - -static GtkIconFactory *gdl_stock_factory = NULL; - -static struct { - const gchar *stock_id; - const guint8 *icon_data; - const guint data_size; -} -gdl_icons[] = -{ - { GDL_STOCK_CLOSE, stock_close_icon, sizeof (stock_close_icon) }, - { GDL_STOCK_MENU_LEFT, stock_menu_left_icon, sizeof (stock_menu_left_icon) }, - { GDL_STOCK_MENU_RIGHT, stock_menu_right_icon, sizeof (stock_menu_right_icon) } -}; - -static void -icon_set_from_data (GtkIconSet *set, - const guint8 *icon_data, - const guint data_size, - GtkIconSize size, - gboolean fallback) -{ - GtkIconSource *source; - GdkPixbuf *pixbuf; - GError *err = NULL; - - source = gtk_icon_source_new (); - - gtk_icon_source_set_size (source, size); - gtk_icon_source_set_size_wildcarded (source, FALSE); - - pixbuf = gdk_pixbuf_new_from_inline (data_size, icon_data, FALSE, &err); - if (err) { - g_warning ("%s", err->message); - g_error_free (err); - err = NULL; - g_object_unref (source); - return; - } - - gtk_icon_source_set_pixbuf (source, pixbuf); - - g_object_unref (pixbuf); - - gtk_icon_set_add_source (set, source); - - if (fallback) { - gtk_icon_source_set_size_wildcarded (source, TRUE); - gtk_icon_set_add_source (set, source); - } - - gtk_icon_source_free (source); -} - -static void -add_icon (GtkIconFactory *factory, - const gchar *stock_id, - const guint8 *icon_data, - const guint data_size) -{ - GtkIconSet *set; - gboolean fallback = FALSE; - - set = gtk_icon_factory_lookup (factory, stock_id); - - if (!set) { - set = gtk_icon_set_new (); - gtk_icon_factory_add (factory, stock_id, set); - gtk_icon_set_unref (set); - - fallback = TRUE; - } - - icon_set_from_data (set, icon_data, data_size, GTK_ICON_SIZE_MENU, fallback); -} - -void -gdl_stock_init (void) -{ - static gboolean initialized = FALSE; - gint i; - - if (initialized) - return; - - gdl_stock_factory = gtk_icon_factory_new (); - - for (i = 0; i < G_N_ELEMENTS (gdl_icons); i++) { - add_icon (gdl_stock_factory, - gdl_icons[i].stock_id, - gdl_icons[i].icon_data, - gdl_icons[i].data_size); - } - - gtk_icon_factory_add_default (gdl_stock_factory); - - initialized = TRUE; -} diff --git a/src/libgdl/gdl-stock.h b/src/libgdl/gdl-stock.h deleted file mode 100644 index cb6f7abb9..000000000 --- a/src/libgdl/gdl-stock.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * gdl-stock.h - * - * Copyright (C) 2003 Jeroen Zwartepoorte - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __GDL_STOCK_H__ -#define __GDL_STOCK_H__ - -#include // G_BEGIN_DECLS - -G_BEGIN_DECLS - -#define GDL_STOCK_CLOSE "gdl-close" -#define GDL_STOCK_MENU_LEFT "gdl-menu-left" -#define GDL_STOCK_MENU_RIGHT "gdl-menu-right" - -void gdl_stock_init (void); - -G_END_DECLS - -#endif /* __GDL_STOCK_H__ */ diff --git a/src/libgdl/gdl-switcher.c b/src/libgdl/gdl-switcher.c index fea3218ae..65013e390 100644 --- a/src/libgdl/gdl-switcher.c +++ b/src/libgdl/gdl-switcher.c @@ -4,20 +4,22 @@ * Copyright (C) 2003 Ettore Perazzoli, * 2007 Naba Kumar * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 - * General Public License for more details. + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * + * * Copied and adapted from ESidebar.[ch] from evolution * * Authors: Ettore Perazzoli @@ -36,10 +38,6 @@ #include -#if HAVE_GNOME -#include -#endif - static void gdl_switcher_set_property (GObject *object, guint prop_id, const GValue *value, @@ -608,12 +606,6 @@ static void gdl_switcher_notify_cb (GObject *g_object, GParamSpec *pspec, GdlSwitcher *switcher) { - gboolean show_tabs; - (void)g_object; - (void)pspec; - g_return_if_fail (switcher != NULL && GDL_IS_SWITCHER (switcher)); - show_tabs = gtk_notebook_get_show_tabs (GTK_NOTEBOOK (switcher)); - gdl_switcher_set_show_buttons (switcher, !show_tabs); } static void @@ -879,179 +871,87 @@ gdl_switcher_insert_page (GdlSwitcher *switcher, GtkWidget *page, } static void -set_switcher_style_internal (GdlSwitcher *switcher, - GdlSwitcherStyle switcher_style ) +set_switcher_style_toolbar (GdlSwitcher *switcher, + GdlSwitcherStyle switcher_style) { GSList *p; - if (switcher_style == GDL_SWITCHER_STYLE_TABS && - switcher->priv->show == FALSE) + if (switcher_style == GDL_SWITCHER_STYLE_NONE + || switcher_style == GDL_SWITCHER_STYLE_TABS) return; - if (switcher_style == GDL_SWITCHER_STYLE_TABS) - { - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), TRUE); - return; - } - - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE); - + if (switcher_style == GDL_SWITCHER_STYLE_TOOLBAR) + switcher_style = GDL_SWITCHER_STYLE_BOTH; + if (switcher_style == INTERNAL_MODE (switcher)) return; - + + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE); + for (p = switcher->priv->buttons; p != NULL; p = p->next) { Button *button = p->data; gtk_container_remove (GTK_CONTAINER (button->hbox), button->arrow); + + if (gtk_widget_get_parent (button->icon)) + gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon); + if (gtk_widget_get_parent (button->label)) + gtk_container_remove (GTK_CONTAINER (button->hbox), button->label); + switch (switcher_style) { case GDL_SWITCHER_STYLE_TEXT: - gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon); - if (INTERNAL_MODE (switcher) - == GDL_SWITCHER_STYLE_ICON) { - gtk_box_pack_start (GTK_BOX (button->hbox), button->label, - TRUE, TRUE, 0); - gtk_widget_show (button->label); - } + gtk_box_pack_start (GTK_BOX (button->hbox), button->label, + TRUE, TRUE, 0); + gtk_widget_show (button->label); break; + case GDL_SWITCHER_STYLE_ICON: - gtk_container_remove(GTK_CONTAINER (button->hbox), button->label); - if (INTERNAL_MODE (switcher) - == GDL_SWITCHER_STYLE_TEXT) { - gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, - TRUE, TRUE, 0); - gtk_widget_show (button->icon); - } else - gtk_container_child_set (GTK_CONTAINER (button->hbox), - button->icon, "expand", TRUE, NULL); + gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, + TRUE, TRUE, 0); + gtk_widget_show (button->icon); break; - case GDL_SWITCHER_STYLE_BOTH: - if (INTERNAL_MODE (switcher) - == GDL_SWITCHER_STYLE_TEXT) { - gtk_container_remove (GTK_CONTAINER (button->hbox), - button->label); - gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, - FALSE, TRUE, 0); - gtk_widget_show (button->icon); - } else { - gtk_container_child_set (GTK_CONTAINER (button->hbox), - button->icon, "expand", FALSE, NULL); - } - gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, - TRUE, 0); + case GDL_SWITCHER_STYLE_BOTH: + gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, + FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (button->hbox), button->label, + TRUE, TRUE, 0); + gtk_widget_show (button->icon); gtk_widget_show (button->label); break; + default: break; } - gtk_box_pack_start (GTK_BOX (button->hbox), button->arrow, FALSE, - FALSE, 0); - } -} - -#if HAVE_GNOME -static GConfEnumStringPair toolbar_styles[] = { - { GDL_SWITCHER_STYLE_TEXT, "text" }, - { GDL_SWITCHER_STYLE_ICON, "icons" }, - { GDL_SWITCHER_STYLE_BOTH, "both" }, - { GDL_SWITCHER_STYLE_BOTH, "both-horiz" }, - { GDL_SWITCHER_STYLE_BOTH, "both_horiz" }, - { -1, NULL } -}; - -static void -style_changed_notify (GConfClient *gconf, guint id, GConfEntry *entry, - void *data) -{ - GdlSwitcher *switcher = data; - char *val; - int switcher_style; - - val = gconf_client_get_string (gconf, - "/desktop/gnome/interface/toolbar_style", - NULL); - if (val == NULL || !gconf_string_to_enum (toolbar_styles, val, - &switcher_style)) - switcher_style = GDL_SWITCHER_STYLE_BOTH; - g_free(val); - set_switcher_style_internal (GDL_SWITCHER (switcher), switcher_style); - switcher->priv->toolbar_style = switcher_style; + gtk_box_pack_start (GTK_BOX (button->hbox), button->arrow, + FALSE, FALSE, 0); + } - gtk_widget_queue_resize (GTK_WIDGET (switcher)); + gdl_switcher_set_show_buttons (switcher, TRUE); } static void gdl_switcher_set_style (GdlSwitcher *switcher, GdlSwitcherStyle switcher_style) { - GConfClient *gconf_client = gconf_client_get_default (); - - if (switcher_style == GDL_SWITCHER_STYLE_TABS && - switcher->priv->show == FALSE) - return; - - if (switcher->priv->switcher_style == switcher_style && - switcher->priv->show == TRUE) + if (switcher->priv->switcher_style == switcher_style) return; - if (switcher->priv->switcher_style == GDL_SWITCHER_STYLE_TOOLBAR) { - if (switcher->priv->style_changed_id) { - gconf_client_notify_remove (gconf_client, - switcher->priv->style_changed_id); - switcher->priv->style_changed_id = 0; - } + if (switcher_style == GDL_SWITCHER_STYLE_NONE) { + gdl_switcher_set_show_buttons (switcher, FALSE); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE); } - - if (switcher_style != GDL_SWITCHER_STYLE_TOOLBAR) { - set_switcher_style_internal (switcher, switcher_style); - - gtk_widget_queue_resize (GTK_WIDGET (switcher)); - } else { - /* This is a little bit tricky, toolbar style is more - * of a meta-style where the actual style is dictated by - * the gnome toolbar setting, so that is why we have - * the is_toolbar_style bool - it tracks the toolbar - * style while the switcher_style member is the actual look and - * feel */ - switcher->priv->style_changed_id = - gconf_client_notify_add (gconf_client, - "/desktop/gnome/interface/toolbar_style", - style_changed_notify, switcher, - NULL, NULL); - style_changed_notify (gconf_client, 0, NULL, switcher); + else if (switcher_style == GDL_SWITCHER_STYLE_TABS) { + gdl_switcher_set_show_buttons (switcher, FALSE); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), TRUE); } - - g_object_unref (gconf_client); - - if (switcher_style != GDL_SWITCHER_STYLE_TABS) - switcher->priv->switcher_style = switcher_style; -} - -#else /* HAVE_GNOME */ - -static void -gdl_switcher_set_style (GdlSwitcher *switcher, GdlSwitcherStyle switcher_style) -{ - if (switcher_style == GDL_SWITCHER_STYLE_TABS && - switcher->priv->show == FALSE) - return; - - if (switcher->priv->switcher_style == switcher_style && - switcher->priv->show == TRUE) - return; + else + set_switcher_style_toolbar (switcher, switcher_style); - set_switcher_style_internal (switcher, - ((switcher_style == - GDL_SWITCHER_STYLE_TOOLBAR)? - GDL_SWITCHER_STYLE_BOTH : switcher_style)); gtk_widget_queue_resize (GTK_WIDGET (switcher)); - - if (switcher_style != GDL_SWITCHER_STYLE_TABS) - switcher->priv->switcher_style = switcher_style; + switcher->priv->switcher_style = switcher_style; } -#endif /* HAVE_GNOME */ - static void gdl_switcher_set_show_buttons (GdlSwitcher *switcher, gboolean show) { diff --git a/src/libgdl/gdl-switcher.h b/src/libgdl/gdl-switcher.h index 9c33f8bbf..991f2da20 100644 --- a/src/libgdl/gdl-switcher.h +++ b/src/libgdl/gdl-switcher.h @@ -4,20 +4,22 @@ * Copyright (C) 2003 Ettore Perazzoli * 2007 Naba Kumar * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +* This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 - * General Public License for more details. + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * + * * Authors: Ettore Perazzoli * Naba Kumar */ @@ -39,14 +41,6 @@ typedef struct _GdlSwitcher GdlSwitcher; typedef struct _GdlSwitcherPrivate GdlSwitcherPrivate; typedef struct _GdlSwitcherClass GdlSwitcherClass; -typedef enum { - GDL_SWITCHER_STYLE_TEXT, - GDL_SWITCHER_STYLE_ICON, - GDL_SWITCHER_STYLE_BOTH, - GDL_SWITCHER_STYLE_TOOLBAR, - GDL_SWITCHER_STYLE_TABS -} GdlSwitcherStyle; - struct _GdlSwitcher { GtkNotebook parent; diff --git a/src/libgdl/gdl.h b/src/libgdl/gdl.h index e47dc310d..467b2b67e 100644 --- a/src/libgdl/gdl.h +++ b/src/libgdl/gdl.h @@ -1,23 +1,22 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * This file is part of the GNOME Devtools Libraries. - * + * * Copyright (C) 1999-2000 Dave Camp * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __GDL_H__ @@ -28,12 +27,8 @@ #include "libgdl/gdl-dock-master.h" #include "libgdl/gdl-dock.h" #include "libgdl/gdl-dock-item.h" +#include "libgdl/gdl-dock-item-grip.h" #include "libgdl/gdl-dock-layout.h" -#include "libgdl/gdl-dock-paned.h" -#include "libgdl/gdl-dock-notebook.h" -#include "libgdl/gdl-dock-tablabel.h" #include "libgdl/gdl-dock-bar.h" -#include "libgdl/gdl-combo-button.h" -#include "libgdl/gdl-switcher.h" #endif diff --git a/src/libgdl/test-dock.c b/src/libgdl/test-dock.c index 1e9c80111..abaecf703 100644 --- a/src/libgdl/test-dock.c +++ b/src/libgdl/test-dock.c @@ -81,6 +81,9 @@ create_styles_item (GtkWidget *dock) group = create_style_button (dock, vbox1, group, GDL_SWITCHER_STYLE_TABS, "Notebook tabs"); + group = create_style_button (dock, vbox1, group, + GDL_SWITCHER_STYLE_NONE, + "None of the above"); return vbox1; } -- cgit v1.2.3 From df7bda1a8b9d4a1c6f0fd4b82cdeb614eb1ea8d2 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 10 Jul 2011 00:13:05 -0700 Subject: Refactored to abstract lcms usage more. Added CMSSystem class. (bzr r10437) --- src/CMakeLists.txt | 2 +- src/Makefile_insert | 3 +- src/cms-system.h | 60 ++++++++++++++++++++++++++++++++++ src/color-profile-fns.h | 60 ---------------------------------- src/color-profile.cpp | 31 +++++++++++------- src/color-profile.h | 1 + src/display/sp-canvas.cpp | 10 +++--- src/sp-image.cpp | 10 +++--- src/svg/svg-color.cpp | 17 ++++------ src/ui/dialog/inkscape-preferences.cpp | 15 +++++---- src/widgets/desktop-widget.cpp | 8 ++--- src/widgets/sp-color-icc-selector.cpp | 10 ++++-- src/widgets/sp-color-notebook.cpp | 10 +++--- 13 files changed, 124 insertions(+), 113 deletions(-) create mode 100644 src/cms-system.h delete mode 100644 src/color-profile-fns.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 11a307037..038e7bb73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -307,7 +307,7 @@ set(inkscape_SRC box3d-side.h box3d.h cms-color-types.h - color-profile-fns.h + cms-system.h color-profile-cms-fns.h color-profile-test.h color-profile.h diff --git a/src/Makefile_insert b/src/Makefile_insert index d4f96fc87..2cb689740 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -13,9 +13,10 @@ ink_common_sources += \ box3d-side.cpp box3d-side.h \ brokenimage.xpm \ cms-color-types.h \ + cms-system.h \ color.cpp color.h \ color-profile.cpp color-profile.h \ - color-profile-fns.h color-profile-cms-fns.h \ + color-profile-cms-fns.h \ color-rgba.h \ common-context.cpp common-context.h \ composite-undo-stack-observer.cpp \ diff --git a/src/cms-system.h b/src/cms-system.h new file mode 100644 index 000000000..1f75f8619 --- /dev/null +++ b/src/cms-system.h @@ -0,0 +1,60 @@ +#ifndef SEEN_COLOR_PROFILE_FNS_H +#define SEEN_COLOR_PROFILE_FNS_H + +/** \file + * Macros and fn declarations related to linear gradients. + */ + +#include +#include +#include +#include +#include "cms-color-types.h" + +class SPDocument; + +namespace Inkscape { + +class ColorProfile; + +class CMSSystem { +public: + static cmsHPROFILE getHandle( SPDocument* document, guint* intent, gchar const* name ); + + static cmsHTRANSFORM getDisplayTransform(); + + static Glib::ustring getDisplayId( int screen, int monitor ); + + static Glib::ustring setDisplayPer( gpointer buf, guint bufLen, int screen, int monitor ); + + static cmsHTRANSFORM getDisplayPer( Glib::ustring const& id ); + + static std::vector getDisplayNames(); + + static std::vector getSoftproofNames(); + + static Glib::ustring getPathForProfile(Glib::ustring const& name); + + static void doTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size); + + static bool isPrintColorSpace(ColorProfile const *profile); + + static gint getChannelCount(ColorProfile const *profile); +}; + + +} // namespace Inkscape + + +#endif // !SEEN_COLOR_PROFILE_FNS_H + +/* + 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/color-profile-fns.h b/src/color-profile-fns.h deleted file mode 100644 index 0588ce89e..000000000 --- a/src/color-profile-fns.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef SEEN_COLOR_PROFILE_FNS_H -#define SEEN_COLOR_PROFILE_FNS_H - -/** \file - * Macros and fn declarations related to linear gradients. - */ - -#include -#include -#if ENABLE_LCMS -#include -#include -#endif // ENABLE_LCMS -#include "cms-color-types.h" - -class SPDocument; - -namespace Inkscape { - -namespace XML { -class Node; -} // namespace XML - -class ColorProfile; - -#if ENABLE_LCMS - -cmsHPROFILE colorprofile_get_handle( SPDocument* document, guint* intent, gchar const* name ); -cmsHTRANSFORM colorprofile_get_display_transform(); - -Glib::ustring colorprofile_get_display_id( int screen, int monitor ); -Glib::ustring colorprofile_set_display_per( gpointer buf, guint bufLen, int screen, int monitor ); -cmsHTRANSFORM colorprofile_get_display_per( Glib::ustring const& id ); - -std::vector colorprofile_get_display_names(); -std::vector colorprofile_get_softproof_names(); - -Glib::ustring get_path_for_profile(Glib::ustring const& name); - -void colorprofile_cmsDoTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size); - -bool colorprofile_isPrintColorSpace(ColorProfile const *profile); - -#endif // ENABLE_LCMS - -} // namespace Inkscape - - -#endif // !SEEN_COLOR_PROFILE_FNS_H - -/* - 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/color-profile.cpp b/src/color-profile.cpp index 4bc37fdf8..f858f7f70 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -31,7 +31,7 @@ #include "xml/repr.h" #include "color.h" #include "color-profile.h" -#include "color-profile-fns.h" +#include "cms-system.h" #include "color-profile-cms-fns.h" #include "attributes.h" #include "inkscape.h" @@ -552,7 +552,7 @@ static SPObject* bruteFind( SPDocument* document, gchar const* name ) return result; } -cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* intent, gchar const* name ) +cmsHPROFILE Inkscape::CMSSystem::getHandle( SPDocument* document, guint* intent, gchar const* name ) { cmsHPROFILE prof = 0; @@ -652,7 +652,7 @@ ProfileInfo::ProfileInfo( cmsHPROFILE prof, Glib::ustring const & path ) static std::vector knownProfiles; -std::vector Inkscape::colorprofile_get_display_names() +std::vector Inkscape::CMSSystem::getDisplayNames() { loadProfiles(); std::vector result; @@ -666,7 +666,7 @@ std::vector Inkscape::colorprofile_get_display_names() return result; } -std::vector Inkscape::colorprofile_get_softproof_names() +std::vector Inkscape::CMSSystem::getSoftproofNames() { loadProfiles(); std::vector result; @@ -680,7 +680,7 @@ std::vector Inkscape::colorprofile_get_softproof_names() return result; } -Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) +Glib::ustring Inkscape::CMSSystem::getPathForProfile(Glib::ustring const& name) { loadProfiles(); Glib::ustring result; @@ -695,12 +695,12 @@ Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) return result; } -void Inkscape::colorprofile_cmsDoTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size) +void Inkscape::CMSSystem::doTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size) { cmsDoTransform(transform, inBuf, outBuf, size); } -bool Inkscape::colorprofile_isPrintColorSpace(ColorProfile const *profile) +bool Inkscape::CMSSystem::isPrintColorSpace(ColorProfile const *profile) { bool isPrint = false; if ( profile ) { @@ -710,6 +710,15 @@ bool Inkscape::colorprofile_isPrintColorSpace(ColorProfile const *profile) return isPrint; } +gint Inkscape::CMSSystem::getChannelCount(ColorProfile const *profile) +{ + gint count = 0; + if ( profile ) { + count = _cmsChannelsOf( asICColorSpaceSig(profile->getColorSpace()) ); + } + return count; +} + #endif // ENABLE_LCMS std::vector ColorProfile::getBaseProfileDirs() { @@ -1077,7 +1086,7 @@ cmsHPROFILE getProofProfileHandle() static void free_transforms(); -cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() +cmsHTRANSFORM Inkscape::CMSSystem::getDisplayTransform() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); @@ -1188,7 +1197,7 @@ void free_transforms() } } -Glib::ustring Inkscape::colorprofile_get_display_id( int screen, int monitor ) +Glib::ustring Inkscape::CMSSystem::getDisplayId( int screen, int monitor ) { Glib::ustring id; @@ -1203,7 +1212,7 @@ Glib::ustring Inkscape::colorprofile_get_display_id( int screen, int monitor ) return id; } -Glib::ustring Inkscape::colorprofile_set_display_per( gpointer buf, guint bufLen, int screen, int monitor ) +Glib::ustring Inkscape::CMSSystem::setDisplayPer( gpointer buf, guint bufLen, int screen, int monitor ) { Glib::ustring id; @@ -1236,7 +1245,7 @@ Glib::ustring Inkscape::colorprofile_set_display_per( gpointer buf, guint bufLen return id; } -cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) +cmsHTRANSFORM Inkscape::CMSSystem::getDisplayPer( Glib::ustring const& id ) { cmsHTRANSFORM result = 0; if ( id.empty() ) { diff --git a/src/color-profile.h b/src/color-profile.h index 1b06b6a78..a9724defc 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -33,6 +33,7 @@ struct ColorProfileClass { /** Color Profile. */ struct ColorProfile : public SPObject { friend cmsHPROFILE colorprofile_get_handle( SPDocument*, guint*, gchar const* ); + friend class CMSSystem; static GType getType(); static void classInit( ColorProfileClass *klass ); diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index ea39d3435..37998437d 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -30,9 +30,7 @@ #include "preferences.h" #include "inkscape.h" #include "sodipodi-ctrlrect.h" -#if ENABLE_LCMS -#include "color-profile-fns.h" -#endif // ENABLE_LCMS +#include "cms-system.h" #include "display/rendermode.h" #include "display/cairo-utils.h" #include "debug/gdk-event-latency-tracker.h" @@ -1672,9 +1670,9 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); if ( fromDisplay ) { - transf = Inkscape::colorprofile_get_display_per( canvas->cms_key ? *(canvas->cms_key) : "" ); + transf = Inkscape::CMSSystem::getDisplayPer( canvas->cms_key ? *(canvas->cms_key) : "" ); } else { - transf = Inkscape::colorprofile_get_display_transform(); + transf = Inkscape::CMSSystem::getDisplayTransform(); } if (transf) { @@ -1683,7 +1681,7 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int int stride = cairo_image_surface_get_stride(imgs); for (int i=0; i //#define DEBUG_LCMS #ifdef DEBUG_LCMS @@ -849,9 +849,9 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) DEBUG_MESSAGE( lcmsFive, "in 's sp_image_update. About to call colorprofile_get_handle()" ); #endif // DEBUG_LCMS guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; - cmsHPROFILE prof = Inkscape::colorprofile_get_handle( object->document, - &profIntent, - image->color_profile ); + cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( object->document, + &profIntent, + image->color_profile ); if ( prof ) { icProfileClassSignature profileClass = cmsGetDeviceClass( prof ); if ( profileClass != icSigNamedColorClass ) { diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index 3605bde55..9293564d5 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -1,5 +1,3 @@ -#define __SP_SVG_COLOR_C__ - /** * \file * Reading \& writing of SVG/CSS colors. @@ -37,17 +35,16 @@ #include "svg-icc-color.h" #if ENABLE_LCMS -#include #include "color.h" #include "color-profile.h" #include "document.h" #include "inkscape.h" #include "profile-manager.h" -#include "color-profile-cms-fns.h" #endif // ENABLE_LCMS -#include "color-profile-fns.h" +#include "cms-system.h" using std::sprintf; +using Inkscape::CMSSystem; struct SPSVGColor { unsigned long rgb; @@ -467,7 +464,7 @@ sp_svg_create_color_hash() #if ENABLE_LCMS //helper function borrowed from src/widgets/sp-color-icc-selector.cpp: -void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guint const*& scalies ); +void getThings( Inkscape::ColorProfile *prof, gchar const**& namers, gchar const**& tippies, guint const*& scalies ); void icc_color_to_sRGB(SVGICCColor* icc, guchar* r, guchar* g, guchar* b){ guchar color_out[4]; @@ -481,18 +478,18 @@ g_message("profile name: %s", icc->colorProfile.c_str()); gchar const** names = 0; gchar const** tips = 0; guint const* scales = 0; - getThings( asICColorSpaceSig(prof->getColorSpace()), names, tips, scales ); + getThings( prof, names, tips, scales ); - guint count = _cmsChannelsOf( asICColorSpaceSig(prof->getColorSpace()) ); + gint count = CMSSystem::getChannelCount( prof ); if (count > 4) { count = 4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?) } - for (guint i=0;icolors[i])*256.0) * (gdouble)scales[i]); g_message("input[%d]: %d",i, color_in[i]); } - cmsDoTransform( trans, color_in, color_out, 1 ); + CMSSystem::doTransform( trans, color_in, color_out, 1 ); g_message("transform to sRGB done"); } *r = color_out[0]; diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index aa3c18aaa..d11ffd565 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -41,7 +41,7 @@ #include "ui/widget/spinbutton.h" #include "display/nr-filter-gaussian.h" #include "display/nr-filter-types.h" -#include "color-profile-fns.h" +#include "cms-system.h" #include "color-profile.h" #include "display/canvas-grid.h" #include "path-prefix.h" @@ -62,6 +62,7 @@ using Inkscape::UI::Widget::PrefCheckButton; using Inkscape::UI::Widget::PrefRadioButton; using Inkscape::UI::Widget::PrefSpinButton; using Inkscape::UI::Widget::StyleSwatch; +using Inkscape::CMSSystem; InkscapePreferences::InkscapePreferences() @@ -858,7 +859,7 @@ static void profileComboChanged( Gtk::ComboBoxText* combo ) } else { Glib::ustring active = combo->get_active_text(); - Glib::ustring path = get_path_for_profile(active); + Glib::ustring path = CMSSystem::getPathForProfile(active); if ( !path.empty() ) { prefs->setString("/options/displayprofile/uri", path); } @@ -868,7 +869,7 @@ static void profileComboChanged( Gtk::ComboBoxText* combo ) static void proofComboChanged( Gtk::ComboBoxText* combo ) { Glib::ustring active = combo->get_active_text(); - Glib::ustring path = get_path_for_profile(active); + Glib::ustring path = CMSSystem::getPathForProfile(active); if ( !path.empty() ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -975,7 +976,7 @@ void InkscapePreferences::initPageCMS() #if ENABLE_LCMS { - std::vector names = ::Inkscape::colorprofile_get_display_names(); + std::vector names = ::Inkscape::CMSSystem::getDisplayNames(); Glib::ustring current = prefs->getString( "/options/displayprofile/uri" ); gint index = 0; @@ -983,7 +984,7 @@ void InkscapePreferences::initPageCMS() index++; for ( std::vector::iterator it = names.begin(); it != names.end(); ++it ) { _cms_display_profile.append_text( *it ); - Glib::ustring path = get_path_for_profile(*it); + Glib::ustring path = CMSSystem::getPathForProfile(*it); if ( !path.empty() && path == current ) { _cms_display_profile.set_active(index); } @@ -993,12 +994,12 @@ void InkscapePreferences::initPageCMS() _cms_display_profile.set_active(0); } - names = ::Inkscape::colorprofile_get_softproof_names(); + names = ::Inkscape::CMSSystem::getSoftproofNames(); current = prefs->getString("/options/softproof/uri"); index = 0; for ( std::vector::iterator it = names.begin(); it != names.end(); ++it ) { _cms_proof_profile.append_text( *it ); - Glib::ustring path = get_path_for_profile(*it); + Glib::ustring path = CMSSystem::getPathForProfile(*it); if ( !path.empty() && path == current ) { _cms_proof_profile.set_active(index); } diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 52008625a..34c3ab75a 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -28,7 +28,7 @@ #include #include "box3d-context.h" -#include "color-profile-fns.h" +#include "cms-system.h" #include "conn-avoid-ref.h" #include "desktop-events.h" #include "desktop-handles.h" @@ -193,7 +193,7 @@ void CMSPrefWatcher::hook(EgeColorProfTracker */*tracker*/, gint screen, gint mo guint len = 0; ege_color_prof_tracker_get_profile_for( screen, monitor, reinterpret_cast(&buf), &len ); - Glib::ustring id = Inkscape::colorprofile_set_display_per( buf, len, screen, monitor ); + Glib::ustring id = Inkscape::CMSSystem::setDisplayPer( buf, len, screen, monitor ); #endif // ENABLE_LCMS } @@ -540,7 +540,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) #if ENABLE_LCMS bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); if ( fromDisplay ) { - Glib::ustring id = Inkscape::colorprofile_get_display_id( 0, 0 ); + Glib::ustring id = Inkscape::CMSSystem::getDisplayId( 0, 0 ); bool enabled = false; if ( dtw->canvas->cms_key ) { @@ -805,7 +805,7 @@ void sp_dtw_color_profile_event(EgeColorProfTracker */*tracker*/, SPDesktopWidge GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(dtw)); gint screenNum = gdk_screen_get_number(screen); gint monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_toplevel(GTK_WIDGET(dtw))->window); - Glib::ustring id = Inkscape::colorprofile_get_display_id( screenNum, monitor ); + Glib::ustring id = Inkscape::CMSSystem::getDisplayId( screenNum, monitor ); bool enabled = false; if ( dtw->canvas->cms_key ) { *(dtw->canvas->cms_key) = id; diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index 9e5291cc4..888cc2629 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -15,9 +15,9 @@ #define noDEBUG_LCMS #if ENABLE_LCMS -#include "color-profile-fns.h" -#include "color-profile-cms-fns.h" #include "color-profile.h" +#include "cms-system.h" +#include "color-profile-cms-fns.h" #ifdef DEBUG_LCMS #include "preferences.h" @@ -259,6 +259,12 @@ void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guin tippies = tips[index]; scalies = scales[index]; } + + +void getThings( Inkscape::ColorProfile *prof, gchar const**& namers, gchar const**& tippies, guint const*& scalies ) { + getThings( asICColorSpaceSig(prof->getColorSpace()), namers, tippies, scalies ); +} + #endif // ENABLE_LCMS diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 546f7838b..1324e0b16 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -36,11 +36,9 @@ #include "../document.h" #include "../profile-manager.h" #include "color-profile.h" -#include "color-profile-fns.h" -#if ENABLE_LCMS -//#include "lcms.h" -//#include "color-profile-cms-fns.h" -#endif // ENABLE_LCMS +#include "cms-system.h" + +using Inkscape::CMSSystem; struct SPColorNotebookTracker { const gchar* name; @@ -540,7 +538,7 @@ void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) gtk_widget_set_sensitive (_box_toomuchink, false); if (color.icc){ Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); - if ( prof && colorprofile_isPrintColorSpace(prof) ) { + if ( prof && CMSSystem::isPrintColorSpace(prof) ) { gtk_widget_show(GTK_WIDGET(_box_toomuchink)); double ink_sum = 0; for (unsigned int i=0; icolors.size(); i++){ -- cgit v1.2.3 From 61b9edb0a77f71d669a621ef2c58f1d1ea6f463d Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 10 Jul 2011 01:48:48 -0700 Subject: Update for non-LCMS builds. (bzr r10438) --- src/color-profile.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/color-profile.cpp b/src/color-profile.cpp index f858f7f70..41c9d4c63 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -131,6 +131,7 @@ public: namespace Inkscape { +#ifdef ENABLE_LCMS icColorSpaceSignature asICColorSpaceSig(ColorSpaceSig const & sig) { return ColorSpaceSigWrapper(sig); @@ -140,6 +141,7 @@ icProfileClassSignature asICColorProfileClassSig(ColorProfileClassSig const & si { return ColorProfileClassSigWrapper(sig); } +#endif // ENABLE_LCMS } // namespace Inkscape -- cgit v1.2.3 From 12f47cac056804dd53cc334b27c7b1b0f55ab5b6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 10 Jul 2011 11:01:19 +0200 Subject: Allow em and ex as units on font-size. (bzr r10437.1.1) --- src/libnrtype/Layout-TNG-Input.cpp | 2 +- src/style.cpp | 133 +++++++++++++++++++++---------------- src/style.h | 11 +-- 3 files changed, 83 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 45bc0c89b..c5ea3969d 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -135,7 +135,7 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const if (this_style->font_size.set && !this_style->font_size.inherit) { switch (this_style->font_size.type) { case SP_FONT_SIZE_LITERAL: { - switch(this_style->font_size.value) { // these multipliers are straight out of the CSS spec + switch(this_style->font_size.literal) { // these multipliers are straight out of the CSS spec case SP_CSS_FONT_SIZE_XX_SMALL: return medium_font_size * inherit_multiplier * (3.0/5.0); case SP_CSS_FONT_SIZE_X_SMALL: return medium_font_size * inherit_multiplier * (3.0/4.0); case SP_CSS_FONT_SIZE_SMALL: return medium_font_size * inherit_multiplier * (8.0/9.0); diff --git a/src/style.cpp b/src/style.cpp index bb25a5f46..699b087dd 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1343,11 +1343,11 @@ sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &pare * fixme: SVG and CSS do not specify clearly, whether we should use * user or screen coordinates (Lauris) */ - if (child.value < SP_CSS_FONT_SIZE_SMALLER) { - child.computed = font_size_table[child.value]; - } else if (child.value == SP_CSS_FONT_SIZE_SMALLER) { + if (child.literal < SP_CSS_FONT_SIZE_SMALLER) { + child.computed = font_size_table[child.literal]; + } else if (child.literal == SP_CSS_FONT_SIZE_SMALLER) { child.computed = parent.computed / 1.2; - } else if (child.value == SP_CSS_FONT_SIZE_LARGER) { + } else if (child.literal == SP_CSS_FONT_SIZE_LARGER) { child.computed = parent.computed * 1.2; } else { /* Illegal value */ @@ -1355,7 +1355,21 @@ sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &pare } else if (child.type == SP_FONT_SIZE_PERCENTAGE) { /* Unlike most other lengths, percentage for font size is relative to parent computed value * rather than viewport. */ - child.computed = parent.computed * SP_F8_16_TO_FLOAT(child.value); + child.computed = parent.computed * child.value; + } else if (child.type == SP_FONT_SIZE_LENGTH) { + switch (child.unit) { + case SP_CSS_UNIT_EM: + /* Relative to parent font size */ + child.computed = parent.computed * child.value; + break; + case SP_CSS_UNIT_EX: + /* Relative to parent font size */ + child.computed = parent.computed * child.value * 0.5; /* Hack */ + break; + default: + /* No change */ + break; + } } } @@ -1790,7 +1804,7 @@ get_relative_font_size_frac(SPIFontSize const &font_size) { switch (font_size.type) { case SP_FONT_SIZE_LITERAL: { - switch (font_size.value) { + switch (font_size.literal) { case SP_CSS_FONT_SIZE_SMALLER: return 5.0 / 6.0; @@ -1803,10 +1817,20 @@ get_relative_font_size_frac(SPIFontSize const &font_size) } case SP_FONT_SIZE_PERCENTAGE: - return SP_F8_16_TO_FLOAT(font_size.value); + return font_size.value; + + case SP_FONT_SIZE_LENGTH: { + switch (font_size.unit ) { + case SP_CSS_UNIT_EM: + return font_size.value; + + case SP_CSS_UNIT_EX: + return font_size.value * 0.5; - case SP_FONT_SIZE_LENGTH: - g_assert_not_reached(); + default: + g_assert_not_reached(); + } + } } g_assert_not_reached(); } @@ -1853,20 +1877,29 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare { /* font-size. Note that we update the computed font-size of style, to assist in em calculations later in this function. */ + if (parent->font_size.set && !parent->font_size.inherit) { + /* Parent has defined font-size */ + if (!style->font_size.set || style->font_size.inherit) { /* font_size inherits the computed value, so we can use the parent value * verbatim. */ style->font_size = parent->font_size; - } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH ) { + + } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH && + style->font_size.unit != SP_CSS_UNIT_EM && + style->font_size.unit != SP_CSS_UNIT_EX ) { + /* Child already has absolute size (stored in computed value), so do nothing. */ + } else if ( style->font_size.type == SP_FONT_SIZE_LITERAL - && style->font_size.value < SP_CSS_FONT_SIZE_SMALLER ) { + && style->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) { /* Child already has absolute size, but we ensure that the computed value is up-to-date. */ - unsigned const ix = style->font_size.value; + unsigned const ix = style->font_size.literal; g_assert(ix < G_N_ELEMENTS(font_size_table)); style->font_size.computed = font_size_table[ix]; + } else { /* Child has relative size. */ double const child_frac(get_relative_font_size_frac(style->font_size)); @@ -1875,17 +1908,26 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare style->font_size.computed = parent->font_size.computed * child_frac; if ( ( parent->font_size.type == SP_FONT_SIZE_LITERAL - && parent->font_size.value < SP_CSS_FONT_SIZE_SMALLER ) - || parent->font_size.type == SP_FONT_SIZE_LENGTH ) - { + && parent->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) || + ( parent->font_size.type == SP_FONT_SIZE_LENGTH && + parent->font_size.unit != SP_CSS_UNIT_EM && + parent->font_size.unit != SP_CSS_UNIT_EX ) ) { + /* Absolute value. */ style->font_size.type = SP_FONT_SIZE_LENGTH; - /* .value is unused for SP_FONT_SIZE_LENGTH. */ + /* .value is unused for non ex/em SP_FONT_SIZE_LENGTH. */ + } else { /* Relative value. */ + double const parent_frac(get_relative_font_size_frac(parent->font_size)); - style->font_size.type = SP_FONT_SIZE_PERCENTAGE; - style->font_size.value = SP_F8_16_FROM_FLOAT(parent_frac * child_frac); + if( style->font_size.type == SP_FONT_SIZE_LENGTH ) { + /* Value in terms of ex/em */ + style->font_size.value *= parent_frac; + } else { + style->font_size.value = parent_frac * child_frac; + style->font_size.type = SP_FONT_SIZE_PERCENTAGE; + } } } } @@ -2677,7 +2719,7 @@ sp_style_clear(SPStyle *style) style->font_size.set = FALSE; style->font_size.type = SP_FONT_SIZE_LITERAL; - style->font_size.value = SP_CSS_FONT_SIZE_MEDIUM; + style->font_size.literal = SP_CSS_FONT_SIZE_MEDIUM; style->font_size.computed = 12.0; style->font_style.set = FALSE; style->font_style.value = style->font_style.computed = SP_CSS_FONT_STYLE_NORMAL; @@ -3008,6 +3050,7 @@ sp_style_read_ienum(SPIEnum *val, gchar const *str, SPStyleEnum const *dict, } } } + return; } @@ -3284,52 +3327,26 @@ sp_style_read_ifontsize(SPIFontSize *val, gchar const *str) val->set = TRUE; val->inherit = FALSE; val->type = SP_FONT_SIZE_LITERAL; - val->value = enum_font_size[i].value; + val->literal = enum_font_size[i].value; return; } } /* Invalid */ return; } else { - gdouble value; - gchar *e; - /* fixme: Move this to standard place (Lauris) */ - value = g_ascii_strtod(str, &e); - if ((gchar const *) e != str) { - if (!*e) { - /* Userspace */ - } else if (!strcmp(e, "px")) { - /* Userspace */ - } else if (!strcmp(e, "pt")) { - /* Userspace * DEVICESCALE */ - value *= PX_PER_PT; - } else if (!strcmp(e, "pc")) { - /* 12pt */ - value *= PX_PER_PT * 12.0; - } else if (!strcmp(e, "mm")) { - value *= PX_PER_MM; - } else if (!strcmp(e, "cm")) { - value *= PX_PER_CM; - } else if (!strcmp(e, "in")) { - value *= PX_PER_IN; - } else if (!strcmp(e, "%")) { - /* Percentage */ - val->set = TRUE; - val->inherit = FALSE; - val->type = SP_FONT_SIZE_PERCENTAGE; - val->value = SP_F8_16_FROM_FLOAT(value / 100.0); - return; - } else { - /* Invalid */ - return; - } - /* Length */ - val->set = TRUE; - val->inherit = FALSE; + SPILength length; + sp_style_read_ilength(&length, str); + val->set = length.set; + val->inherit = length.inherit; + val->unit = length.unit; + val->value = length.value; + val->computed = length.computed; + if( val->unit == SP_CSS_UNIT_PERCENT ) { + val->type = SP_FONT_SIZE_PERCENTAGE; + } else { val->type = SP_FONT_SIZE_LENGTH; - val->computed = value; - return; } + return; } } @@ -3935,7 +3952,7 @@ sp_style_write_ifontsize(gchar *p, gint const len, gchar const *key, return g_strlcpy(p, os.str().c_str(), len); } else if (val->type == SP_FONT_SIZE_PERCENTAGE) { Inkscape::CSSOStringStream os; - os << key << ":" << (SP_F8_16_TO_FLOAT(val->value) * 100.0) << "%;"; + os << key << ":" << (val->value * 100.0) << "%;"; return g_strlcpy(p, os.str().c_str(), len); } } diff --git a/src/style.h b/src/style.h index a12db388a..d82a0dd5e 100644 --- a/src/style.h +++ b/src/style.h @@ -206,21 +206,24 @@ enum { SP_BASELINE_SHIFT_PERCENTAGE }; -#define SP_FONT_SIZE ((1 << 24) - 1) - +/* +Not used anymore, originally for SPIFontSize #define SP_F8_16_TO_FLOAT(v) ((gdouble) (v) / (1 << 16)) #define SP_F8_16_FROM_FLOAT(v) ((int) ((v) * ((1 << 16) + 0.9999))) +*/ #define SP_STYLE_FLAG_IFSET (1 << 0) #define SP_STYLE_FLAG_IFDIFF (1 << 1) #define SP_STYLE_FLAG_ALWAYS (1 << 2) -/// Fontsize type internal to SPStyle. +/// Fontsize type internal to SPStyle (also used by libnrtype/Layout-TNG-Input.cpp). struct SPIFontSize { unsigned set : 1; unsigned inherit : 1; unsigned type : 2; - unsigned value : 24; + unsigned unit : 4; + unsigned literal: 4; + float value; float computed; }; -- cgit v1.2.3 From 7b0a658e33d7b7a7f0313bef2fdaf8ed32af1c7e Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 10 Jul 2011 18:54:41 +0100 Subject: Remove --export-dynamic linker flag (bzr r10430.1.1) --- src/Makefile.am | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 7925dcd7e..5a50eb36f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -208,11 +208,7 @@ libinkscape_a_SOURCES = $(ink_common_sources) inkscape_SOURCES += main.cpp $(win32_sources) inkscape_LDADD = $(all_libs) -if EXPORT_DYNAMIC_DIRECT -inkscape_LDFLAGS = --export-dynamic $(kdeldflags) $(mwindows) -else -inkscape_LDFLAGS = -Wl,--export-dynamic $(kdeldflags) $(mwindows) -endif +inkscape_LDFLAGS = $(kdeldflags) $(mwindows) inkview_SOURCES += inkview.cpp $(win32_sources) inkview_LDADD = $(all_libs) -- cgit v1.2.3 From 79cb3f5ae387630b9f696c17d99de984c00a43e3 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 10 Jul 2011 20:13:40 +0200 Subject: i18n. Adding new GCode Tool extensions (see Bug #731177). i18n. Fix typo in the ABC custom predefined filters (see Bug #806055). Translations. inkscape.pot and fr.po update. (bzr r10437.1.3) --- src/extension/internal/filter/abc.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/extension/internal/filter/abc.h b/src/extension/internal/filter/abc.h index 8368d3f3b..cf2bc8927 100755 --- a/src/extension/internal/filter/abc.h +++ b/src/extension/internal/filter/abc.h @@ -218,7 +218,7 @@ ColorShift::get_filter_text (Inkscape::Extension::Extension * ext) * Smoothness (0.->10., default 6.) -> blur (stdDeviation) * Elevation (0->360, default 25) -> feDistantLight (elevation) * Azimuth (0->360, default 235) -> feDistantLight (azimuth) - * Lightning color (guint, default -1 [white]) -> diffuse (lighting-color) + * Lighting color (guint, default -1 [white]) -> diffuse (lighting-color) */ class DiffuseLight : public Inkscape::Extension::Internal::Filter::Filter { @@ -237,7 +237,7 @@ public: "6\n" "25\n" "235\n" - "-1\n" + "-1\n" "\n" "all\n" "\n" @@ -355,7 +355,7 @@ Feather::get_filter_text (Inkscape::Extension::Extension * ext) * Brightness (0.0->5., default .9) -> specular (specularConstant) * Elevation (0->360, default 60) -> feDistantLight (elevation) * Azimuth (0->360, default 225) -> feDistantLight (azimuth) - * Lightning color (guint, default -1 [white]) -> specular (lighting-color) + * Lighting color (guint, default -1 [white]) -> specular (lighting-color) */ class MatteJelly : public Inkscape::Extension::Internal::Filter::Filter { @@ -375,7 +375,7 @@ public: "0.9\n" "60\n" "225\n" - "-1\n" + "-1\n" "\n" "all\n" "\n" @@ -795,7 +795,7 @@ Silhouette::get_filter_text (Inkscape::Extension::Extension * ext) * Brightness (0.0->5., default 1.) -> specular (specularConstant) * Elevation (0->360, default 45) -> feDistantLight (elevation) * Azimuth (0->360, default 235) -> feDistantLight (azimuth) - * Lightning color (guint, default -1 [white]) -> specular (lighting-color) + * Lighting color (guint, default -1 [white]) -> specular (lighting-color) */ class SpecularLight : public Inkscape::Extension::Internal::Filter::Filter { @@ -815,7 +815,7 @@ public: "1\n" "45\n" "235\n" - "-1\n" + "-1\n" "\n" "all\n" "\n" -- cgit v1.2.3 From dd5da66df059871c546f4d09b9d2eb92e71b74b7 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sun, 10 Jul 2011 21:40:56 +0200 Subject: Selector's toolbar: changing the dimensions of the visual bounding box of selection of multiple objects having different stroke widths has been fixed (bug #212768, #190557, ...) Fixed bugs: - https://launchpad.net/bugs/212768 - https://launchpad.net/bugs/190557 (bzr r10437.1.5) --- src/seltrans.cpp | 4 +- src/snap-preferences.cpp | 2 +- src/snap-preferences.h | 2 +- src/sp-item-transform.cpp | 273 ++++++++++++++++++++++++++++++++++------- src/sp-item-transform.h | 3 +- src/widgets/select-toolbar.cpp | 42 ++++--- 6 files changed, 260 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/seltrans.cpp b/src/seltrans.cpp index f95a204a9..f6a702ed9 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1566,7 +1566,7 @@ Geom::Point Inkscape::SelTrans::_getGeomHandlePos(Geom::Point const &visual_hand // Calculate the absolute affine while taking into account the scaling of the stroke width Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - Geom::Affine abs_affine = get_scale_transform_with_stroke (*_bbox, _strokewidth, transform_stroke, + Geom::Affine abs_affine = get_scale_transform_with_uniform_stroke (*_bbox, _strokewidth, transform_stroke, new_bbox.min()[Geom::X], new_bbox.min()[Geom::Y], new_bbox.max()[Geom::X], new_bbox.max()[Geom::Y]); // Calculate the scaled geometrical bbox @@ -1613,7 +1613,7 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_ strokewidth = _strokewidth; } - _absolute_affine = get_scale_transform_with_stroke (*_approximate_bbox, strokewidth, transform_stroke, + _absolute_affine = get_scale_transform_with_uniform_stroke (*_approximate_bbox, strokewidth, transform_stroke, new_bbox_min[Geom::X], new_bbox_min[Geom::Y], new_bbox_max[Geom::X], new_bbox_max[Geom::Y]); // return the new handle position diff --git a/src/snap-preferences.cpp b/src/snap-preferences.cpp index 4859b111e..b98726a86 100644 --- a/src/snap-preferences.cpp +++ b/src/snap-preferences.cpp @@ -5,7 +5,7 @@ * Authors: * Diederik van Lierop * - * Copyright (C) 2008 Authors + * Copyright (C) 2008 - 2011 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ diff --git a/src/snap-preferences.h b/src/snap-preferences.h index 8e8ebc9cf..35d05c40e 100644 --- a/src/snap-preferences.h +++ b/src/snap-preferences.h @@ -8,7 +8,7 @@ * Authors: * Diederik van Lierop * - * Copyright (C) 2008 - 2010 Authors + * Copyright (C) 2008 - 2011 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index ae55a5c50..45d965e44 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -7,8 +7,9 @@ * bulia byak * Johan Engelen * Abhishek Sharma + * Diederik van Lierop * - * Copyright (C) 1999-2008 authors + * Copyright (C) 1999-2011 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -67,46 +68,76 @@ sp_item_skew_rel (SPItem *item, double skewX, double skewY) void sp_item_move_rel(SPItem *item, Geom::Translate const &tr) { - item->set_i2d_affine(item->i2d_affine() * tr); + item->set_i2d_affine(item->i2d_affine() * tr); - item->doWriteTransform(item->getRepr(), item->transform); + item->doWriteTransform(item->getRepr(), item->transform); } -/* -** Returns the matrix you need to apply to an object with given visual bbox and strokewidth to -scale/move it to the new visual bbox x0/y0/x1/y1. Takes into account the "scale stroke" -preference value passed to it. Has to solve a quadratic equation to make sure -the goal is met exactly and the stroke scaling is obeyed. +/** + * \brief Calculate the affine transformation required to transform one visual bounding box into another, accounting for a uniform strokewidth + * + * PS: This function will only return accurate results for the visual bounding box of a selection of one of more objects, all having + * the same strokewidth. If the stroke width varies from object to object in this selection, then the function + * get_scale_transform_with_unequal_stroke() should be called instead + * + * When scaling or stretching an object using the selector, e.g. by dragging the handles or by entering a value, we will + * need to calculate the affine transformation for the old dimensions to the new dimensions. When using a geometric bounding + * box this is very straightforward, but when using a visual bounding box this become more tricky as we need to account for + * the strokewidth, which is either constant or scales width the area of the object. This function takes care of the calculation + * of the affine transformation: + * \param bbox_visual Current visual bounding box + * \param strokewidth Strokewidth + * \param transform_stroke If true then the stroke will be scaled proportional to the square root of the area of the geometric bounding box + * \param x0 Coordinate of the target visual bounding box + * \param y0 Coordinate of the target visual bounding box + * \param x1 Coordinate of the target visual bounding box + * \param y1 Coordinate of the target visual bounding box + * PS: we have to pass each coordinate individually, to find out if we are mirroring the object; Using a Geom::Rect() instead is + not possible here because it will only allow for a positive width and height, and therefore cannot mirror + * \return */ Geom::Affine -get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +get_scale_transform_with_uniform_stroke (Geom::Rect const &bbox_visual, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) { - Geom::Rect bbox (bbox_param); - - Geom::Affine p2o = Geom::Translate (-bbox.min()); + Geom::Affine p2o = Geom::Translate (-bbox_visual.min()); Geom::Affine o2n = Geom::Translate (x0, y0); - Geom::Affine scale = Geom::Scale (1, 1); // scale component - Geom::Affine unbudge = Geom::Translate (0, 0); // move component to compensate for the drift caused by stroke width change + Geom::Affine scale = Geom::Scale (1, 1); + Geom::Affine unbudge = Geom::Translate (0, 0); // moves the object(s) to compensate for the drift caused by stroke width change + + // 1) We start with a visual bounding box (w0, h0) which we want to transfer into another visual bounding box (w1, h1) + // 2) The stroke is r0, equal for all edges + // 3) Given this visual bounding box we can calculate the geometric bounding box by subtracting half the stroke from each side; + // -> The width and height of the geometric bounding box will therefore be (w0 - 2*0.5*r0) and (h0 - 2*0.5*r0) - gdouble w0 = bbox[Geom::X].extent(); // will return a value >= 0, as required further down the road - gdouble h0 = bbox[Geom::Y].extent(); + gdouble w0 = bbox_visual.width(); // will return a value >= 0, as required further down the road + gdouble h0 = bbox_visual.height(); + gdouble r0 = fabs(strokewidth); + + // We also know the width and height of the new visual bounding box gdouble w1 = x1 - x0; // can have any sign gdouble h1 = y1 - y0; - gdouble r0 = strokewidth; + // The new visual bounding box will have a stroke r1 + + // We will now try to calculate the affine transformation required to transform the first visual bounding box into + // the second one, while accounting for strokewidth - if (bbox.hasZeroArea()) { - Geom::Affine move = Geom::Translate(x0 - bbox.min()[Geom::X], y0 - bbox.min()[Geom::Y]); - return (move); // cannot scale from empty boxes at all, so only translate + if (bbox_visual.hasZeroArea()) { // Obviously we cannot scale from empty visual bounding boxes at all, so we will only translate in such a case + Geom::Affine move = Geom::Translate(x0 - bbox_visual.min()[Geom::X], y0 - bbox_visual.min()[Geom::Y]); + return (move); } - Geom::Affine direct = Geom::Scale(w1 / w0, h1 / h0); + Geom::Affine direct = Geom::Scale(w1 / w0, h1 / h0); // Scaling of the visual bounding box + // Although the area of the visual bounding box is not zero, we can still have a geometric + // bounding box with one or both sides having zero length. We can't handle this and will therefore + // simply return the scaling of the visual bounding box, without accounting for any stroke scaling if (fabs(w0 - r0) < 1e-6 || fabs(h0 - r0) < 1e-6 || (!transform_stroke && (fabs(w1 - r0) < 1e-6 || fabs(h1 - r0) < 1e-6))) { - return (p2o * direct * o2n); // can't solve the equation: one of the dimensions is equal to stroke width, so return the straightforward scaler + return (p2o * direct * o2n); } + // Here starts the calculation you've been waiting for; first do some preparation int flip_x = (w1 > 0) ? 1 : -1; int flip_y = (h1 > 0) ? 1 : -1; @@ -115,43 +146,201 @@ get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewid w1 = fabs(w1); h1 = fabs(h1); r0 = fabs(r0); - // w0 and h0 will always be positive due to the definition extent() + // w0 and h0 will always be positive due to the definition of the width() and height() methods. - gdouble ratio_x = (w1 - r0) / (w0 - r0); + gdouble ratio_x = (w1 - r0) / (w0 - r0); // Only valid when the stroke is kept constant, in which case r1 = r0 gdouble ratio_y = (h1 - r0) / (h0 - r0); - + + // Calculating the scaling of the geometric bounding box if the stroke is kept constant Geom::Affine direct_constant_r = Geom::Scale(flip_x * ratio_x, flip_y * ratio_y); - if (transform_stroke && r0 != 0 && r0 != Geom::infinity()) { // there's stroke, and we need to scale it - // These coefficients are obtained from the assumption that scaling applies to the - // non-stroked "shape proper" and that stroke scale is scaled by the expansion of that - // matrix. We're trying to solve this equation: - // r1 = r0 * sqrt (((w1-r0)/(w0-r0))*((h1-r0)/(h0-r0))) - // The operant of the sqrt() must be positive, which is ensured by the fabs() a few lines above + // If the stroke is not kept constant however, the scaling of the geometric bbox is more difficult to find + if (transform_stroke && r0 != 0 && r0 != Geom::infinity()) { // Check if there's stroke, and we need to scale it + /* Initial area of the geometric bounding box: A0 = (w0-r0)*(h0-r0) + * Desired area of the geometric bounding box: A1 = (w1-r1)*(h1-r1) + * This is how the stroke should scale: r1^2 / A1 = r0^2 / A0 + * So therefore we will need to solve this equation: + * + * r1^2 * (w0-r0) * (h1-r1) = r0^2 * (w1-r1) * (h0-r0) + * + * This is a quadratic equation in r1, of which the roots can be found using the ABC formula + * */ gdouble A = -w0*h0 + r0*(w0 + h0); gdouble B = -(w1 + h1) * r0*r0; gdouble C = w1 * h1 * r0*r0; if (B*B - 4*A*C > 0) { + // Of the two roots, I verified experimentally that this is the one we need gdouble r1 = fabs((-B - sqrt(B*B - 4*A*C))/(2*A)); - //gdouble r2 = (-B + sqrt (B*B - 4*A*C))/(2*A); - //std::cout << "r0" << r0 << " r1" << r1 << " r2" << r2 << "\n"; - // - // If w1 < 0 then the scale will be wrong if we just do - // gdouble scale_x = (w1 - r1)/(w0 - r0); - // Here we also need the absolute values of w0, w1, h0, h1, and r1 + // If w1 < 0 then the scale will be wrong if we just assume that scale_x = (w1 - r1)/(w0 - r0); + // Therefore we here need the absolute values of w0, w1, h0, h1, and r0, as taken care of earlier gdouble scale_x = (w1 - r1)/(w0 - r0); gdouble scale_y = (h1 - r1)/(h0 - r0); + // Now we account for mirroring by flipping if needed scale *= Geom::Scale(flip_x * scale_x, flip_y * scale_y); + // Make sure that the lower-left corner of the visual bounding box stays where it is, even though the stroke width has changed unbudge *= Geom::Translate (-flip_x * 0.5 * (r0 * scale_x - r1), -flip_y * 0.5 * (r0 * scale_y - r1)); - } else { + } else { // Can't find the roots of the quadratic equation. Likely the input parameters are invalid? scale *= direct; } - } else { - if (r0 == 0 || r0 == Geom::infinity()) { // no stroke to scale - scale *= direct; - } else {// nonscaling strokewidth + } else { // The stroke should not be scaled, or is zero + if (!transform_stroke) { // Nonscaling strokewidth scale *= direct_constant_r; unbudge *= Geom::Translate (flip_x * 0.5 * r0 * (1 - ratio_x), flip_y * 0.5 * r0 * (1 - ratio_y)); + } else { // Strokewidth is zero or infinite + scale *= direct; + } + } + + return (p2o * scale * unbudge * o2n); +} + +/** + * \brief Calculate the affine transformation required to transform one visual bounding box into another, accounting for a VARIABLE strokewidth + * + * Note: Please try to understand get_scale_transform_with_uniform_stroke() first, and read all it's comments carefully. This function + * (get_scale_transform_with_unequal_stroke) is a bit different because it will allow for a strokewidth that's different for each + * side of the visual bounding box. Such a situation will arise when transforming the visual bounding box of a selection of objects, + * each having a different stroke width. In fact this function is a generalized version of get_scale_transform_with_uniform_stroke(), but + * will not (yet) replace it because it has not been tested as carefully, and because the old function is can serve as an introduction to + * understand the new one. + * + * When scaling or stretching an object using the selector, e.g. by dragging the handles or by entering a value, we will + * need to calculate the affine transformation for the old dimensions to the new dimensions. When using a geometric bounding + * box this is very straightforward, but when using a visual bounding box this become more tricky as we need to account for + * the strokewidth, which is either constant or scales width the area of the object. This function takes care of the calculation + * of the affine transformation: + * + * \param bbox_visual Current visual bounding box + * \param bbox_geometric Current geometric bounding box (allows for calculating the strokewidth of each edge) + * \param transform_stroke If true then the stroke will be scaled proportional to the square root of the area of the geometric bounding box + * \param x0 Coordinate of the target visual bounding box + * \param y0 Coordinate of the target visual bounding box + * \param x1 Coordinate of the target visual bounding box + * \param y1 Coordinate of the target visual bounding box + PS: we have to pass each coordinate individually, to find out if we are mirroring the object; Using a Geom::Rect() instead is + not possible here because it will only allow for a positive width and height, and therefore cannot mirror + * \return +*/ + +Geom::Affine +get_scale_transform_with_unequal_stroke (Geom::Rect const &bbox_visual, Geom::Rect const &bbox_geom, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +{ + Geom::Affine p2o = Geom::Translate (-bbox_visual.min()); + Geom::Affine o2n = Geom::Translate (x0, y0); + + Geom::Affine scale = Geom::Scale (1, 1); + Geom::Affine unbudge = Geom::Translate (0, 0); // moves the object(s) to compensate for the drift caused by stroke width change + + // 1) We start with a visual bounding box (w0, h0) which we want to transfer into another visual bounding box (w1, h1) + // 2) We will also know the geometric bounding box, which can be used to calculate the strokewidth. The strokewidth will however + // be different for each of the four sides (left/right/top/bottom: r0l, r0r, r0t, r0b) + + gdouble w0 = bbox_visual.width(); // will return a value >= 0, as required further down the road + gdouble h0 = bbox_visual.height(); + + // We also know the width and height of the new visual bounding box + gdouble w1 = x1 - x0; // can have any sign + gdouble h1 = y1 - y0; + // The new visual bounding box will have strokes r1l, r1r, r1t, and r1b + + // We will now try to calculate the affine transformation required to transform the first visual bounding box into + // the second one, while accounting for strokewidth + gdouble r0w = w0 - bbox_geom.width(); // r0w is the average strokewidth of the left and right edges, i.e. 0.5*(r0l + r0r) + gdouble r0h = h0 - bbox_geom.height(); // r0h is the average strokewidth of the top and bottom edges, i.e. 0.5*(r0t + r0b) + + // Check whether the stroke is not negative; should not be possible, but just in case: + g_assert(r0w >= 0); + g_assert(r0h >= 0); + + if (bbox_visual.hasZeroArea()) { // Obviously we cannot scale from empty visual bounding boxes at all, so we will only translate in such a case + Geom::Affine move = Geom::Translate(x0 - bbox_visual.min()[Geom::X], y0 - bbox_visual.min()[Geom::Y]); + return (move); + } + + Geom::Affine direct = Geom::Scale(w1 / w0, h1 / h0); + + // Although the area of the visual bounding box is not zero, we can still have a geometric + // bounding box with one or both sides having zero length. We can't handle this and will therefore + // simply return the scaling of the visual bounding box, without accounting for any stroke scaling + if (fabs(w0 - r0w) < 1e-6 || fabs(h0 - r0h) < 1e-6 || (!transform_stroke && (fabs(w1 - r0w) < 1e-6 || fabs(h1 - r0h) < 1e-6))) { + return (p2o * direct * o2n); + } + + // Here starts the calculation you've been waiting for; first do some preparation + int flip_x = (w1 > 0) ? 1 : -1; + int flip_y = (h1 > 0) ? 1 : -1; + + // w1 and h1 will be negative when mirroring, but if so then e.g. w1-r0 won't make sense + // Therefore we will use the absolute values from this point on + w1 = fabs(w1); + h1 = fabs(h1); + // w0 and h0 will always be positive due to the definition of the width() and height() methods. + + gdouble ratio_x = (w1 - r0w) / (w0 - r0w); // Only valid when the stroke is kept constant, in which case r1 = r0 + gdouble ratio_y = (h1 - r0h) / (h0 - r0h); + + // Calculating the scaling of the geometric bounding box if the stroke is kept constant + Geom::Affine direct_constant_r = Geom::Scale(flip_x * ratio_x, flip_y * ratio_y); + + // The calculation of the new strokewidth will only use the average stroke for each of the dimensions; To find the new stroke for each + // of the edges individually though, we will use the boundary condition that the ratio of the left/right strokewidth will not change due to the + // scaling. The same holds for the ratio of the top/bottom strokewidth. + gdouble stroke_ratio_w = fabs(r0w) < 1e-6 ? 1 : (bbox_geom[Geom::X].min() - bbox_visual[Geom::X].min())/r0w; + gdouble stroke_ratio_h = fabs(r0h) < 1e-6 ? 1 : (bbox_geom[Geom::Y].min() - bbox_visual[Geom::Y].min())/r0h; + + // If the stroke is not kept constant however, the scaling of the geometric bbox is more difficult to find + if (transform_stroke && r0w != 0 && r0w != Geom::infinity() && r0h != 0 && r0h != Geom::infinity()) { // Check if there's stroke, and we need to scale it + /* Initial area of the geometric bounding box: A0 = (w0-r0w)*(h0-r0h) + * Desired area of the geometric bounding box: A1 = (w1-r1w)*(h1-r1h) + * This is how the stroke should scale: r1w^2 = A1/A0 * r0w^2, AND + * r1h^2 = A1/A0 * r0h^2 + * Now we have to solve this set of two equations and find r1w and r1h; this too complicated to do by hand, + * so I used wxMaxima for that (http://wxmaxima.sourceforge.net/). These lines can be copied into Maxima + * + * A1: (w1-r1w)*(h1-r1h); + * s: A1/A0; + * expr1a: r1w^2 = s*r0w^2; + * expr1b: r1h^2 = s*r0h^2; + * sol: solve([expr1a, expr1b], [r1h, r1w]); + * sol[1][1]; sol[2][1]; sol[3][1]; sol[4][1]; + * sol[1][2]; sol[2][2]; sol[3][2]; sol[4][2]; + * + * PS1: The last two lines are only needed for readability of the output, and can be omitted if desired + * PS2: A0 is known beforehand and assumed to be constant, instead of using A0 = (w0-r0w)*(h0-r0h). This reduces the + * length of the results significantly + * PS3: You'll get 8 solutions, 4 for each of the strokewidths r1w and r1h. Some experiments quickly showed which of the solutions + * lead to meaningful strokewidths + * */ + gdouble r0h2 = r0h*r0h; + gdouble r0h3 = r0h2*r0h; + gdouble r0w2 = r0w*r0w; + gdouble w12 = w1*w1; + gdouble h12 = h1*h1; + gdouble A0 = bbox_geom.area(); + gdouble A02 = A0*A0; + + gdouble operant = 4*h1*w1*A0+r0h2*w12-2*h1*r0h*r0w*w1+h12*r0w2; + if (operant >= 0) { + // Of the eight roots, I verified experimentally that these are the two we need + gdouble r1h= fabs((r0h*sqrt(operant)-r0h2*w1-h1*r0h*r0w)/(2*A0-2*r0h*r0w)); + gdouble r1w= fabs(-((h1*r0w*A0+r0h2*r0w*w1)*sqrt(operant)+(-3*h1*r0h*r0w*w1-h12*r0w2)*A0-r0h3*r0w*w12+h1*r0h2*r0w2*w1)/((r0h*A0-r0h2*r0w)*sqrt(operant)-2*h1*A02+(3*h1*r0h*r0w-r0h2*w1)*A0+r0h3*r0w*w1-h1*r0h2*r0w2)); + // If w1 < 0 then the scale will be wrong if we just assume that scale_x = (w1 - r1)/(w0 - r0); + // Therefore we here need the absolute values of w0, w1, h0, h1, and r0, as taken care of earlier + gdouble scale_x = (w1 - r1w)/(w0 - r0w); + gdouble scale_y = (h1 - r1h)/(h0 - r0h); + // Now we account for mirroring by flipping if needed + scale *= Geom::Scale(flip_x * scale_x, flip_y * scale_y); + // Make sure that the lower-left corner of the visual bounding box stays where it is, even though the stroke width has changed + unbudge *= Geom::Translate (-flip_x * stroke_ratio_w * (r0w * scale_x - r1w), -flip_y * stroke_ratio_h * (r0h * scale_y - r1h)); + } else { // Can't find the roots of the quadratic equation. Likely the input parameters are invalid? + scale *= direct; + } + } else { // The stroke should not be scaled, or is zero (or infinite) + if (!transform_stroke) { + scale *= direct_constant_r; + unbudge *= Geom::Translate (flip_x * stroke_ratio_w * r0w * (1 - ratio_x), flip_y * stroke_ratio_h * r0h * (1 - ratio_y)); + } else { // can't calculate, because apparently strokewidth is zero or infinite + scale *= direct; } } diff --git a/src/sp-item-transform.h b/src/sp-item-transform.h index 552b23e2f..47e0ec0ec 100644 --- a/src/sp-item-transform.h +++ b/src/sp-item-transform.h @@ -9,7 +9,8 @@ void sp_item_scale_rel (SPItem *item, Geom::Scale const &scale); void sp_item_skew_rel (SPItem *item, double skewX, double skewY); void sp_item_move_rel(SPItem *item, Geom::Translate const &tr); -Geom::Affine get_scale_transform_with_stroke (Geom::Rect const &bbox, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); +Geom::Affine get_scale_transform_with_uniform_stroke (Geom::Rect const &bbox_visual, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); +Geom::Affine get_scale_transform_with_unequal_stroke (Geom::Rect const &bbox_visual, Geom::Rect const &bbox_geom, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Affine const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index eb9b2805d..ba32dc321 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -159,12 +159,16 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) document->ensureUpToDate (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + Geom::OptRect bbox_vis = selection->bounds(SPItem::APPROXIMATE_BBOX); + Geom::OptRect bbox_geom = selection->bounds(SPItem::GEOMETRIC_BBOX); + int prefs_bbox = prefs->getInt("/tools/bounding_box"); - SPItem::BBoxType bbox_type = (prefs_bbox ==0)? + SPItem::BBoxType bbox_type = (prefs_bbox == 0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - Geom::OptRect bbox = selection->bounds(bbox_type); + Geom::OptRect bbox_user = selection->bounds(bbox_type); - if ( !bbox ) { + if ( !bbox_user ) { g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); return; } @@ -186,35 +190,35 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) x0 = sp_units_get_pixels (a_x->value, unit); y0 = sp_units_get_pixels (a_y->value, unit); x1 = x0 + sp_units_get_pixels (a_w->value, unit); - xrel = sp_units_get_pixels (a_w->value, unit) / bbox->dimensions()[Geom::X]; + xrel = sp_units_get_pixels (a_w->value, unit) / bbox_user->dimensions()[Geom::X]; y1 = y0 + sp_units_get_pixels (a_h->value, unit); - yrel = sp_units_get_pixels (a_h->value, unit) / bbox->dimensions()[Geom::Y]; + yrel = sp_units_get_pixels (a_h->value, unit) / bbox_user->dimensions()[Geom::Y]; } else { double const x0_propn = a_x->value * unit.unittobase; - x0 = bbox->min()[Geom::X] * x0_propn; + x0 = bbox_user->min()[Geom::X] * x0_propn; double const y0_propn = a_y->value * unit.unittobase; - y0 = y0_propn * bbox->min()[Geom::Y]; + y0 = y0_propn * bbox_user->min()[Geom::Y]; xrel = a_w->value * unit.unittobase; - x1 = x0 + xrel * bbox->dimensions()[Geom::X]; + x1 = x0 + xrel * bbox_user->dimensions()[Geom::X]; yrel = a_h->value * unit.unittobase; - y1 = y0 + yrel * bbox->dimensions()[Geom::Y]; + y1 = y0 + yrel * bbox_user->dimensions()[Geom::Y]; } // Keep proportions if lock is on GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { - x1 = x0 + yrel * bbox->dimensions()[Geom::X]; + x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; } else if (adj == a_w) { - y1 = y0 + xrel * bbox->dimensions()[Geom::Y]; + y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y]; } } // scales and moves, in px - double mh = fabs(x0 - bbox->min()[Geom::X]); - double sh = fabs(x1 - bbox->max()[Geom::X]); - double mv = fabs(y0 - bbox->min()[Geom::Y]); - double sv = fabs(y1 - bbox->max()[Geom::Y]); + double mh = fabs(x0 - bbox_user->min()[Geom::X]); + double sh = fabs(x1 - bbox_user->max()[Geom::X]); + double mv = fabs(y0 - bbox_user->min()[Geom::Y]); + double sv = fabs(y1 - bbox_user->max()[Geom::Y]); // unless the unit is %, convert the scales and moves to the unit if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { @@ -244,11 +248,11 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) Geom::Affine scaler; if (bbox_type == SPItem::APPROXIMATE_BBOX) { - // get_scale_transform_with_stroke() is intended for VISUAL (or APPROXIMATE) bounding boxes, not geometrical ones! - scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1); + scaler = get_scale_transform_with_unequal_stroke (*bbox_vis, *bbox_geom, transform_stroke, x0, y0, x1, y1); } else { - // we'll trick it into using a geometrical bounding box though, by setting the stroke width to zero - scaler = get_scale_transform_with_stroke (*bbox, 0, false, x0, y0, x1, y1); + // get_scale_transform_with_stroke() is intended for VISUAL (or APPROXIMATE) bounding boxes, not geometrical ones! + // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero + scaler = get_scale_transform_with_uniform_stroke (*bbox_user, 0, false, x0, y0, x1, y1); } sp_selection_apply_affine(selection, scaler); -- cgit v1.2.3 From 476773dea7a4bf2136beba4b31f44a0dca16fa40 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 11 Jul 2011 09:19:35 +0100 Subject: Drop some unused gdl files that cause build failure on Windows (bzr r10440) --- src/libgdl/gdl-dock-layout.c | 1437 ---------------------------------------- src/libgdl/gdl-dock-layout.h | 98 --- src/libgdl/gdl.h | 1 - src/libgdl/test-combo-button.c | 111 ---- src/libgdl/test-dock.c | 314 --------- 5 files changed, 1961 deletions(-) delete mode 100644 src/libgdl/gdl-dock-layout.c delete mode 100644 src/libgdl/gdl-dock-layout.h delete mode 100644 src/libgdl/test-combo-button.c delete mode 100644 src/libgdl/test-dock.c (limited to 'src') diff --git a/src/libgdl/gdl-dock-layout.c b/src/libgdl/gdl-dock-layout.c deleted file mode 100644 index 7c5279507..000000000 --- a/src/libgdl/gdl-dock-layout.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2002 Gustavo Giráldez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gdl-i18n.h" -#include -#include -#include -#include - -#include "gdl-dock-layout.h" -#include "gdl-tools.h" -#include "gdl-dock-placeholder.h" - - -/* ----- Private variables ----- */ - -enum { - PROP_0, - PROP_MASTER, - PROP_DIRTY -}; - -#define ROOT_ELEMENT "dock-layout" -#define DEFAULT_LAYOUT "__default__" -#define LAYOUT_ELEMENT_NAME "layout" -#define NAME_ATTRIBUTE_NAME "name" - -#define LAYOUT_UI_FILE "layout.ui" - -enum { - COLUMN_NAME, - COLUMN_SHOW, - COLUMN_LOCKED, - COLUMN_ITEM -}; - -#define COLUMN_EDITABLE COLUMN_SHOW - -struct _GdlDockLayoutPrivate { - xmlDocPtr doc; - - /* layout list models */ - GtkListStore *items_model; - GtkListStore *layouts_model; - - /* idle control */ - gboolean idle_save_pending; -}; - -typedef struct _GdlDockLayoutUIData GdlDockLayoutUIData; - -struct _GdlDockLayoutUIData { - GdlDockLayout *layout; - GtkWidget *locked_check; - GtkTreeSelection *selection; -}; - - -/* ----- Private prototypes ----- */ - -static void gdl_dock_layout_class_init (GdlDockLayoutClass *klass); - -static void gdl_dock_layout_instance_init (GdlDockLayout *layout); - -static void gdl_dock_layout_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); - -static void gdl_dock_layout_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void gdl_dock_layout_dispose (GObject *object); - -static void gdl_dock_layout_build_doc (GdlDockLayout *layout); - -static xmlNodePtr gdl_dock_layout_find_layout (GdlDockLayout *layout, - const gchar *name); - -static void gdl_dock_layout_build_models (GdlDockLayout *layout); - - -/* ----- Private implementation ----- */ - -GDL_CLASS_BOILERPLATE (GdlDockLayout, gdl_dock_layout, GObject, G_TYPE_OBJECT); - -static void -gdl_dock_layout_class_init (GdlDockLayoutClass *klass) -{ - GObjectClass *g_object_class = (GObjectClass *) klass; - - g_object_class->set_property = gdl_dock_layout_set_property; - g_object_class->get_property = gdl_dock_layout_get_property; - g_object_class->dispose = gdl_dock_layout_dispose; - - g_object_class_install_property ( - g_object_class, PROP_MASTER, - g_param_spec_object ("master", _("Master"), - _("GdlDockMaster object which the layout object " - "is attached to"), - GDL_TYPE_DOCK_MASTER, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - g_object_class, PROP_DIRTY, - g_param_spec_boolean ("dirty", _("Dirty"), - _("True if the layouts have changed and need to be " - "saved to a file"), - FALSE, - G_PARAM_READABLE)); -} - -static void -gdl_dock_layout_instance_init (GdlDockLayout *layout) -{ - layout->master = NULL; - layout->dirty = FALSE; - layout->_priv = g_new0 (GdlDockLayoutPrivate, 1); - layout->_priv->idle_save_pending = FALSE; - - gdl_dock_layout_build_models (layout); -} - -static void -gdl_dock_layout_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdlDockLayout *layout = GDL_DOCK_LAYOUT (object); - - switch (prop_id) { - case PROP_MASTER: - gdl_dock_layout_attach (layout, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - }; -} - -static void -gdl_dock_layout_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdlDockLayout *layout = GDL_DOCK_LAYOUT (object); - - switch (prop_id) { - case PROP_MASTER: - g_value_set_object (value, layout->master); - break; - case PROP_DIRTY: - g_value_set_boolean (value, layout->dirty); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - }; -} - -static void -gdl_dock_layout_dispose (GObject *object) -{ - GdlDockLayout *layout; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDL_IS_DOCK_LAYOUT (object)); - - layout = GDL_DOCK_LAYOUT (object); - - if (layout->master) - gdl_dock_layout_attach (layout, NULL); - - if (layout->_priv) { - if (layout->_priv->idle_save_pending) { - layout->_priv->idle_save_pending = FALSE; - g_idle_remove_by_data (layout); - } - - if (layout->_priv->doc) { - xmlFreeDoc (layout->_priv->doc); - layout->_priv->doc = NULL; - } - - if (layout->_priv->items_model) { - g_object_unref (layout->_priv->items_model); - g_object_unref (layout->_priv->layouts_model); - layout->_priv->items_model = NULL; - layout->_priv->layouts_model = NULL; - } - - xmlFreeDoc(layout->_priv->doc); - g_free (layout->_priv); - layout->_priv = NULL; - } -} - -static void -gdl_dock_layout_build_doc (GdlDockLayout *layout) -{ - g_return_if_fail (layout->_priv->doc == NULL); - - layout->_priv->doc = xmlNewDoc (BAD_CAST "1.0"); - layout->_priv->doc->children = xmlNewDocNode (layout->_priv->doc, NULL, - BAD_CAST ROOT_ELEMENT, NULL); -} - -static xmlNodePtr -gdl_dock_layout_find_layout (GdlDockLayout *layout, - const gchar *name) -{ - xmlNodePtr node; - gboolean found = FALSE; - - g_return_val_if_fail (layout != NULL, NULL); - - if (!layout->_priv->doc) - return NULL; - - /* get document root */ - node = layout->_priv->doc->children; - for (node = node->children; node; node = node->next) { - xmlChar *layout_name; - - if (strcmp ((char*)node->name, LAYOUT_ELEMENT_NAME)) - /* skip non-layout element */ - continue; - - /* we want the first layout */ - if (!name) - break; - - layout_name = xmlGetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME); - if (!strcmp (name, (char*)layout_name)) - found = TRUE; - xmlFree (layout_name); - - if (found) - break; - }; - return node; -} - -static void -gdl_dock_layout_build_models (GdlDockLayout *layout) -{ - if (!layout->_priv->items_model) { - layout->_priv->items_model = gtk_list_store_new (4, - G_TYPE_STRING, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, - G_TYPE_POINTER); - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (layout->_priv->items_model), - COLUMN_NAME, GTK_SORT_ASCENDING); - } - - if (!layout->_priv->layouts_model) { - layout->_priv->layouts_model = gtk_list_store_new (2, G_TYPE_STRING, - G_TYPE_BOOLEAN); - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (layout->_priv->layouts_model), - COLUMN_NAME, GTK_SORT_ASCENDING); - } -} - -static void -build_list (GdlDockObject *object, GList **list) -{ - /* add only items, not toplevels */ - if (GDL_IS_DOCK_ITEM (object)) - *list = g_list_prepend (*list, object); -} - -static void -update_items_model (GdlDockLayout *layout) -{ - GList *items, *l; - GtkTreeIter iter; - GtkListStore *store; - gchar *long_name; - gboolean locked; - - g_return_if_fail (layout != NULL); - g_return_if_fail (layout->_priv->items_model != NULL); - - if (!layout->master) - return; - - /* build items list */ - items = NULL; - gdl_dock_master_foreach (layout->master, (GFunc) build_list, &items); - - /* walk the current model */ - store = layout->_priv->items_model; - - /* update items model data after a layout load */ - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gboolean valid = TRUE; - - while (valid) { - GdlDockItem *item; - - gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, - COLUMN_ITEM, &item, - -1); - if (item) { - /* look for the object in the items list */ - for (l = items; l && l->data != item; l = l->next); - - if (l) { - /* found, update data */ - g_object_get (item, - "long-name", &long_name, - "locked", &locked, - NULL); - gtk_list_store_set (store, &iter, - COLUMN_NAME, long_name, - COLUMN_SHOW, GDL_DOCK_OBJECT_ATTACHED (item), - COLUMN_LOCKED, locked, - -1); - g_free (long_name); - - /* remove the item from the linked list and keep on walking the model */ - items = g_list_delete_link (items, l); - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); - - } else { - /* not found, which means the item has been removed */ - valid = gtk_list_store_remove (store, &iter); - - } - - } else { - /* not a valid row */ - valid = gtk_list_store_remove (store, &iter); - } - } - } - - /* add any remaining objects */ - for (l = items; l; l = l->next) { - GdlDockObject *object = l->data; - - g_object_get (object, - "long-name", &long_name, - "locked", &locked, - NULL); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COLUMN_ITEM, object, - COLUMN_NAME, long_name, - COLUMN_SHOW, GDL_DOCK_OBJECT_ATTACHED (object), - COLUMN_LOCKED, locked, - -1); - g_free (long_name); - } - - g_list_free (items); -} - -static void -update_layouts_model (GdlDockLayout *layout) -{ - GList *items, *l; - GtkTreeIter iter; - - g_return_if_fail (layout != NULL); - g_return_if_fail (layout->_priv->layouts_model != NULL); - - /* build layouts list */ - gtk_list_store_clear (layout->_priv->layouts_model); - items = gdl_dock_layout_get_layouts (layout, FALSE); - for (l = items; l; l = l->next) { - gtk_list_store_append (layout->_priv->layouts_model, &iter); - gtk_list_store_set (layout->_priv->layouts_model, &iter, - COLUMN_NAME, l->data, COLUMN_EDITABLE, TRUE, - -1); - g_free (l->data); - }; - g_list_free (items); -} - - -/* ------- UI functions & callbacks ------ */ - -static void -load_layout_cb (GtkWidget *w, - gpointer data) -{ - GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; - - GtkTreeModel *model; - GtkTreeIter iter; - GdlDockLayout *layout = ui_data->layout; - gchar *name; - - g_return_if_fail (layout != NULL); - - if (gtk_tree_selection_get_selected (ui_data->selection, &model, &iter)) { - gtk_tree_model_get (model, &iter, - COLUMN_NAME, &name, - -1); - gdl_dock_layout_load_layout (layout, name); - g_free (name); - } -} - -static void -delete_layout_cb (GtkWidget *w, gpointer data) -{ - GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; - - GtkTreeModel *model; - GtkTreeIter iter; - GdlDockLayout *layout = ui_data->layout; - gchar *name; - - g_return_if_fail (layout != NULL); - - if (gtk_tree_selection_get_selected (ui_data->selection, &model, &iter)) { - gtk_tree_model_get (model, &iter, - COLUMN_NAME, &name, - -1); - gdl_dock_layout_delete_layout (layout, name); - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - g_free (name); - }; -} - -static void -show_toggled_cb (GtkCellRendererToggle *renderer, - gchar *path_str, - gpointer data) -{ - GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; - - GdlDockLayout *layout = ui_data->layout; - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - gboolean value; - GdlDockItem *item; - - g_return_if_fail (layout != NULL); - - model = GTK_TREE_MODEL (layout->_priv->items_model); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, - COLUMN_SHOW, &value, - COLUMN_ITEM, &item, - -1); - - value = !value; - if (value) - gdl_dock_item_show_item (item); - else - gdl_dock_item_hide_item (item); - - gtk_tree_path_free (path); -} - -static void -all_locked_toggled_cb (GtkWidget *widget, - gpointer data) -{ - GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) data; - GdlDockMaster *master; - gboolean locked; - - g_return_if_fail (ui_data->layout != NULL); - master = ui_data->layout->master; - g_return_if_fail (master != NULL); - - locked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - g_object_set (master, "locked", locked ? 1 : 0, NULL); -} - -static void -layout_ui_destroyed (GtkWidget *widget, - gpointer user_data) -{ - GdlDockLayoutUIData *ui_data; - - /* widget is the GtkContainer */ - ui_data = g_object_get_data (G_OBJECT (widget), "ui_data"); - if (ui_data) { - if (ui_data->layout) { - if (ui_data->layout->master) - /* disconnet the notify handler */ - g_signal_handlers_disconnect_matched (ui_data->layout->master, - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - ui_data); - - g_object_remove_weak_pointer (G_OBJECT (ui_data->layout), - (gpointer *) &ui_data->layout); - ui_data->layout = NULL; - } - g_object_set_data (G_OBJECT (widget), "ui_data", NULL); - g_free (ui_data); - } -} - -static void -master_locked_notify_cb (GdlDockMaster *master, - GParamSpec *pspec, - gpointer user_data) -{ - GdlDockLayoutUIData *ui_data = (GdlDockLayoutUIData *) user_data; - gint locked; - - g_object_get (master, "locked", &locked, NULL); - if (locked == -1) { - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (ui_data->locked_check), TRUE); - } - else { - gtk_toggle_button_set_inconsistent ( - GTK_TOGGLE_BUTTON (ui_data->locked_check), FALSE); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (ui_data->locked_check), (locked == 1)); - } -} - -static GtkBuilder * -load_interface () -{ - GtkBuilder *gui; - gchar *gui_file; - GError* error = NULL; - - /* load ui */ - gui_file = g_build_filename (GDL_UIDIR, LAYOUT_UI_FILE, NULL); - gui = gtk_builder_new(); - gtk_builder_add_from_file (gui, gui_file, &error); - g_free (gui_file); - if (error) { - g_warning (_("Could not load layout user interface file '%s'"), - LAYOUT_UI_FILE); - g_object_unref (gui); - g_error_free (error); - return NULL; - }; - return gui; -} - -static GtkWidget * -gdl_dock_layout_construct_items_ui (GdlDockLayout *layout) -{ - GtkBuilder *gui; - GtkWidget *dialog; - GtkWidget *items_list; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - GdlDockLayoutUIData *ui_data; - - /* load the interface if it wasn't provided */ - gui = load_interface (); - - if (!gui) - return NULL; - - /* get the container */ - dialog = GTK_WIDGET (gtk_builder_get_object (gui, "layout_dialog")); - - ui_data = g_new0 (GdlDockLayoutUIData, 1); - ui_data->layout = layout; - g_object_add_weak_pointer (G_OBJECT (layout), - (gpointer *) &ui_data->layout); - g_object_set_data (G_OBJECT (dialog), "ui_data", ui_data); - - /* get ui widget references */ - ui_data->locked_check = GTK_WIDGET (gtk_builder_get_object (gui, "locked_check")); - items_list = GTK_WIDGET (gtk_builder_get_object(gui, "items_list")); - - /* locked check connections */ - g_signal_connect (ui_data->locked_check, "toggled", - (GCallback) all_locked_toggled_cb, ui_data); - if (layout->master) { - g_signal_connect (layout->master, "notify::locked", - (GCallback) master_locked_notify_cb, ui_data); - /* force update now */ - master_locked_notify_cb (layout->master, NULL, ui_data); - } - - /* set models */ - gtk_tree_view_set_model (GTK_TREE_VIEW (items_list), - GTK_TREE_MODEL (layout->_priv->items_model)); - - /* construct list views */ - renderer = gtk_cell_renderer_toggle_new (); - g_signal_connect (renderer, "toggled", - G_CALLBACK (show_toggled_cb), ui_data); - column = gtk_tree_view_column_new_with_attributes (_("Visible"), - renderer, - "active", COLUMN_SHOW, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (items_list), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Item"), - renderer, - "text", COLUMN_NAME, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (items_list), column); - - /* connect signals */ - g_signal_connect (dialog, "destroy", (GCallback) layout_ui_destroyed, NULL); - - g_object_unref (gui); - - return dialog; -} - -static void -cell_edited_cb (GtkCellRendererText *cell, - const gchar *path_string, - const gchar *new_text, - gpointer data) -{ - GdlDockLayoutUIData *ui_data = data; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gchar *name; - xmlNodePtr node; - - model = GTK_TREE_MODEL (ui_data->layout->_priv->layouts_model); - path = gtk_tree_path_new_from_string (path_string); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, COLUMN_NAME, &name, -1); - - node = gdl_dock_layout_find_layout (ui_data->layout, name); - g_free (name); - g_return_if_fail (node != NULL); - - xmlSetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME, BAD_CAST new_text); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_NAME, new_text, - COLUMN_EDITABLE, TRUE, -1); - - gdl_dock_layout_save_layout (ui_data->layout, new_text); - - gtk_tree_path_free (path); -} - -static GtkWidget * -gdl_dock_layout_construct_layouts_ui (GdlDockLayout *layout) -{ - GtkBuilder *gui; - GtkWidget *container; - GtkWidget *layouts_list; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkWidget *load_button; - GtkWidget *delete_button; - - GdlDockLayoutUIData *ui_data; - - /* load the interface if it wasn't provided */ - gui = load_interface (); - - if (!gui) - return NULL; - - /* get the container */ - container = GTK_WIDGET (gtk_builder_get_object(gui, "layouts_vbox")); - - ui_data = g_new0 (GdlDockLayoutUIData, 1); - ui_data->layout = layout; - g_object_add_weak_pointer (G_OBJECT (layout), - (gpointer *) &ui_data->layout); - g_object_set_data (G_OBJECT (container), "ui-data", ui_data); - - /* get ui widget references */ - layouts_list = GTK_WIDGET (gtk_builder_get_object(gui, "layouts_list")); - - /* set models */ - gtk_tree_view_set_model (GTK_TREE_VIEW (layouts_list), - GTK_TREE_MODEL (layout->_priv->layouts_model)); - - /* construct list views */ - renderer = gtk_cell_renderer_text_new (); - g_signal_connect (G_OBJECT (renderer), "edited", - G_CALLBACK (cell_edited_cb), ui_data); - column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, - "text", COLUMN_NAME, - "editable", COLUMN_EDITABLE, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (layouts_list), column); - - ui_data->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (layouts_list)); - - /* connect signals */ - load_button = GTK_WIDGET (gtk_builder_get_object(gui, "load_button")); - delete_button = GTK_WIDGET (gtk_builder_get_object(gui, "delete_button")); - - g_signal_connect (load_button, "clicked", (GCallback) load_layout_cb, ui_data); - g_signal_connect (delete_button, "clicked", (GCallback) delete_layout_cb, ui_data); - - - g_signal_connect (container, "destroy", (GCallback) layout_ui_destroyed, NULL); - - g_object_unref (gui); - - return container; -} - -/* ----- Save & Load layout functions --------- */ - -#define GDL_DOCK_PARAM_CONSTRUCTION(p) \ - (((p)->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) != 0) - -static GdlDockObject * -gdl_dock_layout_setup_object (GdlDockMaster *master, - xmlNodePtr node, - gint *n_after_params, - GParameter **after_params) -{ - GdlDockObject *object = NULL; - GType object_type; - xmlChar *object_name; - GObjectClass *object_class = NULL; - - GParamSpec **props; - guint n_props, i; - GParameter *params = NULL; - gint n_params = 0; - GValue serialized = { 0, }; - - object_name = xmlGetProp (node, BAD_CAST GDL_DOCK_NAME_PROPERTY); - if (object_name && strlen ((char*)object_name) > 0) { - /* the object must already be bound to the master */ - object = gdl_dock_master_get_object (master, (char*)object_name); - - xmlFree (object_name); - object_type = object ? G_TYPE_FROM_INSTANCE (object) : G_TYPE_NONE; - } - else { - /* the object should be automatic, so create it by - retrieving the object type from the dock registry */ - object_type = gdl_dock_object_type_from_nick ((char*)node->name); - if (object_type == G_TYPE_NONE) { - g_warning (_("While loading layout: don't know how to create " - "a dock object whose nick is '%s'"), node->name); - } - } - - if (object_type == G_TYPE_NONE || !G_TYPE_IS_CLASSED (object_type)) - return NULL; - - object_class = g_type_class_ref (object_type); - props = g_object_class_list_properties (object_class, &n_props); - - /* create parameter slots */ - /* extra parameter is the master */ - params = g_new0 (GParameter, n_props + 1); - *after_params = g_new0 (GParameter, n_props); - *n_after_params = 0; - - /* initialize value used for transformations */ - g_value_init (&serialized, GDL_TYPE_DOCK_PARAM); - - for (i = 0; i < n_props; i++) { - xmlChar *xml_prop; - - /* process all exported properties, skip - GDL_DOCK_NAME_PROPERTY, since named items should - already by in the master */ - if (!(props [i]->flags & GDL_DOCK_PARAM_EXPORT) || - !strcmp (props [i]->name, GDL_DOCK_NAME_PROPERTY)) - continue; - - /* get the property from xml if there is one */ - xml_prop = xmlGetProp (node, BAD_CAST props [i]->name); - if (xml_prop) { - g_value_set_static_string (&serialized, (char*)xml_prop); - - if (!GDL_DOCK_PARAM_CONSTRUCTION (props [i]) && - (props [i]->flags & GDL_DOCK_PARAM_AFTER)) { - (*after_params) [*n_after_params].name = props [i]->name; - g_value_init (&((* after_params) [*n_after_params].value), - props [i]->value_type); - g_value_transform (&serialized, - &((* after_params) [*n_after_params].value)); - (*n_after_params)++; - } - else if (!object || (!GDL_DOCK_PARAM_CONSTRUCTION (props [i]) && object)) { - params [n_params].name = props [i]->name; - g_value_init (&(params [n_params].value), props [i]->value_type); - g_value_transform (&serialized, &(params [n_params].value)); - n_params++; - } - xmlFree (xml_prop); - } - } - g_value_unset (&serialized); - g_free (props); - - if (!object) { - params [n_params].name = GDL_DOCK_MASTER_PROPERTY; - g_value_init (¶ms [n_params].value, GDL_TYPE_DOCK_MASTER); - g_value_set_object (¶ms [n_params].value, master); - n_params++; - - /* construct the object if we have to */ - /* set the master, so toplevels are created correctly and - other objects are bound */ - object = g_object_newv (object_type, n_params, params); - } - else { - /* set the parameters to the existing object */ - for (i = 0; i < n_params; i++) - g_object_set_property (G_OBJECT (object), - params [i].name, - ¶ms [i].value); - } - - /* free the parameters (names are static/const strings) */ - for (i = 0; i < n_params; i++) - g_value_unset (¶ms [i].value); - g_free (params); - - /* finally unref object class */ - g_type_class_unref (object_class); - - return object; -} - -static void -gdl_dock_layout_recursive_build (GdlDockMaster *master, - xmlNodePtr parent_node, - GdlDockObject *parent) -{ - GdlDockObject *object; - xmlNodePtr node; - - g_return_if_fail (master != NULL && parent_node != NULL); - - /* if parent is NULL we should build toplevels */ - for (node = parent_node->children; node; node = node->next) { - GParameter *after_params = NULL; - gint n_after_params = 0, i; - - object = gdl_dock_layout_setup_object (master, node, - &n_after_params, - &after_params); - - if (object) { - gdl_dock_object_freeze (object); - - /* recurse here to catch placeholders */ - gdl_dock_layout_recursive_build (master, node, object); - - if (GDL_IS_DOCK_PLACEHOLDER (object)) - /* placeholders are later attached to the parent */ - gdl_dock_object_detach (object, FALSE); - - /* apply "after" parameters */ - for (i = 0; i < n_after_params; i++) { - g_object_set_property (G_OBJECT (object), - after_params [i].name, - &after_params [i].value); - /* unset and free the value */ - g_value_unset (&after_params [i].value); - } - g_free (after_params); - - /* add the object to the parent */ - if (parent) { - if (GDL_IS_DOCK_PLACEHOLDER (object)) - gdl_dock_placeholder_attach (GDL_DOCK_PLACEHOLDER (object), - parent); - else if (gdl_dock_object_is_compound (parent)) { - gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (object)); - if (GTK_WIDGET_VISIBLE (parent)) - gtk_widget_show (GTK_WIDGET (object)); - } - } - else { - GdlDockObject *controller = gdl_dock_master_get_controller (master); - if (controller != object && GTK_WIDGET_VISIBLE (controller)) - gtk_widget_show (GTK_WIDGET (object)); - } - - /* call reduce just in case any child is missing */ - if (gdl_dock_object_is_compound (object)) - gdl_dock_object_reduce (object); - - gdl_dock_object_thaw (object); - } - } -} - -static void -_gdl_dock_layout_foreach_detach (GdlDockObject *object) -{ - gdl_dock_object_detach (object, TRUE); -} - -static void -gdl_dock_layout_foreach_toplevel_detach (GdlDockObject *object) -{ - gtk_container_foreach (GTK_CONTAINER (object), - (GtkCallback) _gdl_dock_layout_foreach_detach, - NULL); -} - -static void -gdl_dock_layout_load (GdlDockMaster *master, xmlNodePtr node) -{ - g_return_if_fail (master != NULL && node != NULL); - - /* start by detaching all items from the toplevels */ - gdl_dock_master_foreach_toplevel (master, TRUE, - (GFunc) gdl_dock_layout_foreach_toplevel_detach, - NULL); - - gdl_dock_layout_recursive_build (master, node, NULL); -} - -static void -gdl_dock_layout_foreach_object_save (GdlDockObject *object, - gpointer user_data) -{ - struct { - xmlNodePtr where; - GHashTable *placeholders; - } *info = user_data, info_child; - - xmlNodePtr node; - guint n_props, i; - GParamSpec **props; - GValue attr = { 0, }; - - g_return_if_fail (object != NULL && GDL_IS_DOCK_OBJECT (object)); - g_return_if_fail (info->where != NULL); - - node = xmlNewChild (info->where, - NULL, /* ns */ - BAD_CAST gdl_dock_object_nick_from_type (G_TYPE_FROM_INSTANCE (object)), - BAD_CAST NULL); /* contents */ - - /* get object exported attributes */ - props = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), - &n_props); - g_value_init (&attr, GDL_TYPE_DOCK_PARAM); - for (i = 0; i < n_props; i++) { - GParamSpec *p = props [i]; - - if (p->flags & GDL_DOCK_PARAM_EXPORT) { - GValue v = { 0, }; - - /* export this parameter */ - /* get the parameter value */ - g_value_init (&v, p->value_type); - g_object_get_property (G_OBJECT (object), - p->name, - &v); - - /* only save the object "name" if it is set - (i.e. don't save the empty string) */ - if (strcmp (p->name, GDL_DOCK_NAME_PROPERTY) || - g_value_get_string (&v)) { - if (g_value_transform (&v, &attr)) - xmlSetProp (node, BAD_CAST p->name, BAD_CAST g_value_get_string (&attr)); - } - - /* free the parameter value */ - g_value_unset (&v); - } - } - g_value_unset (&attr); - g_free (props); - - info_child = *info; - info_child.where = node; - - /* save placeholders for the object */ - if (info->placeholders && !GDL_IS_DOCK_PLACEHOLDER (object)) { - GList *lph = g_hash_table_lookup (info->placeholders, object); - for (; lph; lph = lph->next) - gdl_dock_layout_foreach_object_save (GDL_DOCK_OBJECT (lph->data), - (gpointer) &info_child); - } - - /* recurse the object if appropiate */ - if (gdl_dock_object_is_compound (object)) { - gtk_container_foreach (GTK_CONTAINER (object), - (GtkCallback) gdl_dock_layout_foreach_object_save, - (gpointer) &info_child); - } -} - -static void -add_placeholder (GdlDockObject *object, - GHashTable *placeholders) -{ - if (GDL_IS_DOCK_PLACEHOLDER (object)) { - GdlDockObject *host; - GList *l; - - g_object_get (object, "host", &host, NULL); - if (host) { - l = g_hash_table_lookup (placeholders, host); - /* add the current placeholder to the list of placeholders - for that host */ - if (l) - g_hash_table_steal (placeholders, host); - - l = g_list_prepend (l, object); - g_hash_table_insert (placeholders, host, l); - g_object_unref (host); - } - } -} - -static void -gdl_dock_layout_save (GdlDockMaster *master, - xmlNodePtr where) -{ - struct { - xmlNodePtr where; - GHashTable *placeholders; - } info; - - GHashTable *placeholders; - - g_return_if_fail (master != NULL && where != NULL); - - /* build the placeholder's hash: the hash keeps lists of - * placeholders associated to each object, so that we can save the - * placeholders when we are saving the object (since placeholders - * don't show up in the normal widget hierarchy) */ - placeholders = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) g_list_free); - gdl_dock_master_foreach (master, (GFunc) add_placeholder, placeholders); - - /* save the layout recursively */ - info.where = where; - info.placeholders = placeholders; - - gdl_dock_master_foreach_toplevel (master, TRUE, - (GFunc) gdl_dock_layout_foreach_object_save, - (gpointer) &info); - - g_hash_table_destroy (placeholders); -} - - -/* ----- Public interface ----- */ - -/** - * gdl_dock_layout_new: - * @dock: The dock item. - * Creates a new #GdlDockLayout - * - * Returns: New #GdlDockLayout item. - */ -GdlDockLayout * -gdl_dock_layout_new (GdlDock *dock) -{ - GdlDockMaster *master = NULL; - - /* get the master of the given dock */ - if (dock) - master = GDL_DOCK_OBJECT_GET_MASTER (dock); - - return g_object_new (GDL_TYPE_DOCK_LAYOUT, - "master", master, - NULL); -} - -static gboolean -gdl_dock_layout_idle_save (GdlDockLayout *layout) -{ - /* save default layout */ - gdl_dock_layout_save_layout (layout, NULL); - - layout->_priv->idle_save_pending = FALSE; - - return FALSE; -} - -static void -gdl_dock_layout_layout_changed_cb (GdlDockMaster *master, - GdlDockLayout *layout) -{ - /* update model */ - update_items_model (layout); - - if (!layout->_priv->idle_save_pending) { - g_idle_add ((GSourceFunc) gdl_dock_layout_idle_save, layout); - layout->_priv->idle_save_pending = TRUE; - } -} - - -/** - * gdl_dock_layout_attach: - * @layout: The layout item - * @master: The master item to which the layout will be attached - * - * Attach the @layout to the @master and delete the reference to - * the master that the layout attached previously - */ -void -gdl_dock_layout_attach (GdlDockLayout *layout, - GdlDockMaster *master) -{ - g_return_if_fail (layout != NULL); - g_return_if_fail (master == NULL || GDL_IS_DOCK_MASTER (master)); - - if (layout->master) { - g_signal_handlers_disconnect_matched (layout->master, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, layout); - g_object_unref (layout->master); - } - - gtk_list_store_clear (layout->_priv->items_model); - - layout->master = master; - if (layout->master) { - g_object_ref (layout->master); - g_signal_connect (layout->master, "layout-changed", - (GCallback) gdl_dock_layout_layout_changed_cb, - layout); - } - - update_items_model (layout); -} - -/** -* gdl_dock_layout_load_layout: -* @layout: The dock item. -* @name: The name of the layout to load. -* -* Loads the layout with the given name to the memory. -* This will set #GdlDockLayout:dirty to %TRUE. -* -* See also gdl_dock_layout_load_from_file() -* Returns: %TRUE if layout successfully loaded else %FALSE -*/ -gboolean -gdl_dock_layout_load_layout (GdlDockLayout *layout, - const gchar *name) -{ - xmlNodePtr node; - gchar *layout_name; - - g_return_val_if_fail (layout != NULL, FALSE); - - if (!layout->_priv->doc || !layout->master) - return FALSE; - - if (!name) - layout_name = DEFAULT_LAYOUT; - else - layout_name = (gchar *) name; - - node = gdl_dock_layout_find_layout (layout, layout_name); - if (!node && !name) - /* return the first layout if the default name failed to load */ - node = gdl_dock_layout_find_layout (layout, NULL); - - if (node) { - gdl_dock_layout_load (layout->master, node); - return TRUE; - } else - return FALSE; -} - -/** -* gdl_dock_layout_save_layout: -* @layout: The dock item. -* @name: The name of the layout to save. -* -* Saves the @layout with the given name to the memory. -* This will set #GdlDockLayout:dirty to %TRUE. -* -* See also gdl_dock_layout_save_to_file(). -*/ - -void -gdl_dock_layout_save_layout (GdlDockLayout *layout, - const gchar *name) -{ - xmlNodePtr node; - gchar *layout_name; - - g_return_if_fail (layout != NULL); - g_return_if_fail (layout->master != NULL); - - if (!layout->_priv->doc) - gdl_dock_layout_build_doc (layout); - - if (!name) - layout_name = DEFAULT_LAYOUT; - else - layout_name = (gchar *) name; - - /* delete any previously node with the same name */ - node = gdl_dock_layout_find_layout (layout, layout_name); - if (node) { - xmlUnlinkNode (node); - xmlFreeNode (node); - }; - - /* create the new node */ - node = xmlNewChild (layout->_priv->doc->children, NULL, - BAD_CAST LAYOUT_ELEMENT_NAME, NULL); - xmlSetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME, BAD_CAST layout_name); - - /* save the layout */ - gdl_dock_layout_save (layout->master, node); - layout->dirty = TRUE; - g_object_notify (G_OBJECT (layout), "dirty"); -} - -/** -* gdl_dock_layout_delete_layout: -* @layout: The dock item. -* @name: The name of the layout to delete. -* -* Deletes the layout with the given name from the memory. -* This will set #GdlDockLayout:dirty to %TRUE. -*/ - -void -gdl_dock_layout_delete_layout (GdlDockLayout *layout, - const gchar *name) -{ - xmlNodePtr node; - - g_return_if_fail (layout != NULL); - - /* don't allow the deletion of the default layout */ - if (!name || !strcmp (DEFAULT_LAYOUT, name)) - return; - - node = gdl_dock_layout_find_layout (layout, name); - if (node) { - xmlUnlinkNode (node); - xmlFreeNode (node); - layout->dirty = TRUE; - g_object_notify (G_OBJECT (layout), "dirty"); - } -} - -/** -* gdl_dock_layout_run_manager: -* @layout: The dock item. -* -* Runs the layout manager. -*/ - -void -gdl_dock_layout_run_manager (GdlDockLayout *layout) -{ - GtkWidget *dialog; - GtkWidget *parent = NULL; - - g_return_if_fail (layout != NULL); - - if (!layout->master) - /* not attached to a dock yet */ - return; - - dialog = gdl_dock_layout_construct_items_ui (layout); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); -} - -/** -* gdl_dock_layout_load_from_file: -* @layout: The layout item. -* @filename: The name of the file to load. -* -* Loads the layout from file with the given @filename. -* This will set #GdlDockLayout:dirty to %FALSE. -* -* Returns: %TRUE if @layout successfully loaded else %FALSE -*/ - -gboolean -gdl_dock_layout_load_from_file (GdlDockLayout *layout, - const gchar *filename) -{ - gboolean retval = FALSE; - - if (layout->_priv->doc) { - xmlFreeDoc (layout->_priv->doc); - layout->_priv->doc = NULL; - layout->dirty = FALSE; - g_object_notify (G_OBJECT (layout), "dirty"); - } - - /* FIXME: cannot open symlinks */ - if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { - layout->_priv->doc = xmlParseFile (filename); - if (layout->_priv->doc) { - xmlNodePtr root = layout->_priv->doc->children; - /* minimum validation: test the root element */ - if (root && !strcmp ((char*)root->name, ROOT_ELEMENT)) { - update_layouts_model (layout); - retval = TRUE; - } else { - xmlFreeDoc (layout->_priv->doc); - layout->_priv->doc = NULL; - } - } - } - - return retval; -} - -/** - * gdl_dock_layout_save_to_file: - * @layout: The layout item. - * @filename: Name of the file we want to save in layout - * - * This function saves the current layout in XML format to - * the file with the given @filename. - * - * Returns: %TRUE if @layout successfuly save to the file, otherwise %FALSE. - */ -gboolean -gdl_dock_layout_save_to_file (GdlDockLayout *layout, - const gchar *filename) -{ - FILE *file_handle; - int bytes; - gboolean retval = FALSE; - - g_return_val_if_fail (layout != NULL, FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - - /* if there is still no xml doc, create an empty one */ - if (!layout->_priv->doc) - gdl_dock_layout_build_doc (layout); - - file_handle = fopen (filename, "w"); - if (file_handle) { - bytes = xmlDocDump (file_handle, layout->_priv->doc); - if (bytes >= 0) { - layout->dirty = FALSE; - g_object_notify (G_OBJECT (layout), "dirty"); - retval = TRUE; - }; - fclose (file_handle); - }; - - return retval; -} - -/** - * gdl_dock_layout_is_dirty: - * @layout: The layout item. - * - * Checks whether the XML tree in memory is different from the file where the layout was saved. - * Returns: %TRUE is the layout in the memory is different from the file, else %FALSE. - */ -gboolean -gdl_dock_layout_is_dirty (GdlDockLayout *layout) -{ - g_return_val_if_fail (layout != NULL, FALSE); - - return layout->dirty; -}; - -GList * -gdl_dock_layout_get_layouts (GdlDockLayout *layout, - gboolean include_default) -{ - GList *retval = NULL; - xmlNodePtr node; - - g_return_val_if_fail (layout != NULL, NULL); - - if (!layout->_priv->doc) - return NULL; - - node = layout->_priv->doc->children; - for (node = node->children; node; node = node->next) { - xmlChar *name; - - if (strcmp ((char*)node->name, LAYOUT_ELEMENT_NAME)) - continue; - - name = xmlGetProp (node, BAD_CAST NAME_ATTRIBUTE_NAME); - if (include_default || strcmp ((char*)name, DEFAULT_LAYOUT)) - retval = g_list_prepend (retval, g_strdup ((char*)name)); - xmlFree (name); - }; - retval = g_list_reverse (retval); - - return retval; -} - -GtkWidget * -gdl_dock_layout_get_layouts_ui (GdlDockLayout *layout) -{ - GtkWidget *ui; - - g_return_val_if_fail (layout != NULL, NULL); - ui = gdl_dock_layout_construct_layouts_ui (layout); - - return ui; -} diff --git a/src/libgdl/gdl-dock-layout.h b/src/libgdl/gdl-dock-layout.h deleted file mode 100644 index 82dce5de8..000000000 --- a/src/libgdl/gdl-dock-layout.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 2002 Gustavo Giráldez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef __GDL_DOCK_LAYOUT_H__ -#define __GDL_DOCK_LAYOUT_H__ - -#include -#include "libgdl/gdl-dock-master.h" -#include "libgdl/gdl-dock.h" - -G_BEGIN_DECLS - -/* standard macros */ -#define GDL_TYPE_DOCK_LAYOUT (gdl_dock_layout_get_type ()) -#define GDL_DOCK_LAYOUT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayout)) -#define GDL_DOCK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) -#define GDL_IS_DOCK_LAYOUT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDL_TYPE_DOCK_LAYOUT)) -#define GDL_IS_DOCK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_LAYOUT)) -#define GDL_DOCK_LAYOUT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GDL_TYPE_DOCK_LAYOUT, GdlDockLayoutClass)) - -/* data types & structures */ -typedef struct _GdlDockLayout GdlDockLayout; -typedef struct _GdlDockLayoutClass GdlDockLayoutClass; -typedef struct _GdlDockLayoutPrivate GdlDockLayoutPrivate; - -struct _GdlDockLayout { - GObject g_object; - - gboolean dirty; - GdlDockMaster *master; - - GdlDockLayoutPrivate *_priv; -}; - -struct _GdlDockLayoutClass { - GObjectClass g_object_class; -}; - - -/* public interface */ - -GType gdl_dock_layout_get_type (void); - -GdlDockLayout *gdl_dock_layout_new (GdlDock *dock); - -void gdl_dock_layout_attach (GdlDockLayout *layout, - GdlDockMaster *master); - -gboolean gdl_dock_layout_load_layout (GdlDockLayout *layout, - const gchar *name); - -void gdl_dock_layout_save_layout (GdlDockLayout *layout, - const gchar *name); - -void gdl_dock_layout_delete_layout (GdlDockLayout *layout, - const gchar *name); - -GList *gdl_dock_layout_get_layouts (GdlDockLayout *layout, - gboolean include_default); - -void gdl_dock_layout_run_manager (GdlDockLayout *layout); - -gboolean gdl_dock_layout_load_from_file (GdlDockLayout *layout, - const gchar *filename); - -gboolean gdl_dock_layout_save_to_file (GdlDockLayout *layout, - const gchar *filename); - -gboolean gdl_dock_layout_is_dirty (GdlDockLayout *layout); - -GtkWidget *gdl_dock_layout_get_ui (GdlDockLayout *layout); -GtkWidget *gdl_dock_layout_get_items_ui (GdlDockLayout *layout); -GtkWidget *gdl_dock_layout_get_layouts_ui (GdlDockLayout *layout); - -G_END_DECLS - -#endif - - diff --git a/src/libgdl/gdl.h b/src/libgdl/gdl.h index 467b2b67e..d136b9295 100644 --- a/src/libgdl/gdl.h +++ b/src/libgdl/gdl.h @@ -28,7 +28,6 @@ #include "libgdl/gdl-dock.h" #include "libgdl/gdl-dock-item.h" #include "libgdl/gdl-dock-item-grip.h" -#include "libgdl/gdl-dock-layout.h" #include "libgdl/gdl-dock-bar.h" #endif diff --git a/src/libgdl/test-combo-button.c b/src/libgdl/test-combo-button.c deleted file mode 100644 index 35ce3fff3..000000000 --- a/src/libgdl/test-combo-button.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* test-combo-button.c - * - * Copyright (C) 2003 Jeroen Zwartepoorte - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "gdl-combo-button.h" - -static void -combo_button_activate_default_cb (GdlComboButton *combo, - gpointer data) -{ - g_message ("combo_button_activate_default_cb"); -} - -int -main (int argc, char **argv) -{ - GtkWidget *window, *hbox, *combo, *menu, *menuitem; - GdkPixbuf *icon; - - gtk_init (&argc, &argv); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_signal_connect (G_OBJECT (window), "delete_event", - G_CALLBACK (gtk_main_quit), NULL); - gtk_window_set_title (GTK_WINDOW (window), "Combo button test"); - gtk_window_set_resizable (GTK_WINDOW (window), FALSE); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (window), hbox); - - combo = gtk_button_new_from_stock (GTK_STOCK_OPEN); - gtk_button_set_relief (GTK_BUTTON (combo), GTK_RELIEF_NONE); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - - menu = gtk_menu_new (); - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - gtk_widget_show_all (menu); - - combo = gdl_combo_button_new (); - gdl_combo_button_set_label (GDL_COMBO_BUTTON (combo), "Run"); - gdl_combo_button_set_menu (GDL_COMBO_BUTTON (combo), GTK_MENU (menu)); - icon = gtk_widget_render_icon (combo, GTK_STOCK_EXECUTE, - GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); - gdl_combo_button_set_icon (GDL_COMBO_BUTTON (combo), icon); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - - g_signal_connect (combo, "activate_default", - G_CALLBACK (combo_button_activate_default_cb), NULL); - - combo = gtk_button_new_from_stock (GTK_STOCK_SAVE); - gtk_button_set_relief (GTK_BUTTON (combo), GTK_RELIEF_NONE); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - - menu = gtk_menu_new (); - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - gtk_widget_show_all (menu); - - combo = gdl_combo_button_new (); - gdl_combo_button_set_label (GDL_COMBO_BUTTON (combo), "Open"); - gdl_combo_button_set_menu (GDL_COMBO_BUTTON (combo), GTK_MENU (menu)); - icon = gtk_widget_render_icon (combo, GTK_STOCK_OPEN, - GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); - gdl_combo_button_set_icon (GDL_COMBO_BUTTON (combo), icon); - gtk_widget_set_sensitive (combo, FALSE); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - - g_signal_connect (combo, "activate_default", - G_CALLBACK (combo_button_activate_default_cb), NULL); - - menu = gtk_menu_new (); - combo = gdl_combo_button_new (); - gdl_combo_button_set_label (GDL_COMBO_BUTTON (combo), "Open"); - gdl_combo_button_set_menu (GDL_COMBO_BUTTON (combo), GTK_MENU (menu)); - icon = gtk_widget_render_icon (combo, GTK_STOCK_OPEN, - GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); - gdl_combo_button_set_icon (GDL_COMBO_BUTTON (combo), icon); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - - gtk_widget_show_all (window); - - gtk_main (); - - return 0; -} diff --git a/src/libgdl/test-dock.c b/src/libgdl/test-dock.c deleted file mode 100644 index abaecf703..000000000 --- a/src/libgdl/test-dock.c +++ /dev/null @@ -1,314 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "gdl-tools.h" - -#include "gdl-dock.h" -#include "gdl-dock-item.h" -#include "gdl-dock-notebook.h" -#include "gdl-dock-layout.h" -#include "gdl-dock-placeholder.h" -#include "gdl-dock-bar.h" -#include "gdl-switcher.h" - -#include - -/* ---- end of debugging code */ - -static void -on_style_button_toggled (GtkRadioButton *button, GdlDock *dock) -{ - gboolean active; - GdlDockMaster *master = GDL_DOCK_OBJECT_GET_MASTER (dock); - GdlSwitcherStyle style = - GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), - "__style_id")); - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); - if (active) { - g_object_set (master, "switcher-style", style, NULL); - } -} - -static GtkWidget * -create_style_button (GtkWidget *dock, GtkWidget *box, GtkWidget *group, - GdlSwitcherStyle style, const gchar *style_text) -{ - GdlSwitcherStyle current_style; - GtkWidget *button1; - GdlDockMaster *master = GDL_DOCK_OBJECT_GET_MASTER (dock); - - g_object_get (master, "switcher-style", ¤t_style, NULL); - button1 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (group), - style_text); - gtk_widget_show (button1); - g_object_set_data (G_OBJECT (button1), "__style_id", - GINT_TO_POINTER (style)); - if (current_style == style) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button1), TRUE); - } - g_signal_connect (button1, "toggled", - G_CALLBACK (on_style_button_toggled), - dock); - gtk_box_pack_start (GTK_BOX (box), button1, FALSE, FALSE, 0); - return button1; -} - -static GtkWidget * -create_styles_item (GtkWidget *dock) -{ - GtkWidget *vbox1; - GtkWidget *group; - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_widget_show (vbox1); - - group = create_style_button (dock, vbox1, NULL, - GDL_SWITCHER_STYLE_ICON, "Only icon"); - group = create_style_button (dock, vbox1, group, - GDL_SWITCHER_STYLE_TEXT, "Only text"); - group = create_style_button (dock, vbox1, group, - GDL_SWITCHER_STYLE_BOTH, - "Both icons and texts"); - group = create_style_button (dock, vbox1, group, - GDL_SWITCHER_STYLE_TOOLBAR, - "Desktop toolbar style"); - group = create_style_button (dock, vbox1, group, - GDL_SWITCHER_STYLE_TABS, - "Notebook tabs"); - group = create_style_button (dock, vbox1, group, - GDL_SWITCHER_STYLE_NONE, - "None of the above"); - return vbox1; -} - -static GtkWidget * -create_item (const gchar *button_title) -{ - GtkWidget *vbox1; - GtkWidget *button1; - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_widget_show (vbox1); - - button1 = gtk_button_new_with_label (button_title); - gtk_widget_show (button1); - gtk_box_pack_start (GTK_BOX (vbox1), button1, TRUE, TRUE, 0); - - return vbox1; -} - -/* creates a simple widget with a textbox inside */ -static GtkWidget * -create_text_item () -{ - GtkWidget *vbox1; - GtkWidget *scrolledwindow1; - GtkWidget *text; - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_widget_show (vbox1); - - scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow1); - gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), - GTK_SHADOW_ETCHED_IN); - text = gtk_text_view_new (); - g_object_set (text, "wrap-mode", GTK_WRAP_WORD, NULL); - gtk_widget_show (text); - gtk_container_add (GTK_CONTAINER (scrolledwindow1), text); - - return vbox1; -} - -static void -button_dump_cb (GtkWidget *button, gpointer data) -{ - /* Dump XML tree. */ - gdl_dock_layout_save_to_file (GDL_DOCK_LAYOUT (data), "layout.xml"); - g_spawn_command_line_async ("cat layout.xml", NULL); -} - -static void -run_layout_manager_cb (GtkWidget *w, gpointer data) -{ - GdlDockLayout *layout = GDL_DOCK_LAYOUT (data); - gdl_dock_layout_run_manager (layout); -} - -static void -save_layout_cb (GtkWidget *w, gpointer data) -{ - GdlDockLayout *layout = GDL_DOCK_LAYOUT (data); - GtkWidget *dialog, *hbox, *label, *entry; - gint response; - - dialog = gtk_dialog_new_with_buttons ("New Layout", - NULL, - GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, - GTK_RESPONSE_OK, - NULL); - - hbox = gtk_hbox_new (FALSE, 8); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 8); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); - - label = gtk_label_new ("Name:"); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); - - gtk_widget_show_all (hbox); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - if (response == GTK_RESPONSE_OK) { - const gchar *name = gtk_entry_get_text (GTK_ENTRY (entry)); - gdl_dock_layout_save_layout (layout, name); - } - - gtk_widget_destroy (dialog); -} - -int -main (int argc, char **argv) -{ - GtkWidget *item1, *item2, *item3; - GtkWidget *items [4]; - GtkWidget *win, *table, *button, *box; - int i; - GdlDockLayout *layout; - GtkWidget *dock, *dockbar; - - gtk_init (&argc, &argv); - - /*gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);*/ - - /* window creation */ - win = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_signal_connect (win, "delete_event", - G_CALLBACK (gtk_main_quit), NULL); - gtk_window_set_title (GTK_WINDOW (win), "Docking widget test"); - gtk_window_set_default_size (GTK_WINDOW (win), 400, 400); - - /* table */ - table = gtk_vbox_new (FALSE, 5); - gtk_container_add (GTK_CONTAINER (win), table); - gtk_container_set_border_width (GTK_CONTAINER (table), 10); - - /* create the dock */ - dock = gdl_dock_new (); - - /* ... and the layout manager */ - layout = gdl_dock_layout_new (GDL_DOCK (dock)); - - /* create the dockbar */ - dockbar = gdl_dock_bar_new (GDL_DOCK (dock)); - gdl_dock_bar_set_style(GDL_DOCK_BAR(dockbar), GDL_DOCK_BAR_TEXT); - - box = gtk_hbox_new (FALSE, 5); - gtk_box_pack_start (GTK_BOX (table), box, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), dockbar, FALSE, FALSE, 0); - gtk_box_pack_end (GTK_BOX (box), dock, TRUE, TRUE, 0); - - /* create the dock items */ - item1 = gdl_dock_item_new ("item1", "Item #1", GDL_DOCK_ITEM_BEH_LOCKED); - gtk_container_add (GTK_CONTAINER (item1), create_text_item ()); - gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (item1), - GDL_DOCK_TOP); - gtk_widget_show (item1); - - item2 = gdl_dock_item_new_with_stock ("item2", "Item #2: Select the switcher style for notebooks", - GTK_STOCK_EXECUTE, - GDL_DOCK_ITEM_BEH_NORMAL); - g_object_set (item2, "resize", FALSE, NULL); - gtk_container_add (GTK_CONTAINER (item2), create_styles_item (dock)); - gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (item2), - GDL_DOCK_RIGHT); - gtk_widget_show (item2); - - item3 = gdl_dock_item_new_with_stock ("item3", "Item #3 has accented characters (áéíóúñ)", - GTK_STOCK_CONVERT, - GDL_DOCK_ITEM_BEH_NORMAL | - GDL_DOCK_ITEM_BEH_CANT_CLOSE); - gtk_container_add (GTK_CONTAINER (item3), create_item ("Button 3")); - gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (item3), - GDL_DOCK_BOTTOM); - gtk_widget_show (item3); - - items [0] = gdl_dock_item_new_with_stock ("Item #4", "Item #4", - GTK_STOCK_JUSTIFY_FILL, - GDL_DOCK_ITEM_BEH_NORMAL | - GDL_DOCK_ITEM_BEH_CANT_ICONIFY); - gtk_container_add (GTK_CONTAINER (items [0]), create_text_item ()); - gtk_widget_show (items [0]); - gdl_dock_add_item (GDL_DOCK (dock), GDL_DOCK_ITEM (items [0]), GDL_DOCK_BOTTOM); - for (i = 1; i < 3; i++) { - gchar name[10]; - - snprintf (name, sizeof (name), "Item #%d", i + 4); - items [i] = gdl_dock_item_new_with_stock (name, name, GTK_STOCK_NEW, - GDL_DOCK_ITEM_BEH_NORMAL); - gtk_container_add (GTK_CONTAINER (items [i]), create_text_item ()); - gtk_widget_show (items [i]); - - gdl_dock_object_dock (GDL_DOCK_OBJECT (items [0]), - GDL_DOCK_OBJECT (items [i]), - GDL_DOCK_CENTER, NULL); - }; - - /* tests: manually dock and move around some of the items */ - gdl_dock_item_dock_to (GDL_DOCK_ITEM (item3), GDL_DOCK_ITEM (item1), - GDL_DOCK_TOP, -1); - - gdl_dock_item_dock_to (GDL_DOCK_ITEM (item2), GDL_DOCK_ITEM (item3), - GDL_DOCK_RIGHT, -1); - - gdl_dock_item_dock_to (GDL_DOCK_ITEM (item2), GDL_DOCK_ITEM (item3), - GDL_DOCK_LEFT, -1); - - gdl_dock_item_dock_to (GDL_DOCK_ITEM (item2), NULL, - GDL_DOCK_FLOATING, -1); - - box = gtk_hbox_new (TRUE, 5); - gtk_box_pack_end (GTK_BOX (table), box, FALSE, FALSE, 0); - - button = gtk_button_new_from_stock (GTK_STOCK_SAVE); - g_signal_connect (button, "clicked", - G_CALLBACK (save_layout_cb), layout); - gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0); - - button = gtk_button_new_with_label ("Layout Manager"); - g_signal_connect (button, "clicked", - G_CALLBACK (run_layout_manager_cb), layout); - gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0); - - button = gtk_button_new_with_label ("Dump XML"); - g_signal_connect (button, "clicked", - G_CALLBACK (button_dump_cb), layout); - gtk_box_pack_end (GTK_BOX (box), button, FALSE, TRUE, 0); - - gtk_widget_show_all (win); - - gdl_dock_placeholder_new ("ph1", GDL_DOCK_OBJECT (dock), GDL_DOCK_TOP, FALSE); - gdl_dock_placeholder_new ("ph2", GDL_DOCK_OBJECT (dock), GDL_DOCK_BOTTOM, FALSE); - gdl_dock_placeholder_new ("ph3", GDL_DOCK_OBJECT (dock), GDL_DOCK_LEFT, FALSE); - gdl_dock_placeholder_new ("ph4", GDL_DOCK_OBJECT (dock), GDL_DOCK_RIGHT, FALSE); - - gtk_main (); - - g_object_unref (layout); - - return 0; -} -- cgit v1.2.3 From 2b83f175e30021735625712d580adf0e3dd7077f Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 11 Jul 2011 07:49:37 -0700 Subject: Clean up more whiteboard stuff and fix header name in file (bzr r10441) --- src/color-profile-test.h | 2 +- src/ui/dialog/session-player.cpp | 231 --------------------------------------- src/ui/dialog/session-player.h | 134 ----------------------- 3 files changed, 1 insertion(+), 366 deletions(-) delete mode 100644 src/ui/dialog/session-player.cpp delete mode 100644 src/ui/dialog/session-player.h (limited to 'src') diff --git a/src/color-profile-test.h b/src/color-profile-test.h index 4b679e5b7..b3ead5d55 100644 --- a/src/color-profile-test.h +++ b/src/color-profile-test.h @@ -9,7 +9,7 @@ #include "color-profile.h" -#include "color-profile-fns.h" +#include "cms-system.h" class ColorProfileTest : public CxxTest::TestSuite { diff --git a/src/ui/dialog/session-player.cpp b/src/ui/dialog/session-player.cpp deleted file mode 100644 index 040c1419b..000000000 --- a/src/ui/dialog/session-player.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/** @file - * @brief Whiteboard session playback control dialog - implementation - */ -/* Authors: - * David Yip - * Abhishek Sharma - * - * Copyright (c) 2005 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -#include "inkscape.h" -#include "path-prefix.h" - -#include "desktop.h" -#include "desktop-handles.h" -#include "document.h" - -#include "jabber_whiteboard/node-tracker.h" -#include "jabber_whiteboard/session-manager.h" -#include "jabber_whiteboard/session-file-player.h" - -#include "ui/dialog/session-player.h" - -#include "util/ucompose.hpp" - -namespace Inkscape { - -namespace UI { - -namespace Dialog { - -SessionPlaybackDialog* -SessionPlaybackDialog::create() -{ - return new SessionPlaybackDialogImpl(); -} - -SessionPlaybackDialogImpl::SessionPlaybackDialogImpl() - : _delay(100, 1, 5000, 10, 100), _delayentry(_delay) -{ - this->_desktop = this->getDesktop(); - this->_sm = this->_desktop->whiteboard_session_manager(); - this->_sfp = this->_sm->session_player(); - this->_openfile.set_text(this->_sfp->filename()); - - this->_construct(); - this->get_vbox()->show_all_children(); -} - -SessionPlaybackDialogImpl::~SessionPlaybackDialogImpl() -{ - -} - -void -SessionPlaybackDialogImpl::_construct() -{ - Gtk::VBox* main = this->get_vbox(); - - // Dialog organization - this->_filemanager.set_label(_("Session file")); - this->_playback.set_label(_("Playback controls")); - this->_currentmsgbox.set_label(_("Message information")); - - this->_filemanager.set_border_width(4); - this->_playback.set_border_width(4); - this->_fm.set_border_width(4); - this->_toolbarbox.set_border_width(4); - - // Active session file display - // fixme: Does this mean the active file for the session, or the file for the active session? - // Please indicate which with a TRANSLATORS comment. - this->_labels[0].set_text(_("Active session file:")); - this->_labels[1].set_text(_("Delay (milliseconds):")); - - this->_openfile.set_editable(false); - - this->_filebox.pack_start(this->_labels[0], true, false, 8); - this->_filebox.pack_end(this->_openfile, true, true, 0); - - // Unload/load buttons - this->_close.set_label(_("Close file")); - this->_open.set_label(_("Open new file")); - this->_setdelay.set_label(_("Set delay")); - - // Attach callbacks - this->_close.signal_clicked().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), CLOSE_FILE)); - this->_open.signal_clicked().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), OPEN_FILE)); - this->_setdelay.signal_clicked().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), RESET_DELAY)); - - // Button box - this->_filebuttons.pack_start(this->_close, true, false, 0); - this->_filebuttons.pack_start(this->_open, true, false, 0); - - // Message information box - this->_currentmsgbuffer = Gtk::TextBuffer::create(); - this->_currentmsgview.set_buffer(this->_currentmsgbuffer); - this->_currentmsgview.set_editable(false); - this->_currentmsgview.set_cursor_visible(false); - this->_currentmsgview.set_wrap_mode(Gtk::WRAP_WORD); - this->_currentmsgscroller.add(this->_currentmsgview); - this->_currentmsgbox.add(this->_currentmsgscroller); - this->_sfp->setMessageOutputWidget(this->_currentmsgbuffer); - - // Delay setting - // parameters: initial lower upper single-incr page-incr - this->_delayentry.set_numeric(true); - - // Playback controls - this->_playbackcontrols.set_show_arrow(false); - - this->_controls[0].set_label("Rewind"); - this->_controls[1].set_label("Go back one"); - this->_controls[2].set_label("Pause"); - this->_controls[3].set_label("Go forward one"); - this->_controls[4].set_label("Play"); - - this->_controls[0].set_tooltip(this->_tooltips, _("Rewind")); - this->_controls[1].set_tooltip(this->_tooltips, _("Go back one change")); - this->_controls[2].set_tooltip(this->_tooltips, _("Pause")); - this->_controls[3].set_tooltip(this->_tooltips, _("Go forward one change")); - this->_controls[4].set_tooltip(this->_tooltips, _("Play")); - - for(int i = 0; i < 5; i++) { - this->_playbackcontrols.append(this->_controls[i], sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), TOOLBAR_BASE + i)); - } - - this->_delaybox.pack_start(this->_labels[1]); - this->_delaybox.pack_start(this->_delayentry); - this->_delaybox.pack_end(this->_setdelay); - - this->_toolbarbox.pack_start(this->_delaybox); - this->_toolbarbox.pack_end(this->_playbackcontrols); - - // Pack widgets into frames - this->_fm.pack_start(this->_filebox); - this->_fm.pack_end(this->_filebuttons); - - this->_filemanager.add(this->_fm); - this->_playback.add(this->_toolbarbox); - - // Pack widgets into main vbox - main->pack_start(this->_filemanager); - main->pack_start(this->_playback); - main->pack_end(this->_currentmsgbox); -} - -void -SessionPlaybackDialogImpl::_respCallback(int resp) -{ - g_log(NULL, G_LOG_LEVEL_DEBUG, "_respCallback: %u", resp); - switch(resp) { - case CLOSE_FILE: - this->_sfp->unload(); - break; - case OPEN_FILE: { - Gtk::FileChooserDialog sessionfiledlg(_("Open session file"), Gtk::FILE_CHOOSER_ACTION_OPEN); - sessionfiledlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - sessionfiledlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - int result = sessionfiledlg.run(); - switch (result) { - case Gtk::RESPONSE_OK: - this->_sm->clearDocument(); - SPDocumentUndo::done(sp_desktop_document(this->_desktop), SP_VERB_NONE, - /* TODO: annotate */ "session-player.cpp:186"); - this->_sm->loadSessionFile(sessionfiledlg.get_filename()); - this->_openfile.set_text(this->_sfp->filename()); - break; - default: - break; - } - break; - } - case RESET_DELAY: - this->_sfp->setDelay(this->_delayentry.get_value_as_int()); - break; - case REWIND: - if (this->_sfp->_playing) { - this->_sfp->stop(); - } - this->_sfp->_curdir = Whiteboard::SessionFilePlayer::BACKWARD; - this->_sfp->start(); - break; - case STEP_REWIND: - this->_sfp->step(Whiteboard::SessionFilePlayer::BACKWARD); - break; - case PAUSE: - this->_sfp->stop(); - break; - case STEP_PLAY: - this->_sfp->step(Whiteboard::SessionFilePlayer::FORWARD); - break; - case PLAY: - if (this->_sfp->_playing) { - this->_sfp->stop(); - } - this->_sfp->_curdir = Whiteboard::SessionFilePlayer::FORWARD; - this->_sfp->start(); - break; - default: - break; - } -} - -} - -} - -} - -/* - 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/ui/dialog/session-player.h b/src/ui/dialog/session-player.h deleted file mode 100644 index 2d235cd25..000000000 --- a/src/ui/dialog/session-player.h +++ /dev/null @@ -1,134 +0,0 @@ -/** @file - * @brief Whiteboard session playback control dialog - */ -/* Authors: - * David Yip - * - * Copyright (c) 2005 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef __SESSION_PLAYBACK_DIALOG_H__ -#define __SESSION_PLAYBACK_DIALOG_H__ - -#include "verbs.h" -#include "dialog.h" - -#include "gtkmm/toolbutton.h" -#include "gtkmm/toolbar.h" -#include "gtkmm/expander.h" - -#include "ui/widget/icon-widget.h" - -struct SPDesktop; - -namespace Inkscape { - -namespace Whiteboard { - -class SessionManager; -class SessionFilePlayer; - -} - -namespace UI { - -namespace Dialog { - -class SessionPlaybackDialog : public Dialog { -public: - SessionPlaybackDialog() : Dialog("/dialogs/session_playback", SP_VERB_DIALOG_WHITEBOARD_SESSIONPLAYBACK) - { - - } - - static SessionPlaybackDialog* create(); - - virtual ~SessionPlaybackDialog() - { - - } -private: - SessionPlaybackDialog(SessionPlaybackDialog const& dlg); // no copy - void operator=(SessionPlaybackDialog const& dlg); // no assign -}; - -class SessionPlaybackDialogImpl : public SessionPlaybackDialog { -public: - SessionPlaybackDialogImpl(); - ~SessionPlaybackDialogImpl(); - -private: - // GTK+ widgets - Gtk::HBox _filebox; - Gtk::HBox _filebuttons; - Gtk::HBox _toolbarbox; - Gtk::HBox _delaybox; - - Gtk::Entry _openfile; - - Gtk::Label _labels[2]; - Gtk::ToolButton _controls[5]; - - Gtk::Button _close, _open, _setdelay; - - Gtk::Tooltips _tooltips; - Gtk::Toolbar _playbackcontrols; - Gtk::Adjustment _delay; - Widget::SpinButton _delayentry; - - Gtk::Frame _filemanager; - Gtk::VBox _fm; - - Gtk::Frame _playback; - - Gtk::Expander _currentmsgbox; - Glib::RefPtr _currentmsgbuffer; - Gtk::TextView _currentmsgview; - Gtk::ScrolledWindow _currentmsgscroller; - - // Construction and callback - void _construct(); - void _respCallback(int resp); - - // SessionManager and SPDesktop pointers - ::SPDesktop* _desktop; - Whiteboard::SessionManager* _sm; - Whiteboard::SessionFilePlayer* _sfp; - - // button values - static unsigned short const CLOSE_FILE = 0; - static unsigned short const OPEN_FILE = 1; - static unsigned short const RESET_DELAY = 2; - - static unsigned short const TOOLBAR_BASE = 10; - static unsigned short const REWIND = TOOLBAR_BASE + 0; - static unsigned short const STEP_REWIND = TOOLBAR_BASE + 1; - static unsigned short const PAUSE = TOOLBAR_BASE + 2; - static unsigned short const STEP_PLAY = TOOLBAR_BASE + 3; - static unsigned short const PLAY = TOOLBAR_BASE + 4; - - - // noncopyable - SessionPlaybackDialogImpl(SessionPlaybackDialogImpl const& dlg); // no copy - void operator=(SessionPlaybackDialogImpl const& dlg); // no assign -}; - -} - -} - -} - -#endif - -/* - 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 : -- cgit v1.2.3 From 6ffe6f384a2d322451cb21e720effdae7aa904f0 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Mon, 11 Jul 2011 20:44:59 +0200 Subject: Fix crash caused by my previous commit; as reported by ~suv in bug lp:212768 Fixed bugs: - https://launchpad.net/bugs/212768 (bzr r10443) --- src/sp-item-transform.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index 45d965e44..eb4b81a61 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -183,11 +183,11 @@ get_scale_transform_with_uniform_stroke (Geom::Rect const &bbox_visual, gdouble scale *= direct; } } else { // The stroke should not be scaled, or is zero - if (!transform_stroke) { // Nonscaling strokewidth + if (r0 == 0 || r0 == Geom::infinity() ) { // Strokewidth is zero or infinite + scale *= direct; + } else { // Nonscaling strokewidth scale *= direct_constant_r; unbudge *= Geom::Translate (flip_x * 0.5 * r0 * (1 - ratio_x), flip_y * 0.5 * r0 * (1 - ratio_y)); - } else { // Strokewidth is zero or infinite - scale *= direct; } } @@ -336,11 +336,11 @@ get_scale_transform_with_unequal_stroke (Geom::Rect const &bbox_visual, Geom::Re scale *= direct; } } else { // The stroke should not be scaled, or is zero (or infinite) - if (!transform_stroke) { + if (r0w == 0 || r0w == Geom::infinity() || r0h == 0 || r0h == Geom::infinity()) { // can't calculate, because apparently strokewidth is zero or infinite + scale *= direct; + } else { scale *= direct_constant_r; unbudge *= Geom::Translate (flip_x * stroke_ratio_w * r0w * (1 - ratio_x), flip_y * stroke_ratio_h * r0h * (1 - ratio_y)); - } else { // can't calculate, because apparently strokewidth is zero or infinite - scale *= direct; } } @@ -350,7 +350,6 @@ get_scale_transform_with_unequal_stroke (Geom::Rect const &bbox_visual, Geom::Re Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Affine const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke) { - g_assert(initial_geom_bbox); // Find the new geometric bounding box; Do this by transforming each corner of -- cgit v1.2.3 From bcab15a0a88931f0cf2374ab0b76877e90f7f76c Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Tue, 12 Jul 2011 22:26:46 +0200 Subject: GUI uniformisation (bzr r10446) --- src/ui/dialog/filter-effects-dialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index c6d81b070..68cf3b505 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -965,10 +965,10 @@ public: _settings.add_spinslider(0, SP_ATTR_ELEVATION, _("Elevation"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the YZ plane, in degrees")); _settings.type(LIGHT_POINT); - _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); + _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location:"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); _settings.type(LIGHT_SPOT); - _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); + _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location:"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_POINTSATX, SP_ATTR_POINTSATY, SP_ATTR_POINTSATZ, _("Points At"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); -- cgit v1.2.3 From f2c03a756afd46b6ff2b35720442a853649b65c3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jul 2011 22:00:48 +1000 Subject: update cmake for new files (bzr r10447) --- src/libgdl/CMakeLists.txt | 10 +++++----- src/ui/CMakeLists.txt | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libgdl/CMakeLists.txt b/src/libgdl/CMakeLists.txt index befb6edb7..3457337e9 100644 --- a/src/libgdl/CMakeLists.txt +++ b/src/libgdl/CMakeLists.txt @@ -1,17 +1,17 @@ set(libgdl_SRC - gdl-dock.c gdl-dock-bar.c - gdl-dock-item.c + gdl-dock-item-button-image.c gdl-dock-item-grip.c + gdl-dock-item.c gdl-dock-master.c gdl-dock-notebook.c gdl-dock-object.c gdl-dock-paned.c gdl-dock-placeholder.c gdl-dock-tablabel.c + gdl-dock.c gdl-i18n.c - gdl-stock.c gdl-switcher.c gdl-tools.h libgdlmarshal.c @@ -21,6 +21,7 @@ set(libgdl_SRC # ------- # Headers gdl-dock-bar.h + gdl-dock-item-button-image.h gdl-dock-item-grip.h gdl-dock-item.h gdl-dock-master.h @@ -32,9 +33,8 @@ set(libgdl_SRC gdl-dock.h gdl-i18n.h gdl-stock-icons.h - gdl-stock.h gdl-switcher.h - libgdl.h + gdl.h libgdlmarshal.h libgdltypebuiltins.h ) diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 9bbdd861e..1a662f3be 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -159,7 +159,6 @@ set(ui_SRC dialog/print-colors-preview-dialog.h dialog/print.h dialog/scriptdialog.h - dialog/session-player.h dialog/svg-fonts-dialog.h dialog/swatches.h dialog/tile.h -- cgit v1.2.3 From 9323663d8412d926c6a868b5fc89f2b354cf77bc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 13 Jul 2011 13:04:36 +0200 Subject: Properly handle CSS font shorthand property. Work done with Abhishek Sharma for GSOC. (bzr r10448) --- src/style.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 143 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/style.cpp b/src/style.cpp index 699b087dd..303b347c4 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -6,6 +6,7 @@ * Peter Moulder * bulia byak * Abhishek Sharma + * Tavmjong Bah * * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. @@ -911,8 +912,137 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) style->text->font.value = g_strdup(val); style->text->font.set = TRUE; style->text->font.inherit = (val && !strcmp(val, "inherit")); + + // Break string into white space separated tokens + std::stringstream os( val ); + Glib::ustring param; + + while (os >> param) { + + // CSS is case insensitive but we're comparing against lowercase strings + Glib::ustring lparam = param.lowercase(); + + if (lparam == "/") { + + os >> param; + // Eat the line-height for the moment as it is not an SVG property. + // lparam = param.lowercase(); + // sp_style_read_ilengthornormal(&style->line_height, lparam); + + } else { + + // Skip if "normal" as that is the default (and we don't know which attribute it applies to). + if (lparam == "normal") continue; + + // Check each property in turn + + // font-style + SPIEnum test_style; + test_style.set = FALSE; + + // Read once to see if param is valid style. If valid, .set will be TRUE. + sp_style_read_ienum(&test_style, lparam.c_str(), enum_font_style, true); + + // If valid style parameter + if (test_style.set) { + + // If not previously set + if (!style->font_style.set) { + style->font_style.set = TRUE; + style->font_style.inherit = test_style.inherit; + style->font_style.value = test_style.value; + style->font_style.computed = test_style.computed; + } + continue; // Next parameter. + } + + // font-variant (small-caps) + SPIEnum test_variant; + test_variant.set = FALSE; + sp_style_read_ienum(&test_variant, lparam.c_str(), enum_font_variant, true); + + // If valid variant parameter + if (test_variant.set) { + + // If not previously set + if (!style->font_variant.set) { + style->font_variant.set = TRUE; + style->font_variant.inherit = test_variant.inherit; + style->font_variant.value = test_variant.value; + style->font_variant.computed = test_variant.computed; + } + continue; // Next parameter. + } + + // font-weight + SPIEnum test_weight; + test_weight.set = FALSE; + sp_style_read_ienum(&test_weight, lparam.c_str(), enum_font_weight, true); + + // If valid weight parameter + if (test_weight.set) { + + // If not previously set + if (!style->font_weight.set) { + style->font_weight.set = TRUE; + style->font_weight.inherit = test_weight.inherit; + style->font_weight.value = test_weight.value; + style->font_weight.computed = test_weight.computed; + } + continue; // Next parameter + } + + // Font-size + SPIFontSize test_size; + test_size.set = FALSE; + + // Read once to see if param is valid size. + sp_style_read_ifontsize( &test_size, lparam.c_str() ); + + // If valid size parameter + if (test_size.set) { + + // If not previously set + if (!style->font_size.set) { + style->font_size.set = TRUE; + style->font_size.inherit = test_size.inherit; + style->font_size.unit = test_size.unit; + style->font_size.value = test_size.value; + style->font_size.computed = test_size.computed; + style->font_size.type = test_size.type; + style->font_size.literal = test_size.literal; + } + continue; + } + + // No valid property value found. + break; + } + } // params + + // The rest must be font-family... + std::string val_s = val; + std::string family = val_s.substr( val_s.find( param ) ); + + if (!style->text_private) sp_style_privatize_text(style); + if (!style->text->font_family.set) { + gchar *val_unquoted = attribute_unquote( family.c_str() ); + sp_style_read_istring(&style->text->font_family, val_unquoted); + if (val_unquoted) g_free (val_unquoted); + } + + // Set all properties to their default values per CSS 2.1 spec if not already set + SPS_READ_IFONTSIZE_IF_UNSET(&style->font_size, "medium" ); + SPS_READ_IENUM_IF_UNSET(&style->font_style, "normal", enum_font_style, true); + SPS_READ_IENUM_IF_UNSET(&style->font_variant, "normal", enum_font_variant, true); + SPS_READ_IENUM_IF_UNSET(&style->font_weight, "normal", enum_font_weight, true); + // Line height is not an SVG property but Inkscape uses it for multi-line text. + // sp_style_read_ilengthornormal(&style->line_height, "normal"); + } + break; + /* Text */ case SP_PROP_TEXT_INDENT: SPS_READ_ILENGTH_IF_UNSET(&style->text_indent, val); @@ -3109,9 +3239,8 @@ sp_style_read_ilength(SPILength *val, gchar const *str) val->unit = SP_CSS_UNIT_PT; val->computed = value * PX_PER_PT; } else if (!strcmp(e, "pc")) { - /* 1 pica = 12pt; FIXME: add it to SPUnit */ val->unit = SP_CSS_UNIT_PC; - val->computed = value * PX_PER_PT * 12; + val->computed = value * PX_PER_PC; } else if (!strcmp(e, "mm")) { val->unit = SP_CSS_UNIT_MM; val->computed = value * PX_PER_MM; @@ -3335,16 +3464,19 @@ sp_style_read_ifontsize(SPIFontSize *val, gchar const *str) return; } else { SPILength length; + length.set = FALSE; sp_style_read_ilength(&length, str); - val->set = length.set; - val->inherit = length.inherit; - val->unit = length.unit; - val->value = length.value; - val->computed = length.computed; - if( val->unit == SP_CSS_UNIT_PERCENT ) { - val->type = SP_FONT_SIZE_PERCENTAGE; - } else { - val->type = SP_FONT_SIZE_LENGTH; + if( length.set ) { + val->set = TRUE; + val->inherit = length.inherit; + val->unit = length.unit; + val->value = length.value; + val->computed = length.computed; + if( val->unit == SP_CSS_UNIT_PERCENT ) { + val->type = SP_FONT_SIZE_PERCENTAGE; + } else { + val->type = SP_FONT_SIZE_LENGTH; + } } return; } -- cgit v1.2.3 From 6973283a77d7becd6a5a1bd7396206c6840ca785 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 13 Jul 2011 23:43:55 +0200 Subject: Fix crashes in print preview Fixed bugs: - https://launchpad.net/bugs/806105 (bzr r10450) --- src/display/cairo-utils.cpp | 12 ++++++++++++ src/display/cairo-utils.h | 1 + src/extension/internal/cairo-renderer.cpp | 8 +++++--- src/helper/pixbuf-ops.cpp | 5 +++-- src/ui/cache/svg_preview_cache.cpp | 3 +-- src/ui/dialog/color-item.cpp | 4 ++-- 6 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 90f65c33e..8b75f09a6 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -345,6 +345,18 @@ ink_cairo_surface_create_for_argb32_pixbuf(GdkPixbuf *pb) return pbs; } +/** @brief Cleanup function for GdkPixbuf. + * This function should be passed as the GdkPixbufDestroyNotify parameter + * to gdk_pixbuf_new_from_data when creating a GdkPixbuf backed by + * a Cairo surface. + */ +void +ink_cairo_pixbuf_cleanup(guchar *pixels, void *data) +{ + cairo_surface_t *surface = reinterpret_cast(data); + cairo_surface_destroy(surface); +} + /** @brief Create an exact copy of a surface. * Creates a surface that has the same type, content type, dimensions and contents * as the specified surface. */ diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 0c2ac2dd6..1de88785d 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -106,6 +106,7 @@ void convert_pixels_argb32_to_pixbuf(guchar *data, int w, int h, int rs); void convert_pixbuf_normal_to_argb32(GdkPixbuf *); void convert_pixbuf_argb32_to_normal(GdkPixbuf *); cairo_surface_t *ink_cairo_surface_create_for_argb32_pixbuf(GdkPixbuf *pb); +void ink_cairo_pixbuf_cleanup(guchar *pixels, void *surface); G_GNUC_CONST guint32 argb32_from_pixbuf(guint32 in); G_GNUC_CONST guint32 pixbuf_from_argb32(guint32 in); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 6118a7ae9..1e550f7d1 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -475,9 +475,11 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) } // The width and height of the bitmap in pixels - unsigned width = (unsigned) floor ((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); - unsigned height =(unsigned) floor ((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN)); - + unsigned width = ceil((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); + unsigned height = ceil((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN)); + + if (width == 0 || height == 0) return; + // Scale to exactly fit integer bitmap inside bounding box double scale_x = (bbox->max()[Geom::X] - bbox->min()[Geom::X]) / width; double scale_y = (bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) / height; diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index f6796f2ad..9ebbe13c7 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -107,6 +107,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, GSList *items_only) { + if (width == 0 || height == 0) return NULL; GdkPixbuf* pixbuf = NULL; /* Create new arena for offscreen rendering*/ @@ -167,8 +168,8 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(surface), GDK_COLORSPACE_RGB, TRUE, 8, width, height, cairo_image_surface_get_stride(surface), - (GdkPixbufDestroyNotify) cairo_surface_destroy, - NULL); + ink_cairo_pixbuf_cleanup, + surface); convert_pixbuf_argb32_to_normal(pixbuf); } else diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index fd7070bab..edd7c9431 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -79,8 +79,7 @@ GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rec GDK_COLORSPACE_RGB, TRUE, 8, psize, psize, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify)cairo_surface_destroy, - NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); return pixbuf; diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 3463aa496..598827da9 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -225,7 +225,7 @@ static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpoin pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, width, height, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); } else { Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); @@ -533,7 +533,7 @@ void ColorItem::_regenPreview(EekPreview * preview) GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, w, h, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); eek_preview_set_pixbuf( preview, pixbuf ); } -- cgit v1.2.3