PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/source/libs/paragui/src/widgets/pglayout.cpp

https://bitbucket.org/val_haris/asc-ai
C++ | 1288 lines | 923 code | 297 blank | 68 comment | 238 complexity | ab11bea9855c9fecc7f95cae9836d373 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0
  1. #include "paragui.h"
  2. #include "pglayout.h"
  3. #include "pgwidget.h"
  4. #include "pgbutton.h"
  5. #include "pgdropdown.h"
  6. #include "pglabel.h"
  7. #include "pgthemewidget.h"
  8. #include "pgmaskedit.h"
  9. #include "pgprogressbar.h"
  10. #include "pgspinnerbox.h"
  11. #include "pgwindow.h"
  12. #include "pgwidgetlist.h"
  13. #include "pglistbox.h"
  14. #include "pglistboxitem.h"
  15. #include "pgcolumnitem.h"
  16. #include "pgmessagebox.h"
  17. #include "pgradiobutton.h"
  18. #include "pgcheckbutton.h"
  19. #include "pgscrollbar.h"
  20. #include "pgslider.h"
  21. #include "pgimage.h"
  22. #include "pgrichedit.h"
  23. #include "pglog.h"
  24. #include "pgpopupmenu.h"
  25. #include "pgmenubar.h"
  26. #include "pgscrollwidget.h"
  27. #include <cstring>
  28. #include <stdarg.h>
  29. #include <sys/stat.h>
  30. #include <expat.h>
  31. // Expat UNICODE workaround - copied from xmltchar.h (Expat dist) - Inserted by Ales Teska
  32. #ifdef XML_UNICODE
  33. #ifndef XML_UNICODE_WCHAR_T
  34. #error UNICODE version requires a 16-bit Unicode-compatible wchar_t=20
  35. #endif
  36. #define T(x) L ## x
  37. #define tcscmp wcscmp
  38. #else /* not XML_UNICODE */
  39. #define T(x) x
  40. #define tcscmp strcmp
  41. #endif
  42. #define IsTag(lx,sx,y) (((tcscmp(T(lx),T(name))==0)||(tcscmp(T(sx),T(name))==0))&&((XMLParser->Section & (y))!=0))
  43. #define XML_BUFF_SIZE 1024
  44. #define XML_SECTION_NONPAIR 0x00000000
  45. #define XML_SECTION_DOC 0x00000001
  46. #define XML_SECTION_LAYOUT 0x00000002
  47. #define XML_SECTION_HEAD 0x00000004
  48. #define XML_SECTION_BODY 0x00000008
  49. #define XML_SECTION_BUTTON 0x00000010
  50. #define XML_SECTION_COMWIDPARAMS 0x00000020
  51. #define XML_SECTION_DROPDOWN 0x00000040
  52. #define XML_SECTION_WIDGET 0x00000080
  53. #define XML_SECTION_LABEL 0x00000100
  54. #define XML_SECTION_GWIDGET 0x00000200
  55. #define XML_SECTION_SFRAME 0x00000400
  56. #define XML_SECTION_LINEEDIT 0x00000800
  57. #define XML_SECTION_MASKEDIT 0x00001000
  58. #define XML_SECTION_PROGRESSBAR 0x00002000
  59. #define XML_SECTION_SPINNERBOX 0x00004000
  60. #define XML_SECTION_WINDOW 0x00008000
  61. #define XML_SECTION_WIDGETLIST 0x00010000
  62. #define XML_SECTION_LISTBOX 0x00020000
  63. #define XML_SECTION_LISTBOXITEM 0x00040000
  64. #define XML_SECTION_COLUMNITEM 0x00080000
  65. #define XML_SECTION_MESSAGEBOX 0x00100000
  66. #define XML_SECTION_RADIOBUTTON 0x00200000
  67. #define XML_SECTION_CHECKBUTTON 0x00400000
  68. #define XML_SECTION_SCROLLBAR 0x00800000
  69. #define XML_SECTION_IMAGE 0x01000000
  70. #define XML_SECTION_RICHEDIT 0x02000000
  71. #define XML_SECTION_WIDGETLISTEX 0x04000000
  72. #define XML_SECTION_FONT 0x08000000
  73. #define XML_SECTION_POPUPMENU 0x10000000
  74. #define XML_SECTION_MENUBAR 0x20000000
  75. #define XML_SECTION_POPUPMENUITEM 0x40000000
  76. typedef struct {
  77. XML_Parser Parser;
  78. int Section;
  79. const char* FileName;
  80. int EndTagFlags; //Not inherited
  81. int InhTagFlags; //Inherited
  82. int Height;
  83. int Width;
  84. PG_Widget *ParentObject;
  85. void *PrevUserData; //Previous user data
  86. void *UserSpace;
  87. }
  88. ParseUserData_t;
  89. #define ENDTAGFLAG_OBJECT 1
  90. #define ENDTAGFLAG_WIDGETLIST 2
  91. #define ENDTAGFLAG_SETSIZE 4
  92. #define INHTAGFLAG_HIDE 1
  93. #define INHTAGFLAG_ADDWIDGET 2
  94. static char Empty = 0;
  95. char *PG_Layout::GetParamStr(const char **Source, const char *What) {
  96. char **c;
  97. for (c = (char **)Source;*c; c += 2)
  98. if (tcscmp(T(*c),T(What)) == 0)
  99. return(*(c+1));
  100. return(&Empty);
  101. }
  102. void PG_Layout::GetParamRect(const char **Source, const char *What, PG_Rect& Rect, PG_Widget* parent) {
  103. char *c = PG_Layout::GetParamStr(Source,What);
  104. if(c == NULL) {
  105. return;
  106. }
  107. if(strlen(c) == 0) {
  108. return;
  109. }
  110. SDL_Surface *screen = PG_Application::GetScreen();
  111. char* parm;
  112. char *d;
  113. char tmp[16];
  114. int i=0;
  115. int mx;
  116. int r[4];
  117. r[0] = r[1] = r[2] = r[3] = 0;
  118. parm = strdup(c);
  119. for(d = strtok(parm,","); d != NULL; d = strtok(NULL,",")) {
  120. if(parent == NULL) {
  121. mx = ((i%2)==0) ? screen->w : screen->h;
  122. } else {
  123. mx = ((i%2)==0) ? parent->w : parent->h;
  124. }
  125. if( sscanf(d, "%d%[%]", & r[i], tmp) == 2 )
  126. r[i] = (int) ((float)r[i]*mx/100);
  127. if(r[i]<0)
  128. r[i] = mx+r[i];
  129. i++;
  130. }
  131. Rect.SetRect(r[0], r[1], r[2], r[3]);
  132. free(parm);
  133. }
  134. int PG_Layout::GetParamInt(const char **Source, const char *What) {
  135. char* p = PG_Layout::GetParamStr(Source, What);
  136. if(p[0] == 0) {
  137. return -1;
  138. }
  139. return atoi(p);
  140. }
  141. PG_ScrollBar::ScrollDirection PG_Layout::GetParamScrollDirection(const char **Source, const char *What) {
  142. char* p = PG_Layout::GetParamStr(Source, What);
  143. PG_ScrollBar::ScrollDirection r = PG_ScrollBar::VERTICAL;
  144. switch(atoi(p)) {
  145. case 0:
  146. r = PG_ScrollBar::VERTICAL;
  147. break;
  148. case 1:
  149. r = PG_ScrollBar::HORIZONTAL;
  150. break;
  151. }
  152. return r;
  153. }
  154. PG_Label::TextAlign PG_Layout::GetParamAlign(const char **Source, const char *What) {
  155. PG_Label::TextAlign ret = PG_Label::LEFT;
  156. char *c = PG_Layout::GetParamStr(Source,What);
  157. if (c[0]==0)
  158. return PG_Label::LEFT;
  159. if (tcscmp(T(c),T("left")) == 0)
  160. ret = PG_Label::LEFT;
  161. if (tcscmp(T(c),T("right")) == 0)
  162. ret = PG_Label::RIGHT;
  163. if (tcscmp(T(c),T("center")) == 0)
  164. ret = PG_Label::CENTER;
  165. return ret;
  166. }
  167. PG_Draw::BkMode PG_Layout::GetParamIMode(const char **Source, const char *What) {
  168. PG_Draw::BkMode ret = PG_Draw::TILE;
  169. char *c = PG_Layout::GetParamStr(Source,What);
  170. if (tcscmp(T(c),T("tile")) == 0)
  171. ret = PG_Draw::TILE;
  172. if (tcscmp(T(c),T("stretch")) == 0)
  173. ret = PG_Draw::STRETCH;
  174. if (tcscmp(T(c),T("3tileh")) == 0)
  175. ret = PG_Draw::TILE3H;
  176. if (tcscmp(T(c),T("3tilev")) == 0)
  177. ret = PG_Draw::TILE3V;
  178. if (tcscmp(T(c),T("9tile")) == 0)
  179. ret = PG_Draw::TILE9;
  180. return(ret);
  181. }
  182. int PG_Layout::GetParamGrad(const char **Source, const char *What, PG_Gradient *grad) {
  183. char *c = PG_Layout::GetParamStr(Source,What);
  184. int r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
  185. if (c[0] == 0)
  186. return(0);
  187. sscanf(c,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&r1,&g1,&b1,&r2,&g2,&b2,&r3,&g3,&b3,&r4,&g4,&b4);
  188. grad->colors[0].r = r1;
  189. grad->colors[0].g = g1;
  190. grad->colors[0].b = b1;
  191. grad->colors[1].r = r2;
  192. grad->colors[1].g = g2;
  193. grad->colors[1].b = b2;
  194. grad->colors[2].r = r3;
  195. grad->colors[2].g = g3;
  196. grad->colors[2].b = b3;
  197. grad->colors[3].r = r4;
  198. grad->colors[3].g = g4;
  199. grad->colors[3].b = b4;
  200. return(1);
  201. }
  202. static void SaveUserData(ParseUserData_t *XMLParser) {
  203. ParseUserData_t *OldUserData;
  204. OldUserData = (ParseUserData_t *)malloc(sizeof(ParseUserData_t));
  205. *OldUserData = *XMLParser;
  206. XMLParser->PrevUserData = OldUserData;
  207. XMLParser->EndTagFlags = 0;
  208. return;
  209. }
  210. static void RestoreUserData(ParseUserData_t *XMLParser) {
  211. ParseUserData_t *OldUserData = (ParseUserData_t *)XMLParser->PrevUserData;
  212. *XMLParser = *OldUserData;
  213. free(OldUserData);
  214. return;
  215. }
  216. void (* PG_LayoutWidgetParams)(PG_Widget *Widget, const char **atts) = NULL;
  217. void (* PG_LayoutProcessingInstruction)(const char* target, const char* data, const std::string& FileName, void *UserSpace) = NULL;
  218. //Declaration
  219. //static void XMLTextDoc(void *userData, const XML_Char *s, int len);
  220. static int SetWidgetAtts(PG_Widget *Widget, const char **atts, ParseUserData_t *XMLParser) {
  221. char *c;
  222. int i,ret = 0;
  223. c = PG_Layout::GetParamStr(atts, "name");
  224. if (c[0] != 0)
  225. Widget->SetName(c);
  226. i = PG_Layout::GetParamInt(atts, "id");
  227. if (i != -1) {
  228. Widget->SetID(i);
  229. }
  230. c = PG_Layout::GetParamStr(atts, "fcolor");
  231. if (c[0] != 0) {
  232. int r,g,b;
  233. sscanf(c,"%d,%d,%d",&r,&g,&b);
  234. Widget->SetFontColor(PG_Color(r,g,b));
  235. }
  236. c = PG_Layout::GetParamStr(atts, "fname");
  237. if (c[0] != 0) {
  238. Widget->SetFontName(c);
  239. }
  240. i = PG_Layout::GetParamInt(atts, "fsize");
  241. if (i != -1) {
  242. Widget->SetFontSize(i);
  243. }
  244. i = PG_Layout::GetParamInt(atts, "fstyle");
  245. if (i != -1) {
  246. Widget->SetFontStyle((PG_Font::Style)i);
  247. }
  248. i = PG_Layout::GetParamInt(atts, "findex");
  249. if (i != -1) {
  250. Widget->SetFontIndex(i);
  251. }
  252. i = PG_Layout::GetParamInt(atts, "falpha");
  253. if (i != -1) {
  254. Widget->SetFontAlpha(i);
  255. }
  256. c = PG_Layout::GetParamStr(atts, "data");
  257. if (c[0] != 0)
  258. Widget->SetUserData(c, strlen(c)+1);
  259. if (PG_LayoutWidgetParams != NULL)
  260. PG_LayoutWidgetParams(Widget,atts);
  261. //TO-DO : Remove this (obsolete)
  262. c = PG_Layout::GetParamStr(atts, "text");
  263. if (c[0] != 0) {
  264. Widget->SetText((const char*)c);
  265. }
  266. i = PG_Layout::GetParamInt(atts, "hide");
  267. if (i == 1)
  268. ret |= INHTAGFLAG_HIDE;
  269. c = PG_Layout::GetParamStr(atts, "sbt");
  270. if (c[0] != 0) {
  271. sscanf(c,"%d,%d", &XMLParser->Width, &XMLParser->Height);
  272. XMLParser->EndTagFlags |= ENDTAGFLAG_SETSIZE;
  273. }
  274. //Remove AddWidget tag ...
  275. ret &= ~INHTAGFLAG_ADDWIDGET;
  276. XMLParser->EndTagFlags |= ENDTAGFLAG_OBJECT;
  277. return(ret);
  278. }
  279. static int SetDropDownAtts(PG_DropDown *Widget, const char **atts,ParseUserData_t *XMLParser) {
  280. int i;
  281. i = PG_Layout::GetParamInt(atts, "indent");
  282. if (i > 0)
  283. Widget->SetIndent(i);
  284. i = PG_Layout::GetParamInt(atts, "edit");
  285. Widget->SetEditable(i == 1);
  286. return (SetWidgetAtts(Widget, atts, XMLParser));
  287. }
  288. static int SetThemeWidgetAtts(PG_ThemeWidget *Widget, const char **atts, ParseUserData_t *XMLParser) {
  289. char *c;
  290. PG_Gradient grad;
  291. c = PG_Layout::GetParamStr(atts, "image");
  292. if(c[0] != 0) {
  293. Widget->SetBackground(c,PG_Layout::GetParamIMode(atts, "imode"));
  294. }
  295. int b = PG_Layout::GetParamInt(atts, "blend");
  296. if(b != -1) {
  297. Widget->SetBackgroundBlend(b);
  298. }
  299. if (PG_Layout::GetParamGrad(atts, "gradient", &grad) != 0)
  300. Widget->SetGradient(grad);
  301. c = PG_Layout::GetParamStr(atts, "bimage");
  302. if (c[0] != 0) {
  303. Widget->LoadImage(c);
  304. }
  305. b = PG_Layout::GetParamInt(atts, "transparency");
  306. if(b != -1) {
  307. Widget->SetTransparency(b);
  308. }
  309. return SetWidgetAtts(Widget, atts, XMLParser);
  310. }
  311. static int SetLabelAtts(PG_Label *Widget, const char **atts, ParseUserData_t *XMLParser) {
  312. PG_Label::TextAlign a;
  313. int i;
  314. char* c;
  315. a = PG_Layout::GetParamAlign(atts, "align");
  316. Widget->SetAlignment(a);
  317. i = PG_Layout::GetParamInt(atts, "indent");
  318. if (i != -1) {
  319. Widget->SetIndent(i);
  320. }
  321. c = PG_Layout::GetParamStr(atts, "icon");
  322. if (c[0] != 0) {
  323. Widget->SetIcon((const char*)c);
  324. }
  325. return(SetWidgetAtts(Widget, atts, XMLParser));
  326. }
  327. static int SetUserButtonAtts(PG_Button *Widget, const char **atts, ParseUserData_t *XMLParser) {
  328. char *c,*c1,*c2;
  329. int i,j,k;
  330. int b;
  331. c = PG_Layout::GetParamStr(atts, "upimage");
  332. c1 = PG_Layout::GetParamStr(atts, "downimage");
  333. c2 = PG_Layout::GetParamStr(atts, "overimage");
  334. /*if (c1[0] == 0) {
  335. c1 = NULL;
  336. }
  337. if (c2[0] == 0) {
  338. c2 = NULL;
  339. }*/
  340. if (c[0] != 0) {
  341. b = PG_Layout::GetParamInt(atts, "colorkey");
  342. if(b != -1) {
  343. Widget->SetIcon(c, c1, c2, b);
  344. } else {
  345. Widget->SetIcon(c, c1, c2);
  346. }
  347. }
  348. i = PG_Layout::GetParamInt(atts, "toggle");
  349. Widget->SetToggle(i == 1);
  350. i = PG_Layout::GetParamInt(atts, "pressed");
  351. Widget->SetPressed(i == 1);
  352. c = PG_Layout::GetParamStr(atts, "shift");
  353. if (c[0] != 0) {
  354. sscanf(c,"%d",&i);
  355. Widget->SetShift(i);
  356. }
  357. c = PG_Layout::GetParamStr(atts, "border");
  358. if (c[0] != 0) {
  359. sscanf(c,"%d,%d,%d",&i,&j,&k);
  360. Widget->SetBorderSize(i,j,k);
  361. }
  362. c = PG_Layout::GetParamStr(atts, "transparency");
  363. if (c[0] != 0) {
  364. sscanf(c,"%d,%d,%d",&i,&j,&k);
  365. Widget->SetTransparency(i,j,k);
  366. }
  367. return(SetWidgetAtts(Widget, atts, XMLParser));
  368. }
  369. static int SetButtonAtts(PG_Button *Widget, const char **atts, ParseUserData_t *XMLParser) {
  370. PG_Gradient grad;
  371. if (PG_Layout::GetParamGrad(atts, "upgrad", &grad) != 0)
  372. Widget->SetGradient(PG_Button::UNPRESSED, grad);
  373. if (PG_Layout::GetParamGrad(atts, "downgrad", &grad) != 0)
  374. Widget->SetGradient(PG_Button::PRESSED, grad);
  375. if (PG_Layout::GetParamGrad(atts, "selgrad", &grad) != 0)
  376. Widget->SetGradient(PG_Button::HIGHLITED, grad);
  377. /*SetBackground*/
  378. return(SetUserButtonAtts(Widget, atts, XMLParser));
  379. }
  380. static int SetPopupMenuAtts(PG_PopupMenu *Widget, const char **atts, ParseUserData_t *XMLParser) {
  381. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  382. }
  383. static int SetLineEditAtts(PG_LineEdit *Widget, const char **atts, ParseUserData_t *XMLParser) {
  384. char *c;
  385. if (PG_Layout::GetParamInt(atts, "readonly") == 1)
  386. Widget->SetEditable(0);
  387. c = PG_Layout::GetParamStr(atts, "validkeys");
  388. if (c[0] != 0)
  389. Widget->SetValidKeys(c);
  390. c = PG_Layout::GetParamStr(atts, "passchar");
  391. if (c[0] != 0)
  392. Widget->SetPassHidden(c[0]);
  393. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  394. }
  395. static int SetMaskEditAtts(PG_MaskEdit *Widget, const char **atts, ParseUserData_t *XMLParser) {
  396. char *c;
  397. Widget->SetMask(PG_Layout::GetParamStr(atts, "mask"));
  398. c = PG_Layout::GetParamStr(atts, "spacer");
  399. if (c[0] != 0)
  400. Widget->SetSpacer(c[0]);
  401. return(SetLineEditAtts(Widget, atts, XMLParser));
  402. }
  403. static int SetWindowAtts(PG_Window *Widget, const char **atts, ParseUserData_t *XMLParser) {
  404. char *c;
  405. c = PG_Layout::GetParamStr(atts, "titlecolor");
  406. if (c[0] != 0) {
  407. int r,g,b;
  408. sscanf(c,"%d,%d,%d",&r,&g,&b);
  409. Widget->SetTitlebarColor(((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xFF));
  410. }
  411. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  412. }
  413. static int SetProgressBarAtts(PG_ProgressBar *Widget, const char **atts, ParseUserData_t *XMLParser) {
  414. char *c;
  415. double p;
  416. c = PG_Layout::GetParamStr(atts, "progress");
  417. if (c[0] != 0) {
  418. p = atof(c);
  419. Widget->SetProgress(p);
  420. }
  421. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  422. }
  423. static int SetSpinnerBoxAtts(PG_SpinnerBox *Widget, const char **atts, ParseUserData_t *XMLParser) {
  424. int i,j;
  425. char *c;
  426. i = PG_Layout::GetParamInt(atts, "value");
  427. if(i != -1) {
  428. Widget->SetValue(i);
  429. }
  430. i = PG_Layout::GetParamInt(atts, "min");
  431. if(i != -1) {
  432. Widget->SetMinValue(i);
  433. }
  434. j = PG_Layout::GetParamInt(atts, "max");
  435. if (j > i)
  436. Widget->SetMaxValue(j);
  437. c = PG_Layout::GetParamStr(atts, "mask");
  438. if (c[0] != 0)
  439. Widget->SetMask(c);
  440. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  441. }
  442. static int SetWidgetListAtts(PG_WidgetList *Widget, const char **atts, ParseUserData_t *XMLParser) {
  443. if (PG_Layout::GetParamInt(atts, "scrollbar") == 1)
  444. Widget->EnableScrollBar(1);
  445. XMLParser->EndTagFlags |= ENDTAGFLAG_WIDGETLIST;
  446. return (INHTAGFLAG_ADDWIDGET | SetThemeWidgetAtts(Widget, atts, XMLParser));
  447. }
  448. static int SetScrollWidgetAtts(PG_ScrollWidget*Widget, const char **atts, ParseUserData_t *XMLParser) {
  449. if (PG_Layout::GetParamInt(atts, "scrollbar") == 1)
  450. Widget->EnableScrollBar(1);
  451. XMLParser->EndTagFlags |= ENDTAGFLAG_WIDGETLIST;
  452. return (INHTAGFLAG_ADDWIDGET | SetThemeWidgetAtts(Widget, atts, XMLParser));
  453. }
  454. static int SetListBoxAtts(PG_ListBox *Widget, const char **atts, ParseUserData_t *XMLParser) {
  455. Widget->SetMultiSelect(PG_Layout::GetParamInt(atts, "multisel") == 1);
  456. return(SetWidgetListAtts(Widget, atts, XMLParser));
  457. }
  458. static int SetListBoxItemAtts(PG_ListBoxItem *Widget, const char **atts, ParseUserData_t *XMLParser) {
  459. if (PG_Layout::GetParamInt(atts, "select") == 1)
  460. Widget->Select(1);
  461. return(SetLabelAtts(Widget, atts, XMLParser));
  462. }
  463. static int SetRadioButtonAtts(PG_RadioButton *Widget, const char **atts, ParseUserData_t *XMLParser) {
  464. if (PG_Layout::GetParamInt(atts, "pressed") == 1)
  465. Widget->SetPressed();
  466. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  467. }
  468. static int SetScrollBarAtts(PG_ScrollBar *Widget, const char **atts, ParseUserData_t *XMLParser) {
  469. int i,j;
  470. i = PG_Layout::GetParamInt(atts, "value");
  471. if (i != -1) {
  472. Widget->SetPosition(i);
  473. }
  474. /*i = PG_Layout::GetParamInt(atts, "wsize");
  475. if (i != -1) {
  476. Widget->SetWindowSize(i);
  477. }*/
  478. i = PG_Layout::GetParamInt(atts, "lsize");
  479. if (i != -1) {
  480. Widget->SetLineSize(i);
  481. }
  482. i = PG_Layout::GetParamInt(atts, "psize");
  483. if (i != -1) {
  484. Widget->SetPageSize(i);
  485. }
  486. i = PG_Layout::GetParamInt(atts, "min");
  487. j = PG_Layout::GetParamInt(atts, "max");
  488. if ((i < j) && (i != j)) {
  489. Widget->SetRange(i,j);
  490. }
  491. return SetThemeWidgetAtts(Widget, atts, XMLParser);
  492. }
  493. static void XMLStartDoc(void *userData, const char *name, const char **atts) {
  494. PG_Rect Rect; // -> UserData ???? - for parent size
  495. ParseUserData_t *XMLParser = (ParseUserData_t *)userData;
  496. SaveUserData(XMLParser);
  497. PG_Widget* parent = /*((XMLParser->EndTagFlags & INHTAGFLAG_ADDWIDGET) == INHTAGFLAG_ADDWIDGET) ? NULL :*/ XMLParser->ParentObject;
  498. //Tag <layout> <LA>
  499. if (IsTag("layout","LA",XML_SECTION_DOC)) {
  500. XMLParser->Section = XML_SECTION_LAYOUT;
  501. return;
  502. }
  503. //Tag <head> <HD>
  504. if (IsTag("head","HD",XML_SECTION_LAYOUT)) {
  505. XMLParser->Section = XML_SECTION_HEAD;
  506. return;
  507. }
  508. //Tag <body> <BD>
  509. if (IsTag("body","BD",XML_SECTION_LAYOUT)) {
  510. XMLParser->Section = XML_SECTION_BODY;
  511. return;
  512. }
  513. //Tag <widget> <WD>
  514. if (IsTag("widget","WD",XML_SECTION_BODY)) {
  515. XMLParser->Section = XML_SECTION_WIDGET | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  516. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  517. PG_Widget *Widget = new PG_Widget(parent, Rect);
  518. XMLParser->ParentObject = Widget;
  519. XMLParser->InhTagFlags |=SetWidgetAtts(Widget, atts, XMLParser);
  520. return;
  521. }
  522. //Tag <dropdown> <DD>
  523. if (IsTag("dropdown","DD",XML_SECTION_BODY)) {
  524. XMLParser->Section = XML_SECTION_DROPDOWN | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  525. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  526. if (Rect.w < Rect.h) {
  527. PG_LogWRN("Width must be greater than height in <dropdown>");
  528. return;
  529. }
  530. PG_DropDown *Widget = new PG_DropDown (parent, Rect);
  531. XMLParser->ParentObject = Widget;
  532. XMLParser->InhTagFlags |=SetDropDownAtts(Widget, atts, XMLParser);
  533. return;
  534. }
  535. //Tag <dropdownitem> <DI>
  536. if (IsTag("dropdownitem","DI",XML_SECTION_DROPDOWN)) {
  537. XMLParser->Section = XML_SECTION_NONPAIR;
  538. ((PG_DropDown *)(XMLParser->ParentObject))->AddItem(PG_Layout::GetParamStr(atts, "text"));
  539. return;
  540. }
  541. //Tag <button> <BT>
  542. if (IsTag("button","BT",XML_SECTION_BODY)) {
  543. XMLParser->Section = XML_SECTION_BUTTON | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  544. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  545. PG_LogDBG("layout: parent = %p", parent);
  546. PG_Button *Widget = new PG_Button(
  547. parent,
  548. Rect,
  549. PG_Layout::GetParamStr(atts, "text"),
  550. PG_Layout::GetParamInt(atts, "id"),
  551. PG_Layout::GetParamStr(atts, "style"));
  552. XMLParser->ParentObject = Widget;
  553. XMLParser->InhTagFlags |=SetButtonAtts(Widget, atts, XMLParser);
  554. return;
  555. }
  556. //Tag <label> <LL>
  557. if (IsTag("label","LL",XML_SECTION_BODY)) {
  558. XMLParser->Section = XML_SECTION_LABEL | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  559. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  560. PG_Label *Widget = new PG_Label(parent, Rect, "", PG_Layout::GetParamStr(atts, "style"));
  561. XMLParser->ParentObject = Widget;
  562. XMLParser->InhTagFlags |=SetLabelAtts(Widget, atts, XMLParser);
  563. return;
  564. }
  565. //Tag <gradientwidget> <GW>
  566. //Tag <staticframe> <SF>
  567. //Tag <themewidget> <TW>
  568. if (IsTag("themewidget","GW",XML_SECTION_BODY) || IsTag("gradientwidget","GW",XML_SECTION_BODY) || IsTag("staticframe","SF",XML_SECTION_BODY)) {
  569. XMLParser->Section = XML_SECTION_GWIDGET | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  570. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  571. PG_ThemeWidget* Widget = new PG_ThemeWidget(parent, Rect);
  572. XMLParser->ParentObject = Widget;
  573. XMLParser->InhTagFlags |= SetThemeWidgetAtts(Widget, atts, XMLParser);
  574. return;
  575. }
  576. //Tag <lineedit> <LE>
  577. if (IsTag("lineedit","LE",XML_SECTION_BODY)) {
  578. int i;
  579. XMLParser->Section = XML_SECTION_LINEEDIT | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  580. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  581. i = PG_Layout::GetParamInt(atts, "length");
  582. if (i == -1) {
  583. i = 1000000;
  584. }
  585. PG_LineEdit* Widget = new PG_LineEdit(parent, Rect, "LineEdit", i);
  586. XMLParser->ParentObject = Widget;
  587. XMLParser->InhTagFlags |=SetLineEditAtts(Widget, atts, XMLParser);
  588. return;
  589. }
  590. //Tag <maskedit> <ME>
  591. if (IsTag("maskedit","ME",XML_SECTION_BODY)) {
  592. XMLParser->Section = XML_SECTION_MASKEDIT | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  593. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  594. PG_MaskEdit* Widget = new PG_MaskEdit(parent, Rect);
  595. XMLParser->ParentObject = Widget;
  596. XMLParser->InhTagFlags |=SetMaskEditAtts(Widget, atts, XMLParser);
  597. return;
  598. }
  599. //Tag <progressbar> <PB>
  600. if (IsTag("progressbar","PB",XML_SECTION_BODY)) {
  601. XMLParser->Section = XML_SECTION_PROGRESSBAR | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  602. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  603. PG_ProgressBar *Widget = new PG_ProgressBar(parent, Rect);
  604. XMLParser->ParentObject = Widget;
  605. XMLParser->InhTagFlags |=SetProgressBarAtts(Widget, atts, XMLParser);
  606. return;
  607. }
  608. //Tag <spinnerbox> <SB>
  609. if (IsTag("spinnerbox","SB",XML_SECTION_BODY)) {
  610. XMLParser->Section = XML_SECTION_SPINNERBOX | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  611. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  612. PG_SpinnerBox *Widget = new PG_SpinnerBox(parent, Rect);
  613. XMLParser->ParentObject = Widget;
  614. XMLParser->InhTagFlags |=SetSpinnerBoxAtts(Widget, atts, XMLParser);
  615. return;
  616. }
  617. //Tag <window> <WN>
  618. if (IsTag("window","WN",XML_SECTION_BODY)) {
  619. int i;
  620. XMLParser->Section = XML_SECTION_WINDOW | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  621. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  622. i = PG_Layout::GetParamInt(atts, "titleheight");
  623. if (i == -1) {
  624. i = 25;
  625. }
  626. int flags = PG_Layout::GetParamInt(atts, "flags");
  627. if(flags == -1) {
  628. flags = 0;
  629. }
  630. PG_Window *Widget = new PG_Window(parent, Rect, PG_Layout::GetParamStr(atts, "title"), (PG_Window::WindowFlags)flags, "Window", i);
  631. XMLParser->ParentObject = Widget;
  632. XMLParser->InhTagFlags |=SetWindowAtts(Widget, atts, XMLParser);
  633. return;
  634. }
  635. //Tag <messagebox> <MB>
  636. if (IsTag("messagebox","MB",XML_SECTION_BODY)) {
  637. PG_Rect B1Rect,B2Rect;
  638. char* B1Text,*B2Text;
  639. PG_MessageBox *Widget;
  640. XMLParser->Section = XML_SECTION_MESSAGEBOX | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  641. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  642. B1Text = PG_Layout::GetParamStr(atts, "b1text");
  643. B2Text = PG_Layout::GetParamStr(atts, "b2text");
  644. PG_Layout::GetParamRect(atts, "b1pos", B1Rect, parent);
  645. PG_Layout::GetParamRect(atts, "b2pos", B2Rect, parent);
  646. if (B2Text[0] == 0) {
  647. Widget = new PG_MessageBox(parent, Rect, PG_Layout::GetParamStr(atts, "title"), "", B1Rect, B1Text, PG_Layout::GetParamAlign(atts, "talign"));
  648. } else {
  649. Widget = new PG_MessageBox(parent, Rect, PG_Layout::GetParamStr(atts, "title"), "", B1Rect, B1Text, B2Rect, B2Text, PG_Layout::GetParamAlign(atts, "talign"));
  650. }
  651. XMLParser->ParentObject = Widget;
  652. XMLParser->InhTagFlags |=SetWindowAtts(Widget, atts, XMLParser);
  653. return;
  654. }
  655. //Tag <widgetlist> <WL>
  656. if (IsTag("widgetlist","WL",XML_SECTION_BODY)) {
  657. XMLParser->Section = XML_SECTION_WIDGETLIST | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  658. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  659. PG_WidgetList *Widget = new PG_WidgetList(parent, Rect);
  660. XMLParser->ParentObject = Widget;
  661. XMLParser->InhTagFlags |= SetWidgetListAtts(Widget, atts, XMLParser);
  662. return;
  663. }
  664. //Tag <listbox> <LB>
  665. if (IsTag("listbox","LB",XML_SECTION_BODY)) {
  666. XMLParser->Section = XML_SECTION_LISTBOX | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  667. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  668. PG_ListBox *Widget = new PG_ListBox(parent, Rect);
  669. XMLParser->ParentObject = Widget;
  670. XMLParser->InhTagFlags |= SetListBoxAtts(Widget, atts, XMLParser) &~INHTAGFLAG_ADDWIDGET;
  671. return;
  672. }
  673. //Tag <listboxitem> <LI>
  674. if (IsTag("listboxitem","LI",XML_SECTION_LISTBOX)) {
  675. XMLParser->Section = XML_SECTION_LISTBOXITEM | XML_SECTION_COMWIDPARAMS;
  676. int h = PG_Layout::GetParamInt(atts, "height");
  677. if(h < 0) {
  678. h = 25;
  679. }
  680. // to be updated!
  681. PG_ListBoxItem *Widget = new PG_ListBoxItem(parent, h, PG_Layout::GetParamStr(atts, "ltext"));
  682. //((PG_ListBox *)XMLParser->ParentObject)->AddItem(Widget);
  683. XMLParser->ParentObject = Widget;
  684. XMLParser->InhTagFlags |= SetListBoxItemAtts(Widget, atts, XMLParser);
  685. return;
  686. }
  687. //Tag <columnitem> <CI>
  688. if (IsTag("columnitem","CI",XML_SECTION_LISTBOX)) {
  689. XMLParser->Section = XML_SECTION_COLUMNITEM | XML_SECTION_COMWIDPARAMS;
  690. // to be updated!
  691. PG_ColumnItem *Widget = new PG_ColumnItem(parent, PG_Layout::GetParamInt(atts, "columns"),PG_Layout::GetParamInt(atts, "height"));
  692. //((PG_ListBox *)XMLParser->ParentObject)->AddItem(Widget);
  693. XMLParser->ParentObject = Widget;
  694. XMLParser->InhTagFlags |= SetListBoxItemAtts(Widget, atts, XMLParser);
  695. return;
  696. }
  697. //Tag <column> <CO>
  698. if (IsTag("column","CO",XML_SECTION_COLUMNITEM)) {
  699. int no,i;
  700. XMLParser->Section = XML_SECTION_COLUMNITEM | XML_SECTION_COMWIDPARAMS;
  701. no = PG_Layout::GetParamInt(atts, "number");
  702. if(no == -1) {
  703. no = 0;
  704. }
  705. if (no >= ((PG_ColumnItem *)XMLParser->ParentObject)->GetColumnCount ()) {
  706. PG_LogWRN("Column number error !!!");
  707. return;
  708. }
  709. i = PG_Layout::GetParamInt(atts, "width");
  710. if (i != -1) {
  711. ((PG_ColumnItem *)XMLParser->ParentObject)->SetColumnWidth(no, i);
  712. }
  713. ((PG_ColumnItem *)XMLParser->ParentObject)->SetColumnText(no, PG_Layout::GetParamStr(atts, "text"));
  714. return;
  715. }
  716. //Tag <radiobutton> <RB>
  717. if (IsTag("radiobutton","RB",XML_SECTION_BODY)) {
  718. XMLParser->Section = XML_SECTION_RADIOBUTTON | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  719. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  720. PG_RadioButton *Widget = new PG_RadioButton(
  721. parent,
  722. Rect,
  723. (const char*)PG_Layout::GetParamStr(atts, "text"),
  724. (PG_RadioButton *)PG_Application::GetWidgetByName(PG_Layout::GetParamStr(atts, "group")),
  725. 0);
  726. XMLParser->ParentObject = Widget;
  727. XMLParser->InhTagFlags |= SetRadioButtonAtts(Widget, atts, XMLParser);
  728. return;
  729. }
  730. //Tag <checkbutton> <CB>
  731. if (IsTag("checkbutton","CB",XML_SECTION_BODY)) {
  732. XMLParser->Section = XML_SECTION_CHECKBUTTON | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  733. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  734. PG_CheckButton *Widget = new PG_CheckButton(
  735. parent,
  736. Rect,
  737. PG_Layout::GetParamStr(atts, "text"),
  738. 0);
  739. XMLParser->ParentObject = Widget;
  740. XMLParser->InhTagFlags |= SetRadioButtonAtts(Widget, atts, XMLParser);
  741. return;
  742. }
  743. //Tag <scrollbar> <SB>
  744. if (IsTag("scrollbar","SB",XML_SECTION_BODY)) {
  745. XMLParser->Section = XML_SECTION_SCROLLBAR | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  746. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  747. PG_ScrollBar::ScrollDirection d = PG_Layout::GetParamScrollDirection(atts, "dir");
  748. (d <= 0) ? d = PG_ScrollBar::HORIZONTAL : d = PG_ScrollBar::VERTICAL;
  749. PG_ScrollBar *Widget = new PG_ScrollBar(parent, Rect, d);
  750. XMLParser->ParentObject = Widget;
  751. XMLParser->InhTagFlags |= SetScrollBarAtts(Widget, atts, XMLParser);
  752. return;
  753. }
  754. //Tag <slider> <SR>
  755. if (IsTag("slider","SR",XML_SECTION_BODY)) {
  756. XMLParser->Section = XML_SECTION_SCROLLBAR | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  757. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  758. PG_Slider *Widget = new PG_Slider(parent, Rect, PG_Layout::GetParamScrollDirection(atts, "dir"));
  759. XMLParser->ParentObject = Widget;
  760. XMLParser->InhTagFlags |=SetScrollBarAtts(Widget, atts, XMLParser);
  761. return;
  762. }
  763. //Tag <image> <IM>
  764. if (IsTag("image","IM",XML_SECTION_BODY)) {
  765. PG_Point Point;
  766. PG_Rect Rect;
  767. XMLParser->Section = XML_SECTION_IMAGE | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  768. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  769. Point.x=Rect.x;
  770. Point.y=Rect.y;
  771. PG_Image *Widget = new PG_Image(parent, Point, PG_Layout::GetParamStr(atts, "iimage"));
  772. XMLParser->ParentObject = Widget;
  773. XMLParser->InhTagFlags |= SetThemeWidgetAtts(Widget, atts, XMLParser);
  774. return;
  775. }
  776. //Tag <richedit> <RE>
  777. if (IsTag("richedit","RE",XML_SECTION_BODY)) {
  778. XMLParser->Section = XML_SECTION_RICHEDIT | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  779. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  780. PG_RichEdit *Widget = new PG_RichEdit(parent, Rect, PG_Layout::GetParamInt(atts, "vresize") == 1 , PG_Layout::GetParamInt(atts, "linewidth"));
  781. XMLParser->ParentObject = Widget;
  782. XMLParser->InhTagFlags |= SetScrollWidgetAtts(Widget, atts, XMLParser);
  783. return;
  784. }
  785. //Tag <popupmenu> <PM>
  786. if(IsTag("popupmenu", "PM", XML_SECTION_BODY)) {
  787. PG_Point Point;
  788. PG_Rect Rect;
  789. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  790. Point.x=Rect.x;
  791. Point.y=Rect.y;
  792. PG_PopupMenu* Widget = NULL;
  793. // is the current popup a child of another popup ?
  794. if(XMLParser->Section & XML_SECTION_POPUPMENU) {
  795. Widget = new PG_PopupMenu(NULL, 0, 0, PG_NULLSTR);
  796. PG_PopupMenu* menu = static_cast<PG_PopupMenu*>(XMLParser->ParentObject);
  797. menu->addMenuItem(PG_Layout::GetParamStr(atts, "caption"), Widget);
  798. } else {
  799. // is the popup a child of a menubar ?
  800. if(XMLParser->Section & XML_SECTION_MENUBAR) {
  801. Widget = new PG_PopupMenu(NULL, Point.x, Point.y, PG_Layout::GetParamStr(atts, "caption"));
  802. static_cast<PG_MenuBar*>(XMLParser->ParentObject)->Add(PG_Layout::GetParamStr(atts, "text"), Widget);
  803. } else {
  804. Widget = new PG_PopupMenu(parent, Point.x, Point.y, PG_Layout::GetParamStr(atts, "caption"));
  805. }
  806. }
  807. // register section popupmenu
  808. XMLParser->Section = XML_SECTION_POPUPMENU | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  809. XMLParser->ParentObject = Widget;
  810. XMLParser->InhTagFlags |= SetPopupMenuAtts(Widget, atts, XMLParser);
  811. XMLParser->InhTagFlags |= INHTAGFLAG_HIDE; // Popups shouldn't be displayed immediately
  812. return;
  813. }
  814. //Tag <popupmenuitem> <PM>
  815. if(IsTag("popupmenuitem", "PI", XML_SECTION_BODY)) {
  816. if(!(XMLParser->Section & XML_SECTION_POPUPMENU)) {
  817. PG_LogERR("popupmenuitem can't be created in the current context!");
  818. return;
  819. }
  820. PG_PopupMenu* menu = static_cast<PG_PopupMenu*>(XMLParser->ParentObject);
  821. menu->addMenuItem(PG_Layout::GetParamStr(atts, "caption"), PG_Layout::GetParamInt(atts, "id"));
  822. return;
  823. }
  824. //Tag <menubar> <MB>
  825. if(IsTag("menubar", "MB", XML_SECTION_BODY)) {
  826. PG_Rect Rect;
  827. XMLParser->Section = XML_SECTION_MENUBAR | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS;
  828. PG_Layout::GetParamRect(atts, "pos", Rect, parent);
  829. PG_MenuBar* Widget = new PG_MenuBar(parent, Rect);
  830. XMLParser->ParentObject = Widget;
  831. XMLParser->InhTagFlags |= SetThemeWidgetAtts(Widget, atts, XMLParser);
  832. return;
  833. }
  834. //Tag <style> <ST>
  835. if (IsTag("style","ST",XML_SECTION_COMWIDPARAMS)) {
  836. char *widget;
  837. char *object;
  838. XMLParser->Section = XML_SECTION_NONPAIR;
  839. widget = PG_Layout::GetParamStr(atts, "widget");
  840. if (widget[0] == 0)
  841. return;
  842. object = PG_Layout::GetParamStr(atts, "object");
  843. if (object[0] == 0) {
  844. XMLParser->ParentObject->LoadThemeStyle(widget);
  845. } else {
  846. XMLParser->ParentObject->LoadThemeStyle(widget,object);
  847. }
  848. return;
  849. }
  850. //Tag <font> <FT>
  851. if (IsTag("font","FT",XML_SECTION_COMWIDPARAMS)) {
  852. return;
  853. }
  854. if(XMLParser->Section & XML_SECTION_HEAD) {
  855. // create tag description
  856. PG_XMLTag* n = new PG_XMLTag(name, atts);
  857. PG_Application::GetApp()->sigXMLTag(n);
  858. }
  859. PG_LogWRN("Unknown tag `%s` in section %d !",name,XMLParser->Section);
  860. return;
  861. }
  862. static void XMLEndDoc(void *userData, const char *name) {
  863. ParseUserData_t *XMLParser = (ParseUserData_t *)userData;
  864. PG_Widget *WidgetToAdd = NULL;
  865. //if (XMLParser->Section & XML_SECTION_FONT)
  866. // XMLTextDoc(userData, PG_FFT_END_TAG , 2);
  867. if ((XMLParser->EndTagFlags & ENDTAGFLAG_SETSIZE) != 0) {
  868. XMLParser->ParentObject->SetSizeByText(XMLParser->Width,XMLParser->Height);
  869. }
  870. if ((XMLParser->EndTagFlags & ENDTAGFLAG_OBJECT) != 0) {
  871. if (((XMLParser->InhTagFlags & INHTAGFLAG_ADDWIDGET) != 0) && ((XMLParser->EndTagFlags & ENDTAGFLAG_WIDGETLIST) == 0)) {
  872. //WidgetToAdd = XMLParser->ParentObject;
  873. // goto object_end;
  874. }
  875. if ((XMLParser->InhTagFlags & INHTAGFLAG_HIDE) == 0) {
  876. if(XMLParser->ParentObject->GetParent() == NULL) {
  877. XMLParser->ParentObject->Show();
  878. }
  879. } else {
  880. XMLParser->ParentObject->Hide();
  881. }
  882. //object_end:
  883. // XMLParser->ParentObject->AddText("", true);
  884. }
  885. RestoreUserData(XMLParser);
  886. if (WidgetToAdd == NULL) {
  887. return;
  888. }
  889. ((PG_WidgetList *)(XMLParser->ParentObject))->AddChild(WidgetToAdd);
  890. }
  891. static void XMLTextDoc(void *userData, const XML_Char *s, int len) {
  892. char* buffer = new char[len+1];
  893. ParseUserData_t *XMLParser = (ParseUserData_t *)userData;
  894. memcpy(buffer,s,len);
  895. buffer[len]=0;
  896. if (XMLParser->ParentObject != NULL)
  897. XMLParser->ParentObject->AddText(buffer);
  898. delete[] buffer;
  899. }
  900. static void XMLProcInstr(void *userData, const XML_Char *target, const XML_Char *data) {
  901. ParseUserData_t *XMLParser = (ParseUserData_t *)userData;
  902. if (PG_LayoutProcessingInstruction != NULL)
  903. PG_LayoutProcessingInstruction(target, data, XMLParser->FileName, XMLParser->UserSpace);
  904. }
  905. bool PG_Layout::Load(PG_Widget* parent, const std::string& filename, void (* WorkCallback)(int now, int max), void *UserSpace) {
  906. ParseUserData_t XMLParser;
  907. int bytes_pos = 0;
  908. XMLParser.Parser = XML_ParserCreate(NULL);
  909. XMLParser.Section = XML_SECTION_DOC;
  910. XMLParser.PrevUserData = NULL;
  911. XMLParser.ParentObject = parent;
  912. XMLParser.InhTagFlags = 0;
  913. XMLParser.UserSpace = UserSpace;
  914. XML_SetUserData(XMLParser.Parser, &XMLParser);
  915. XML_SetElementHandler(XMLParser.Parser, XMLStartDoc, XMLEndDoc);
  916. XML_SetCharacterDataHandler(XMLParser.Parser, XMLTextDoc);
  917. XML_SetProcessingInstructionHandler(XMLParser.Parser, XMLProcInstr);
  918. XMLParser.FileName = filename.c_str();
  919. PG_File* f = PG_Application::OpenFile(XMLParser.FileName);
  920. if (f == NULL) {
  921. PG_LogWRN("Layout file %s not found !", filename.c_str());
  922. return false;
  923. }
  924. for (;;) {
  925. int bytes_read;
  926. void* buff;
  927. if ((buff = XML_GetBuffer(XMLParser.Parser, XML_BUFF_SIZE)) == NULL) {
  928. PG_LogWRN("Can`t get parse buffer");
  929. break;
  930. }
  931. bytes_read = f->read(buff, XML_BUFF_SIZE);
  932. bytes_pos += bytes_read;
  933. if (WorkCallback != NULL) {
  934. WorkCallback(bytes_pos , f->fileLength());
  935. }
  936. if (XML_ParseBuffer(XMLParser.Parser, bytes_read, bytes_read == 0) == 0) {
  937. PG_LogWRN("%s on the line %d pos %d",XML_ErrorString(XML_GetErrorCode(XMLParser.Parser)),XML_GetCurrentLineNumber(XMLParser.Parser), XML_GetCurrentColumnNumber(XMLParser.Parser));
  938. break;
  939. }
  940. if (bytes_read == 0) {
  941. break;
  942. }
  943. }
  944. if (XMLParser.Parser != NULL) {
  945. XML_ParserFree(XMLParser.Parser);
  946. }
  947. delete f;
  948. while (XMLParser.PrevUserData != NULL)
  949. RestoreUserData(&XMLParser);
  950. return true;
  951. }
  952. PG_XMLTag::PG_XMLTag(const char* n, const char** a) {
  953. // fill in name
  954. name = strdup(name);
  955. if(a == NULL) {
  956. atts = NULL;
  957. return;
  958. }
  959. // get size of arry
  960. const char** a0 = a;
  961. int s=0;
  962. while((*a0) != NULL) {
  963. a0++;
  964. s++;
  965. }
  966. // alloc array of pointers
  967. atts = (const char**)malloc((s+1)*sizeof(char*));
  968. a0 = atts;
  969. // copy strings to new array
  970. while(*a != NULL) {
  971. *a0 = strdup(*a);
  972. a0++;
  973. a++;
  974. }
  975. *a0 = NULL;
  976. }
  977. PG_XMLTag::~PG_XMLTag() {
  978. if(name != NULL) {
  979. free((void*)name);
  980. }
  981. if(atts == NULL) {
  982. return;
  983. }
  984. const char** a = atts;
  985. while(*a) {
  986. free((void*)*a);
  987. a++;
  988. }
  989. free((void*)atts);
  990. }