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