File indexing completed on 2024-04-28 05:46:49

0001 /*****************************************************************************
0002  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0003  *                                                                           *
0004  *   This program is free software; you can redistribute it and/or modify    *
0005  *   it under the terms of the GNU Lesser General Public License as          *
0006  *   published by the Free Software Foundation; either version 2.1 of the    *
0007  *   License, or (at your option) version 3, or any later version accepted   *
0008  *   by the membership of KDE e.V. (or its successor approved by the         *
0009  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0010  *   Section 6 of version 3 of the license.                                  *
0011  *                                                                           *
0012  *   This program is distributed in the hope that it will be useful,         *
0013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0015  *   Lesser General Public License for more details.                         *
0016  *                                                                           *
0017  *   You should have received a copy of the GNU Lesser General Public        *
0018  *   License along with this library. If not,                                *
0019  *   see <http://www.gnu.org/licenses/>.                                     *
0020  *****************************************************************************/
0021 
0022 #ifndef __QTC_UTILS_GTK_UTILS_H__
0023 #define __QTC_UTILS_GTK_UTILS_H__
0024 
0025 #include "utils.h"
0026 #include <gtk/gtk.h>
0027 
0028 namespace QtCurve {
0029 namespace Widget {
0030 
0031 static inline cairo_rectangle_int_t
0032 getAllocation(GtkWidget *widget)
0033 {
0034     cairo_rectangle_int_t alloc;
0035     // Binary compatible
0036     gtk_widget_get_allocation(widget, (GdkRectangle*)&alloc);
0037     return alloc;
0038 }
0039 
0040 static inline GtkRequisition
0041 getRequisition(GtkWidget *widget)
0042 {
0043     GtkRequisition req;
0044 #if GTK_CHECK_VERSION(3, 0, 0)
0045     gtk_widget_get_preferred_size(widget, &req, nullptr);
0046 #else
0047     gtk_widget_get_requisition(widget, &req);
0048 #endif
0049     return req;
0050 }
0051 
0052 static inline GtkOrientation
0053 getOrientation(GtkWidget *widget)
0054 {
0055     return gtk_orientable_get_orientation(GTK_ORIENTABLE(widget));
0056 }
0057 
0058 static inline bool
0059 isHorizontal(GtkWidget *widget)
0060 {
0061     return getOrientation(widget) == GTK_ORIENTATION_HORIZONTAL;
0062 }
0063 
0064 }
0065 
0066 static inline float
0067 qtcFrameGetLabelYAlign(GtkFrame *f)
0068 {
0069     float x, y;
0070     gtk_frame_get_label_align(f, &x, &y);
0071     return y;
0072 }
0073 
0074 static inline bool
0075 qtcIsProgressBar(GtkWidget *w)
0076 {
0077 #if GTK_CHECK_VERSION(3, 0, 0)
0078     if (!GTK_IS_PROGRESS_BAR(w)) {
0079         return false;
0080     }
0081 #else
0082     if (!GTK_IS_PROGRESS(w)) {
0083         return false;
0084     }
0085 #endif
0086     GtkAllocation alloc;
0087     gtk_widget_get_allocation(w, &alloc);
0088     return alloc.x != -1 && alloc.y != -1;
0089 }
0090 
0091 template<typename T>
0092 static inline const char*
0093 gTypeName(T *obj)
0094 {
0095     if (qtcUnlikely(!obj))
0096         return "";
0097     return qtcDefault(G_OBJECT_TYPE_NAME(obj), "");
0098 }
0099 
0100 struct GObjectDeleter {
0101     template<typename T>
0102     inline void
0103     operator()(T *p)
0104     {
0105         g_object_unref(p);
0106     }
0107     template<typename T>
0108     inline void
0109     ref(T *p)
0110     {
0111         g_object_ref_sink(p);
0112     }
0113 };
0114 
0115 template<typename T, typename D>
0116 class RefPtr : public std::unique_ptr<T, D> {
0117 public:
0118     constexpr
0119     RefPtr()
0120         : std::unique_ptr<T, D>()
0121     {
0122     }
0123     RefPtr(T *p)
0124         : std::unique_ptr<T, D>(p)
0125     {
0126         if (p) {
0127             this->get_deleter().ref(p);
0128         }
0129     }
0130     RefPtr(const RefPtr &other)
0131         : RefPtr(other.get())
0132     {
0133     }
0134     RefPtr(RefPtr &&other)
0135         : std::unique_ptr<T, D>(std::move(other))
0136     {
0137     }
0138     RefPtr&
0139     operator=(RefPtr &&other)
0140     {
0141         std::unique_ptr<T, D>::operator=(std::move(other));
0142         return *this;
0143     }
0144 };
0145 
0146 template<typename ObjType=GObject>
0147 using GObjPtr = RefPtr<ObjType, GObjectDeleter>;
0148 
0149 class GObjWeakRef {
0150     GObjWeakRef() = delete;
0151     GObjWeakRef(const GObjWeakRef&) = delete;
0152     GObject *m_obj;
0153     static void
0154     destroyCb(void *_that, GObject*)
0155     {
0156         GObjWeakRef *that = (GObjWeakRef*)_that;
0157         that->m_obj = nullptr;
0158     }
0159 public:
0160     template<typename T>
0161     GObjWeakRef(T *obj)
0162         : m_obj((GObject*)obj)
0163     {
0164         if (m_obj) {
0165             g_object_weak_ref(m_obj, destroyCb, this);
0166         }
0167     }
0168     ~GObjWeakRef()
0169     {
0170         if (m_obj) {
0171             g_object_weak_unref(m_obj, destroyCb, this);
0172         }
0173     }
0174     template<typename T=GObject>
0175     inline T*
0176     get()
0177     {
0178         return (T*)m_obj;
0179     }
0180 };
0181 
0182 }
0183 
0184 #endif