#include "paragui.h" #include "pglayout.h" #include "pgwidget.h" #include "pgbutton.h" #include "pgdropdown.h" #include "pglabel.h" #include "pgthemewidget.h" #include "pgmaskedit.h" #include "pgprogressbar.h" #include "pgspinnerbox.h" #include "pgwindow.h" #include "pgwidgetlist.h" #include "pglistbox.h" #include "pglistboxitem.h" #include "pgcolumnitem.h" #include "pgmessagebox.h" #include "pgradiobutton.h" #include "pgcheckbutton.h" #include "pgscrollbar.h" #include "pgslider.h" #include "pgimage.h" #include "pgrichedit.h" #include "pglog.h" #include "pgpopupmenu.h" #include "pgmenubar.h" #include #include #include #include // Expat UNICODE workaround - copied from xmltchar.h (Expat dist) - Inserted by Ales Teska #ifdef XML_UNICODE #ifndef XML_UNICODE_WCHAR_T #error UNICODE version requires a 16-bit Unicode-compatible wchar_t=20 #endif #define T(x) L ## x #define tcscmp wcscmp #else /* not XML_UNICODE */ #define T(x) x #define tcscmp strcmp #endif #define IsTag(lx,sx,y) (((tcscmp(T(lx),T(name))==0)||(tcscmp(T(sx),T(name))==0))&&((XMLParser->Section & (y))!=0)) #define XML_BUFF_SIZE 1024 #define XML_SECTION_NONPAIR 0x00000000 #define XML_SECTION_DOC 0x00000001 #define XML_SECTION_LAYOUT 0x00000002 #define XML_SECTION_HEAD 0x00000004 #define XML_SECTION_BODY 0x00000008 #define XML_SECTION_BUTTON 0x00000010 #define XML_SECTION_COMWIDPARAMS 0x00000020 #define XML_SECTION_DROPDOWN 0x00000040 #define XML_SECTION_WIDGET 0x00000080 #define XML_SECTION_LABEL 0x00000100 #define XML_SECTION_GWIDGET 0x00000200 #define XML_SECTION_SFRAME 0x00000400 #define XML_SECTION_LINEEDIT 0x00000800 #define XML_SECTION_MASKEDIT 0x00001000 #define XML_SECTION_PROGRESSBAR 0x00002000 #define XML_SECTION_SPINNERBOX 0x00004000 #define XML_SECTION_WINDOW 0x00008000 #define XML_SECTION_WIDGETLIST 0x00010000 #define XML_SECTION_LISTBOX 0x00020000 #define XML_SECTION_LISTBOXITEM 0x00040000 #define XML_SECTION_COLUMNITEM 0x00080000 #define XML_SECTION_MESSAGEBOX 0x00100000 #define XML_SECTION_RADIOBUTTON 0x00200000 #define XML_SECTION_CHECKBUTTON 0x00400000 #define XML_SECTION_SCROLLBAR 0x00800000 #define XML_SECTION_IMAGE 0x01000000 #define XML_SECTION_RICHEDIT 0x02000000 #define XML_SECTION_WIDGETLISTEX 0x04000000 #define XML_SECTION_FONT 0x08000000 #define XML_SECTION_POPUPMENU 0x10000000 #define XML_SECTION_MENUBAR 0x20000000 #define XML_SECTION_POPUPMENUITEM 0x40000000 typedef struct { XML_Parser Parser; int Section; const char *FileName; int EndTagFlags; //Not inherited int InhTagFlags; //Inherited int Height; int Width; PG_Widget *ParentObject; void *PrevUserData; //Previous user data void *UserSpace; } ParseUserData_t; #define ENDTAGFLAG_OBJECT 1 #define ENDTAGFLAG_WIDGETLIST 2 #define ENDTAGFLAG_SETSIZE 4 #define INHTAGFLAG_HIDE 1 #define INHTAGFLAG_ADDWIDGET 2 static char Empty = 0; char *PG_Layout::GetParamStr(const char **Source, char *What) { char **c; for (c = (char **)Source;*c; c += 2) if (tcscmp(T(*c),T(What)) == 0) return(*(c+1)); return(&Empty); } void PG_Layout::GetParamRect(const char **Source, char *What, PG_Rect& Rect, PG_Widget* parent) { char *c = PG_Layout::GetParamStr(Source,What); if(c == NULL) { return; } if(strlen(c) == 0) { return; } SDL_Surface *screen = PG_Application::GetScreen(); char* parm; char *d; char tmp[16]; int i=0; int mx; int r[4]; r[0] = r[1] = r[2] = r[3] = 0; parm = strdup(c); for(d = strtok(parm,","); d != NULL; d = strtok(NULL,",")) { if(parent == NULL) { mx = ((i%2)==0) ? screen->w : screen->h; } else { mx = ((i%2)==0) ? parent->w : parent->h; } if( sscanf(d, "%d%[%]", & r[i], tmp) == 2 ) r[i] = (int) ((float)r[i]*mx/100); if(r[i]<0) r[i] = mx+r[i]; i++; } Rect.SetRect(r[0], r[1], r[2], r[3]); free(parm); } int PG_Layout::GetParamInt(const char **Source, char *What) { char* p = PG_Layout::GetParamStr(Source, What); if(p[0] == 0) { return -1; } return atoi(p); } int PG_Layout::GetParamAlign(const char **Source, char *What) { int ret = -1; char *c = PG_Layout::GetParamStr(Source,What); if (c[0]==0) return(-1); if (tcscmp(T(c),T("left")) == 0) ret = PG_TA_LEFT; if (tcscmp(T(c),T("right")) == 0) ret = PG_TA_RIGHT; if (tcscmp(T(c),T("center")) == 0) ret = PG_TA_CENTER; if (ret == -1) PG_LogWRN("Unknown align type %s !",c); return(ret); } int PG_Layout::GetParamIMode(const char **Source, char *What) { int ret = BKMODE_TILE; char *c = PG_Layout::GetParamStr(Source,What); if (tcscmp(T(c),T("tile")) == 0) ret = BKMODE_TILE; if (tcscmp(T(c),T("stretch")) == 0) ret = BKMODE_STRETCH; return(ret); } int PG_Layout::GetParamGrad(const char **Source, char *What, PG_Gradient *grad) { char *c = PG_Layout::GetParamStr(Source,What); int r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4; if (c[0] == 0) return(0); 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); grad->colors[0].r = r1; grad->colors[0].g = g1; grad->colors[0].b = b1; grad->colors[1].r = r2; grad->colors[1].g = g2; grad->colors[1].b = b2; grad->colors[2].r = r3; grad->colors[2].g = g3; grad->colors[2].b = b3; grad->colors[3].r = r4; grad->colors[3].g = g4; grad->colors[3].b = b4; return(1); } static void SaveUserData(ParseUserData_t *XMLParser) { ParseUserData_t *OldUserData; OldUserData = (ParseUserData_t *)malloc(sizeof(ParseUserData_t)); *OldUserData = *XMLParser; XMLParser->PrevUserData = OldUserData; XMLParser->EndTagFlags = 0; return; } static void RestoreUserData(ParseUserData_t *XMLParser) { ParseUserData_t *OldUserData = (ParseUserData_t *)XMLParser->PrevUserData; *XMLParser = *OldUserData; free(OldUserData); return; } void (* PG_LayoutWidgetParams)(PG_Widget *Widget, const char **atts) = NULL; void (* PG_LayoutProcessingInstruction)(const char *target, const char *data, const char *FileName, void *UserSpace) = NULL; //Declaration //static void XMLTextDoc(void *userData, const XML_Char *s, int len); static int SetWidgetAtts(PG_Widget *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c; int i,ret = 0; c = PG_Layout::GetParamStr(atts, "name"); if (c[0] != 0) Widget->SetName(c); i = PG_Layout::GetParamInt(atts, "id"); if (i != -1) { Widget->SetID(i); } c = PG_Layout::GetParamStr(atts, "fcolor"); if (c[0] != 0) { int r,g,b; sscanf(c,"%d,%d,%d",&r,&g,&b); Widget->SetFontColor(r,g,b); } c = PG_Layout::GetParamStr(atts, "fname"); if (c[0] != 0) { Widget->SetFontName(c); } i = PG_Layout::GetParamInt(atts, "fsize"); if (i != -1) { Widget->SetFontSize(i); } i = PG_Layout::GetParamInt(atts, "fstyle"); if (i != -1) { Widget->SetFontStyle(i); } i = PG_Layout::GetParamInt(atts, "findex"); if (i != -1) { Widget->SetFontIndex(i); } i = PG_Layout::GetParamInt(atts, "falpha"); if (i != -1) { Widget->SetFontAlpha(i); } c = PG_Layout::GetParamStr(atts, "data"); if (c[0] != 0) Widget->SetUserData(c, strlen(c)+1); if (PG_LayoutWidgetParams != NULL) PG_LayoutWidgetParams(Widget,atts); //TO-DO : Remove this (obsolete) c = PG_Layout::GetParamStr(atts, "text"); if (c[0] != 0) { Widget->SetText((const char*)c); } i = PG_Layout::GetParamInt(atts, "hide"); if (i == 1) ret |= INHTAGFLAG_HIDE; c = PG_Layout::GetParamStr(atts, "sbt"); if (c[0] != 0) { sscanf(c,"%d,%d", &XMLParser->Width, &XMLParser->Height); XMLParser->EndTagFlags |= ENDTAGFLAG_SETSIZE; } //Remove AddWidget tag ... ret &= ~INHTAGFLAG_ADDWIDGET; XMLParser->EndTagFlags |= ENDTAGFLAG_OBJECT; return(ret); } static int SetDropDownAtts(PG_DropDown *Widget, const char **atts,ParseUserData_t *XMLParser) { int i; i = PG_Layout::GetParamInt(atts, "indent"); if (i > 0) Widget->SetIndent(i); i = PG_Layout::GetParamInt(atts, "edit"); Widget->SetEditable(i == 1); return (SetWidgetAtts(Widget, atts, XMLParser)); } static int SetThemeWidgetAtts(PG_ThemeWidget *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c; PG_Gradient grad; c = PG_Layout::GetParamStr(atts, "image"); if (c[0] != 0) Widget->SetBackground(c,PG_Layout::GetParamIMode(atts, "imode")); int b = PG_Layout::GetParamInt(atts, "blend"); if(b != -1) { Widget->SetBackgroundBlend(b); } if (PG_Layout::GetParamGrad(atts, "gradient", &grad) != 0) Widget->SetGradient(grad); c = PG_Layout::GetParamStr(atts, "bimage"); if (c[0] != 0) { Widget->LoadImage(c); } b = PG_Layout::GetParamInt(atts, "transparency"); if(b != -1) { Widget->SetTransparency(b); } return SetWidgetAtts(Widget, atts, XMLParser); } static int SetLabelAtts(PG_Label *Widget, const char **atts, ParseUserData_t *XMLParser) { int i; char *c; i = PG_Layout::GetParamAlign(atts, "align"); if (i != -1) { Widget->SetAlignment(i); } i = PG_Layout::GetParamInt(atts, "indent"); if (i != -1) { Widget->SetIndent(i); } c = PG_Layout::GetParamStr(atts, "icon"); if (c[0] != 0) { Widget->SetIcon((const char*)c); } return(SetWidgetAtts(Widget, atts, XMLParser)); } static int SetUserButtonAtts(PG_Button *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c,*c1,*c2; int i,j,k; int b; c = PG_Layout::GetParamStr(atts, "upimage"); c1 = PG_Layout::GetParamStr(atts, "downimage"); c2 = PG_Layout::GetParamStr(atts, "overimage"); if (c1[0] == 0) { c1 = NULL; } if (c2[0] == 0) { c2 = NULL; } if (c[0] != 0) { b = PG_Layout::GetParamInt(atts, "colorkey"); if(b != -1) { Widget->SetIcon2(c, c1, c2, b); } else { Widget->SetIcon2(c, c1, c2); } } i = PG_Layout::GetParamInt(atts, "toggle"); Widget->SetToggle(i == 1); i = PG_Layout::GetParamInt(atts, "pressed"); Widget->SetPressed(i == 1); c = PG_Layout::GetParamStr(atts, "shift"); if (c[0] != 0) { sscanf(c,"%d",&i); Widget->SetShift(i); } c = PG_Layout::GetParamStr(atts, "border"); if (c[0] != 0) { sscanf(c,"%d,%d,%d",&i,&j,&k); Widget->SetBorderSize(i,j,k); } c = PG_Layout::GetParamStr(atts, "transparency"); if (c[0] != 0) { sscanf(c,"%d,%d,%d",&i,&j,&k); Widget->SetTransparency(i,j,k); } return(SetWidgetAtts(Widget, atts, XMLParser)); } static int SetButtonAtts(PG_Button *Widget, const char **atts, ParseUserData_t *XMLParser) { PG_Gradient grad; if (PG_Layout::GetParamGrad(atts, "upgrad", &grad) != 0) Widget->SetGradient(0,grad); if (PG_Layout::GetParamGrad(atts, "downgrad", &grad) != 0) Widget->SetGradient(1,grad); if (PG_Layout::GetParamGrad(atts, "selgrad", &grad) != 0) Widget->SetGradient(2,grad); /*SetBackground*/ return(SetUserButtonAtts(Widget, atts, XMLParser)); } static int SetPopupMenuAtts(PG_PopupMenu *Widget, const char **atts, ParseUserData_t *XMLParser) { return SetThemeWidgetAtts(Widget, atts, XMLParser); } static int SetLineEditAtts(PG_LineEdit *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c; if (PG_Layout::GetParamInt(atts, "readonly") == 1) Widget->SetEditable(0); c = PG_Layout::GetParamStr(atts, "validkeys"); if (c[0] != 0) Widget->SetValidKeys(c); c = PG_Layout::GetParamStr(atts, "passchar"); if (c[0] != 0) Widget->SetPassHidden(c[0]); return SetThemeWidgetAtts(Widget, atts, XMLParser); } static int SetMaskEditAtts(PG_MaskEdit *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c; Widget->SetMask(PG_Layout::GetParamStr(atts, "mask")); c = PG_Layout::GetParamStr(atts, "spacer"); if (c[0] != 0) Widget->SetSpacer(c[0]); return(SetLineEditAtts(Widget, atts, XMLParser)); } static int SetWindowAtts(PG_Window *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c; c = PG_Layout::GetParamStr(atts, "titlecolor"); if (c[0] != 0) { int r,g,b; sscanf(c,"%d,%d,%d",&r,&g,&b); Widget->SetColorTitlebar(((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xFF)); } return SetThemeWidgetAtts(Widget, atts, XMLParser); } static int SetProgressBarAtts(PG_ProgressBar *Widget, const char **atts, ParseUserData_t *XMLParser) { char *c; double p; c = PG_Layout::GetParamStr(atts, "progress"); if (c[0] != 0) { p = atof(c); Widget->SetProgress(p); } return SetThemeWidgetAtts(Widget, atts, XMLParser); } static int SetSpinnerBoxAtts(PG_SpinnerBox *Widget, const char **atts, ParseUserData_t *XMLParser) { int i,j; char *c; i = PG_Layout::GetParamInt(atts, "value"); if(i != -1) { Widget->SetValue(i); } i = PG_Layout::GetParamInt(atts, "min"); if(i != -1) { Widget->SetMinValue(i); } j = PG_Layout::GetParamInt(atts, "max"); if (j > i) Widget->SetMaxValue(j); c = PG_Layout::GetParamStr(atts, "mask"); if (c[0] != 0) Widget->SetMask(c); return SetThemeWidgetAtts(Widget, atts, XMLParser); } static int SetWidgetListAtts(PG_WidgetList *Widget, const char **atts, ParseUserData_t *XMLParser) { if (PG_Layout::GetParamInt(atts, "scrollbar") == 1) Widget->EnableScrollBar(1); XMLParser->EndTagFlags |= ENDTAGFLAG_WIDGETLIST; return (INHTAGFLAG_ADDWIDGET | SetThemeWidgetAtts(Widget, atts, XMLParser)); } static int SetListBoxAtts(PG_ListBox *Widget, const char **atts, ParseUserData_t *XMLParser) { Widget->SetMultiSelect(PG_Layout::GetParamInt(atts, "multisel") == 1); return(SetWidgetListAtts(Widget, atts, XMLParser)); } static int SetListBoxItemAtts(PG_ListBoxItem *Widget, const char **atts, ParseUserData_t *XMLParser) { if (PG_Layout::GetParamInt(atts, "select") == 1) Widget->Select(1); return(SetLabelAtts(Widget, atts, XMLParser)); } static int SetRadioButtonAtts(PG_RadioButton *Widget, const char **atts, ParseUserData_t *XMLParser) { if (PG_Layout::GetParamInt(atts, "pressed") == 1) Widget->SetPressed(); return SetThemeWidgetAtts(Widget, atts, XMLParser); } static int SetScrollBarAtts(PG_ScrollBar *Widget, const char **atts, ParseUserData_t *XMLParser) { int i,j; i = PG_Layout::GetParamInt(atts, "value"); if (i != -1) { Widget->SetPosition(i); } i = PG_Layout::GetParamInt(atts, "wsize"); if (i != -1) { Widget->SetWindowSize(i); } i = PG_Layout::GetParamInt(atts, "lsize"); if (i != -1) { Widget->SetLineSize(i); } i = PG_Layout::GetParamInt(atts, "psize"); if (i != -1) { Widget->SetPageSize(i); } i = PG_Layout::GetParamInt(atts, "min"); j = PG_Layout::GetParamInt(atts, "max"); if ((i < j) && (i != j)) { Widget->SetRange(i,j); } return SetThemeWidgetAtts(Widget, atts, XMLParser); } static void XMLStartDoc(void *userData, const char *name, const char **atts) { PG_Rect Rect; // -> UserData ???? - for parent size ParseUserData_t *XMLParser = (ParseUserData_t *)userData; SaveUserData(XMLParser); PG_Widget* parent = ((XMLParser->EndTagFlags & INHTAGFLAG_ADDWIDGET) == INHTAGFLAG_ADDWIDGET) ? NULL : XMLParser->ParentObject; //Tag if (IsTag("layout","LA",XML_SECTION_DOC)) { XMLParser->Section = XML_SECTION_LAYOUT; return; } //Tag if (IsTag("head","HD",XML_SECTION_LAYOUT)) { XMLParser->Section = XML_SECTION_HEAD; return; } //Tag if (IsTag("body","BD",XML_SECTION_LAYOUT)) { XMLParser->Section = XML_SECTION_BODY; return; } //Tag if (IsTag("widget","WD",XML_SECTION_BODY)) { XMLParser->Section = XML_SECTION_WIDGET | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS; PG_Layout::GetParamRect(atts, "pos", Rect, parent); PG_Widget *Widget = new PG_Widget(parent, Rect); XMLParser->ParentObject = Widget; XMLParser->InhTagFlags |=SetWidgetAtts(Widget, atts, XMLParser); return; } //Tag
if (IsTag("dropdown","DD",XML_SECTION_BODY)) { XMLParser->Section = XML_SECTION_DROPDOWN | XML_SECTION_BODY | XML_SECTION_COMWIDPARAMS; PG_Layout::GetParamRect(atts, "pos", Rect, parent); if (Rect.w < Rect.h) { PG_LogWRN("Width must be greater than height in "); return; } PG_DropDown *Widget = new PG_DropDown (parent, 0, Rect); XMLParser->ParentObject = Widget; XMLParser->InhTagFlags |=SetDropDownAtts(Widget, atts, XMLParser); return; } //Tag if (IsTag("dropdownitem","DI",XML_SECTION_DROPDOWN)) { XMLParser->Section = XML_SECTION_NONPAIR; ((PG_DropDown *)(XMLParser->ParentObject))->AddItem(PG_Layout::GetParamStr(atts, "text")); return; } //Tag