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 }