1 // $Id: image.cc,v 1.33 2004/05/14 10:01:24 christof Exp $
2 /* glade--: C++ frontend for glade (Gtk+ User Interface Builder)
3 * Copyright (C) 1998 Christof Petig
4 * Copyright (C) 1999-2000 Adolf Petig GmbH & Co. KG, written by Christof Petig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include "misc.hh"
22 #include <fstream>
23
24 static const UniqueValue::value_t v_Image=CxxFile::element_types.get();
25 static const UniqueValue::value_t v_FuncDecl=CxxFile::element_types.get();
26
27 class Gtk_Image : public Gtk_Misc
28 {public:
29 typedef Gtk_Misc Parent;
30 virtual const std::string TypeName(const Widget &w) const;
NeedExplicitCtor(const Widget & w) const31 virtual const std::string IncludeName(const Widget &w) const;
32 Gtk_Image();
ConstructionArgs(Widget const & w,CxxFile & f) const33 virtual bool NeedExplicitCtor(const Widget &w) const
34 { return true; }
35 virtual void ConstructionArgs(Widget const &w, CxxFile &f) const;
36 virtual void GCInclude(const Widget &w,CxxFile &f) const;
37 virtual bool CantMemberConstruct(const Widget &w) const
38 { return true; } // huh? then a delete?
39 virtual void CreatePointer(const Widget &w,CxxFile &f) const;
40 virtual void ApplyPreferences(Tag &t) const;
TypeName(const Widget & w) const41 private:
42 void EmbedImage(CxxFile &f,const std::string &pixbuf) const;
43 };
44
IncludeName(const Widget & w) const45 static Gtk_Image Gtk_Image;
46
47 const std::string Gtk_Image::TypeName(const Widget &w) const
48 { return GtkPrefix()+"Image";
Gnome_Entry()49 }
50
51 const std::string Gtk_Image::IncludeName(const Widget &w) const
52 { return Configuration.GtkmmIncludePath()+"image.h";
53 }
54
55 Gtk_Image::Gtk_Image()
56 { Writer["GtkImage"]=this;
57 }
IsSubwidget(const Widget & w,const Widget & ch) const58
59 void Gtk_Image::GCInclude(const Widget &w,CxxFile &f) const
60 { Parent::GCInclude(w,f);
61 const std::string pixbuf=w.getProperty("pixbuf");
62 if (pixbuf.empty()) return;
63 if (GTKMM1) f.Include(Configuration.GtkmmIncludePath()+"imageloader.h");
64 if (!Configuration.image_provider.empty())
65 { if (!f.ElementAlreadyThere(CxxFile::element_t(v_FuncDecl,Configuration.image_provider)))
66 { f.Declaration() << "extern Glib::RefPtr<Gdk::Pixbuf> "
67 << Configuration.image_provider << "(const std::string &name)";
68 f.AddElement(CxxFile::element_t(v_FuncDecl,Configuration.image_provider));
69 }
70 }
71 else if (Configuration.embed_images)
72 { if (!xpmname(pixbuf).empty())
73 f.Include(Configuration.CString(Configuration.pixmap_dir_relative_to_src+"/"+pixbuf),true);
74 else if (GTKMM2)
75 { f.Include("gdkmm/pixbufloader.h");
76 if (!f.ElementAlreadyThere(CxxFile::element_t(v_Image,pixbuf)))
77 { EmbedImage(f,pixbuf);
78 f.AddElement(CxxFile::element_t(v_Image,pixbuf));
79 }
80 }
81 }
82 }
83
84 // Glib::RefPtr<Pixmap> (Glib::RefPtr<Colormap>&,Glib::RefPtr<Bitmap>& mask,data)
85 // Pixmap: Gdk::Window,
86
87 // Variants: Pixmap/Image,Bitmap (image+mask)
88 // : Pixbuf
89 // : ustring (file)
90 void Gtk_Image::ConstructionArgs(Widget const &w, CxxFile &f) const
91 { std::string pixbuf=w.getProperty("pixbuf");
92 std::string xpm_ident=xpmname(pixbuf);
93 std::string stock=w.getProperty("stock");
94 if (GTKMM2)
95 { if (!stock.empty())
96 { // perhaps ... we should transform to IDs during translation
97 // if possible to save running time
98 f.FunctionArg() << "Gtk::StockID(" <<
99 Configuration.CString_WithQuotes(stock) << ')';
100 f.FunctionArg() << "Gtk::IconSize("
101 << w.getIntProperty("icon_size") << ')';
102 }
103 else if (!Configuration.image_provider.empty())
104 { f.FunctionArg() << Configuration.image_provider
105 << '(' << Configuration.CString_WithQuotes(pixbuf) << ')';
106 }
107 else if (Configuration.embed_images && !xpm_ident.empty())
108 { f.FunctionArg() << '_' << Configuration.InstanceName(w.Name())
109 << "_pixmap";
110 f.FunctionArg() << '_' << Configuration.InstanceName(w.Name())
111 << "_mask";
112 }
113 else if (Configuration.embed_images)
114 { f.FunctionArg() << '_' << Configuration.InstanceName(w.Name())
115 << "_loader->get_pixbuf()";
116 }
117 else
118 { f.FunctionArg();
119 if (pixbuf[0]!='/' && pixbuf.substr(0,2)!="./"
120 && !Configuration.pixmap_dir_relative_to_src.empty())
121 pixbuf=Configuration.pixmap_dir_relative_to_src+"/"+pixbuf;
122 if (!pixbuf.empty()) f << Configuration.CString_WithQuotes(pixbuf);
123 }
124 }
125 else
126 { f.FunctionArg() << '_' << Configuration.InstanceName(w.Name())
127 << "_imageloader->pix()";
128 f.FunctionArg() << '_' << Configuration.InstanceName(w.Name())
129 << "_imageloader->mask()";
130 }
131 }
132
133 void Gtk_Image::CreatePointer(const Widget &w,CxxFile &f) const
134 { std::string pixbuf=w.getProperty("pixbuf");
135 if (pixbuf.empty() && !w.getProperty("stock").empty())
136 { Parent::CreatePointer(w,f);
137 return;
138 }
139 std::string xpm_ident=xpmname(pixbuf);
140 std::string instname=Configuration.InstanceName(w.Name());
141 if (GTKMM2)
142 { if (!Configuration.image_provider.empty())
143 ; // nothing needed
144 else if (Configuration.embed_images)
145 {if (!xpm_ident.empty())
146 { f.Declaration() << "Glib::RefPtr<Gdk::Bitmap> _"
147 << instname <<"_mask";
148 f.Declaration() << "Glib::RefPtr<Gdk::Pixmap> _"
149 << instname <<"_pixmap "
150 "= Gdk::Pixmap::create_from_xpm(get_default_colormap(), _"
151 << instname <<"_mask, "
152 << xpm_ident << ')';
153 }
154 else
155 { f.Declaration() << "Glib::RefPtr<Gdk::PixbufLoader> _" << instname
156 << "_loader=Gdk::PixbufLoader::create()";
157 if (Configuration.gtkmm_version<Pkg_Version(2,0,0))
158 f.Declaration() << "GError *_" << instname << "_err=0";
159 f.Statement() << "_" << instname << "_loader->write("
160 << Configuration.CName(pixbuf) << "_data, sizeof "
161 << Configuration.CName(pixbuf) << "_data";
162 if (Configuration.gtkmm_version<Pkg_Version(2,0,0))
163 f << ", _" << instname << "_err";
164 f << ')';
165 f.Statement() << "_" << instname << "_loader->close()";
166 }
167 }
168 Parent::CreatePointer(w,f);
169 if (Configuration.image_provider.empty() && Configuration.embed_images
170 && xpm_ident.empty())
171 f.Statement() << "_" << instname << "_loader=Glib::RefPtr<Gdk::PixbufLoader>()";
172 }
173 else // can not work with 1.2 ???
174 { f.Declaration() << GtkPrefix()+"ImageLoaderData *_"<<
175 instname<<"_imageloader = new "
176 << GtkPrefix()+"ImageLoaderData("
177 << Naming::ToCIdentifier(pixbuf)
178 << ")";
179 Parent::CreatePointer(w,f);
180 f.Statement() << "delete _" <<
181 instname<<"_imageloader";
182 }
183 }
184
185 void Gtk_Image::ApplyPreferences(Tag &t) const
186 { // I gave up for 1.2, Image seems to not like xpm data
187 if (GTKMM1)
188 { static_cast<GladeTag*>(&t)->setWidgetType("GtkPixmap");
189 Widget w(&t);
190 w.setProperty("filename",w.getProperty("pixbuf"));
191 LookupWriter(w).ApplyPreferences(t);
192 }
193 else
194 Parent::ApplyPreferences(t);
195 }
196
197 void Gtk_Image::EmbedImage(CxxFile &f,const std::string &pixbuf) const
198 { f.Declaration("static const unsigned char ");
199 f << Configuration.CName(pixbuf) << "_data[]";
200 f.Assignment().StartBlock().EndLine();
201 { std::ifstream is((Configuration.pixmap_dir+"/"+pixbuf).c_str());
202 if (!is.good())
203 { f << "\n#error error opening image " << Configuration.pixmap_dir
204 << "/" <<pixbuf << "\n";
205 }
206 else while (is.good())
207 { /* unsigned ... hmmm g++3.1 does not like this ... */ char buf[16];
208 is.read(buf,sizeof buf);
209 size_t read=is.gcount();
210 f << '\t';
211 for (size_t x=0;x<read;++x) f << (unsigned int)(unsigned char)buf[x] << ',';
212 f << '\n';
213 }
214 }
215 f.EndBlock();
216 }
217