1 /** \file wxsimagelist.cpp
2 *
3 * This file is part of wxSmith plugin for Code::Blocks Studio
4 * Copyright (C) 2010 Gary Harris
5 *
6 * wxSmith 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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * wxSmith 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 wxSmith. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * This code was taken from the wxSmithImage plug-in, copyright Ron Collins
20 * and released under the GPL.
21 *
22 */
23
24 #include "wxsimagelist.h"
25 #include "../properties/wxsimagelisteditordlg.h"
26
27 namespace
28 {
29 wxsRegisterItem<wxsImageList> Reg(_T("ImageList"), wxsTTool, _T("Tools"), 72);
30 }
31
wxsImageList(wxsItemResData * Data)32 wxsImageList::wxsImageList(wxsItemResData *Data):
33 wxsTool(Data, &Reg.Info, 0, 0)
34 {
35 int n;
36 wxString ss, tt;
37 wxFileName fn;
38
39 m_IsBuilt = false;
40 m_ImageData.Clear();
41 m_Width = 16;
42 m_Height = 16;
43 m_Count = 0;
44 m_Include = false;
45
46 // make the absolute directory path where we store XPM image files
47 // this directory is always a sub-dir where the source code file is stored
48 fn = Data->GetSrcFileName();
49 ss = fn.GetPath((wxPATH_GET_VOLUME + wxPATH_GET_SEPARATOR));
50 n = ss.Len();
51 ss = ss + _T("wximages") + ss[n-1];
52
53 m_IDir = ss;
54 m_RDir = _T("./wximages/");
55 m_Base = fn.GetName();
56 }
57
58 /*! \brief Create the initial control.
59 *
60 * \return void
61 *
62 */
OnBuildCreatingCode()63 void wxsImageList::OnBuildCreatingCode()
64 {
65 int i;
66 wxString inc;
67 wxString vname; // this variable name
68 wxString bname; // name of the bitmap variable
69 wxString fbase; // base name of XPM file without dirs or extension
70 wxString fabs; // absolute name of XPM file
71 wxString frel; // relative
72 wxString dname; // name of XPM data array
73 wxBitmap bmp; // preview bitmap saved as XPM
74 wxString ss, tt; // general use
75
76 // have we already been here?
77 if(m_IsBuilt){
78 return;
79 }
80 m_IsBuilt = true;
81
82 switch(GetLanguage())
83 {
84 case wxsCPP:
85 {
86 AddHeader(_("<wx/imaglist.h>"), GetInfo().ClassName, 0);
87
88 // store the XPM data someplace
89 StoreXpmData();
90
91 vname = GetVarName();
92 // if there is no data, then just make empty image and bitmap
93 if(m_Count == 0){
94 Codef(_T("%s = new wxImageList(%d, %d, 1);\n"), vname.wx_str(), m_Width, m_Height);
95 }
96 // else fill it with XPM data
97 else{
98 Codef(_T("%s = new wxImageList(%d, %d, %d);\n"), vname.wx_str(), m_Width, m_Height, (m_Count + 1));
99 for(i = 0; i < m_Count; i++) {
100 ss.Printf(_("%s_%d_XPM"), vname.wx_str(), i);
101 Codef(_T("%s->Add(wxBitmap(%s));\n"), vname.wx_str(), ss.wx_str());
102 }
103 }
104
105 BuildSetupWindowCode();
106 return;
107 }
108
109 case wxsUnknownLanguage: // fall through
110 default:
111 {
112 wxsCodeMarks::Unknown(_T("wxsImageList::OnBuildCreatingCode"), GetLanguage());
113 }
114 }
115 }
116
117 /*! \brief Enumerate the tool's properties.
118 *
119 * \param flags long The control flags.
120 * \return void
121 *
122 */
OnEnumToolProperties(cb_unused long Flags)123 void wxsImageList::OnEnumToolProperties(cb_unused long Flags)
124 {
125 // starting a new build cycle
126 m_IsBuilt = false;
127 m_Context = GetCoderContext();
128
129 // details for the image list
130 WXS_IMAGELIST(wxsImageList, m_ImageData, _T("Image List"), _T("image_list"));
131 WXS_ARRAYSTRING(wxsImageList, m_ImageData, _("Images as Text"), _T("image_text"), _T("item2"));
132 WXS_LONG(wxsImageList, m_Width, _("Image Width"), _T("image_width"), 16);
133 WXS_LONG(wxsImageList, m_Height, _("Image Height"), _T("image_height"), 16);
134 WXS_LONG(wxsImageList, m_Count, _("Image Count"), _T("image_count"), 0);
135 WXS_BOOL(wxsImageList, m_Include, _("Use Include File"), _T("use_include"), false);
136 };
137
138 /*! \brief Save XPM data either in the code or in a separate header file.
139 *
140 * \param void
141 * \return void
142 *
143 */
StoreXpmData(void)144 void wxsImageList::StoreXpmData(void)
145 {
146 int i, n;
147 long ll;
148 wxString vname;
149 wxString xname;
150 wxString ss, tt, vv;
151 wxFile ff;
152
153 // important names
154 vname = GetVarName();
155
156 // if no XPM images, then just store the image size
157 n = m_ImageData.GetCount();
158 if(n <= 2){
159 if(m_Width <= 0) m_Width = 16;
160 if(m_Height <= 0) m_Height = 16;
161 m_Count = 0;
162
163 m_ImageData.Clear();
164 ss.Printf(_T("%ld"), m_Width);
165 m_ImageData.Add(ss);
166
167 ss.Printf(_T("%ld"), m_Height);
168 m_ImageData.Add(ss);
169 }
170 // else reset the displayed size
171 else{
172 ss = m_ImageData.Item(0);
173 if(ss.ToLong(&ll)) m_Width = ll;
174
175 ss = m_ImageData.Item(1);
176 if(ss.ToLong(&ll)) m_Height = ll;
177
178 m_Count = 0;
179 for(i = 0;i < (int)m_ImageData.GetCount();i++){
180 ss = m_ImageData.Item(i);
181 if(ss.Find(_T("xpm_data")) >= 0){
182 m_Count += 1;
183 }
184 };
185 };
186
187 // are we finished?
188 if(m_Count == 0){
189 return;
190 }
191
192 // need to create a #include file?
193 if(m_Include){
194 if(! wxFileName::DirExists(m_IDir)) wxFileName::Mkdir(m_IDir);
195 ss = m_IDir;
196 ss += m_Base;
197 ss += _T("_");
198 ss += vname;
199 ss += _T(".xpm");
200 ff.Open(ss, wxFile::write);
201 }
202
203 // go thru entire array, pulling out one XPM at a time into a single string
204 n = 0;
205 i = 2;
206 tt = _("");
207 while(i < (int)m_ImageData.GetCount()){
208 ss = m_ImageData.Item(i);
209 i += 1;
210
211 // the beginning of a new XPM image means the end of the previous image
212 if(ss.Find(_T("xpm_data")) >= 0){
213 vv.Printf(_T("%s_%d_XPM"), vname.wx_str(), n);
214 ss.Replace(_T("xpm_data"), vv);
215 n += 1;
216
217 if(tt.Length() > 0){
218 if(m_Include){
219 ff.Write(tt);
220 }
221 else{
222 Codef(tt);
223 }
224 }
225
226 tt = ss;
227 tt += _T("\n");
228 }
229 // else just another data line
230 else {
231 tt += ss;
232 tt += _T("\n");
233 }
234 }
235
236 // the left-overs
237 if(tt.Length() > 0){
238 if(m_Include){
239 ff.Write(tt);
240 }
241 else{
242 Codef(tt);
243 }
244 }
245
246 // include the #include file
247 if(m_Include){
248 ff.Close();
249
250 ss = _T("\"");
251 ss += m_RDir;
252 ss += m_Base;
253 ss += _T("_");
254 ss += vname;
255 ss += _T(".xpm");
256 ss += _T("\"");
257
258 AddHeader(ss, GetInfo().ClassName, 0);
259 }
260 }
261
GetCount(void)262 int wxsImageList::GetCount(void)
263 {
264 return m_Count;
265 }
266
267 /*! \brief Get an image preview by index.
268 *
269 * \param inIndex int
270 * \return wxBitmap
271 *
272 */
GetPreview(int inIndex)273 wxBitmap wxsImageList::GetPreview(int inIndex)
274 {
275 int i, j, n;
276 wxString ss, tt;
277 wxArrayString aa;
278 wxBitmap bmp;
279
280 // no such image?
281 if((inIndex < 0) || (inIndex >= m_Count)){
282 return wxNullBitmap;
283 }
284 if(m_ImageData.GetCount() == 0){
285 return wxNullBitmap;
286 }
287
288 // count down to the start of that image data
289 n = -1; // found index at start of data
290 j = 0; // counter of data blocks
291 i = 0; // index into m_ImageData
292
293 while((i < (int)m_ImageData.GetCount()) && (n < 0)){
294 ss = m_ImageData.Item(i);
295 i += 1;
296
297 if(ss.Find(_T("xpm_data")) >= 0){
298 if(j == inIndex){
299 n = i;
300 }
301 j += 1;
302 }
303 }
304
305 // still no data block?
306 if(n < 0){
307 return wxNullBitmap;\
308 }
309
310 // save that first line
311 aa.Clear();
312 aa.Add(ss);
313
314 // copy out the data block (until the next "xpm_data")
315 i = n;
316 n = -1;
317 while((i < (int)m_ImageData.GetCount()) && (n < 0)){
318 ss = m_ImageData.Item(i);
319 i += 1;
320
321 if(ss.Find(_T("xpm_data")) >= 0){
322 n = i;
323 }
324 else{
325 aa.Add(ss);
326 }
327 }
328
329 // turn that data block into a bitmap
330 wxsImageListEditorDlg::ArrayToBitmap(aa, bmp);
331
332 // done
333 return bmp;
334 }
335
336 /*! \brief Get the image list.
337 *
338 * \param aImageList wxImageList&
339 * \return void
340 *
341 */
GetImageList(wxImageList & aImageList)342 void wxsImageList::GetImageList(wxImageList &aImageList)
343 {
344 aImageList.RemoveAll();
345 wxsImageListEditorDlg::ArrayToImageList(m_ImageData, aImageList);
346 }
347
348 /*! \brief This just exposes the "OnBuildCreatingCode()" method.
349 *
350 * \param void
351 * \return void
352 *
353 */
DoBuild(void)354 void wxsImageList::DoBuild(void)
355 {
356 BuildCode(m_Context);
357 }
358
359