File indexing completed on 2024-04-21 05:47:02

0001 /*****************************************************************************
0002  *   Copyright 2003 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 
0023 #include "widgetmap.h"
0024 
0025 #include <qtcurve-utils/gtkprops.h>
0026 
0027 #include <unordered_map>
0028 
0029 namespace QtCurve {
0030 namespace WidgetMap {
0031 
0032 typedef std::unordered_map<GtkWidget*, GObjWeakRef> WidgetMap;
0033 static WidgetMap widget_map[2];
0034 
0035 template<typename Id>
0036 static inline bool
0037 getMapHacked(const GtkWidgetProps &props, Id &id)
0038 {
0039     return props->widgetMapHacked & (id ? (1 << 1) : (1 << 0));
0040 }
0041 
0042 template<typename Id>
0043 static inline void
0044 setMapHacked(const GtkWidgetProps &props, Id &id)
0045 {
0046     props->widgetMapHacked |= id ? (1 << 1) : (1 << 0);
0047 }
0048 
0049 static GtkWidget*
0050 lookupHash(GtkWidget *hash, GtkWidget *value, int map)
0051 {
0052     auto it = widget_map[map].find(hash);
0053     GtkWidget *rv = (it != widget_map[map].end() ?
0054                      (*it).second.get<GtkWidget>() : nullptr);
0055     if (!rv && value) {
0056         widget_map[map].emplace(std::piecewise_construct,
0057                                 std::forward_as_tuple(hash),
0058                                 std::forward_as_tuple(value));
0059         rv = value;
0060     }
0061     return rv;
0062 }
0063 
0064 static void
0065 removeHash(GtkWidget *hash)
0066 {
0067     for (int i = 0;i < 2;++i) {
0068         widget_map[i].erase(hash);
0069     }
0070 }
0071 
0072 static void
0073 cleanup(GtkWidget *widget)
0074 {
0075     GtkWidgetProps props(widget);
0076     if (props->widgetMapHacked) {
0077         props->widgetMapDestroy.disconn();
0078         props->widgetMapUnrealize.disconn();
0079         props->widgetMapStyleSet.disconn();
0080         props->widgetMapHacked = 0;
0081         removeHash(widget);
0082     }
0083 }
0084 
0085 static gboolean
0086 styleSet(GtkWidget *widget, GtkStyle*, void*)
0087 {
0088     cleanup(widget);
0089     return false;
0090 }
0091 
0092 static gboolean
0093 destroy(GtkWidget *widget, GdkEvent*, void*)
0094 {
0095     cleanup(widget);
0096     return false;
0097 }
0098 
0099 void
0100 setup(GtkWidget *from, GtkWidget *to, int map)
0101 {
0102     GtkWidgetProps fromProps(from);
0103     if (from && to && !getMapHacked(fromProps, map)) {
0104         if (!fromProps->widgetMapHacked) {
0105             fromProps->widgetMapDestroy.conn("destroy-event", destroy);
0106             fromProps->widgetMapUnrealize.conn("unrealize", destroy);
0107             fromProps->widgetMapStyleSet.conn("style-set", styleSet);
0108         }
0109         setMapHacked(fromProps, map);
0110         lookupHash(from, to, map);
0111     }
0112 }
0113 
0114 GtkWidget*
0115 getWidget(GtkWidget *widget, int map)
0116 {
0117     GtkWidgetProps props(widget);
0118     return (widget && getMapHacked(props, map) ?
0119             lookupHash(widget, nullptr, map) : nullptr);
0120 }
0121 
0122 }
0123 }