51 void TGHtml::UnmapControls()
55 for (p = fFirstInput; p; p = p->fINext) {
56 if (p->fFrame != 0 ) {
57 p->fFrame->UnmapWindow();
71 int TGHtml::MapControls()
79 w = fCanvas->GetWidth();
80 h = fCanvas->GetHeight();
81 for (p = fFirstInput; p; p = p->fINext) {
82 if (p->fFrame == 0)
continue;
83 if (p->fY < y + h && p->fY + p->fH > y &&
84 p->fX < x + w && p->fX + p->fW > x) {
86 p->fFrame->MoveResize(p->fX - x, p->fY + fFormPadding/2 - y,
87 p->fW, p->fH - fFormPadding);
88 p->fFrame->MapWindow();
92 p->fFrame->UnmapWindow();
103 void TGHtml::DeleteControls()
114 for (; p; p = p->fINext) {
115 if (p->fPForm && ((TGHtmlForm *)p->fPForm)->fHasctl) {
116 ((TGHtmlForm *)p->fPForm)->fHasctl = 0;
119 if (!fExiting) p->fFrame->DestroyWindow();
130 static int InputType(TGHtmlElement *p)
132 int type = INPUT_TYPE_Unknown;
139 {
"checkbox", INPUT_TYPE_Checkbox },
140 {
"file", INPUT_TYPE_File },
141 {
"hidden", INPUT_TYPE_Hidden },
142 {
"image", INPUT_TYPE_Image },
143 {
"password", INPUT_TYPE_Password },
144 {
"radio", INPUT_TYPE_Radio },
145 {
"reset", INPUT_TYPE_Reset },
146 {
"submit", INPUT_TYPE_Submit },
147 {
"text", INPUT_TYPE_Text },
148 {
"name", INPUT_TYPE_Text },
149 {
"textfield", INPUT_TYPE_Text },
150 {
"button", INPUT_TYPE_Button },
151 {
"name", INPUT_TYPE_Text },
156 z = p->MarkupArg(
"type",
"text");
158 for (i = 0; i < int(
sizeof(types) /
sizeof(types[0])); i++) {
159 if (strcasecmp(types[i].zName, z) == 0) {
160 type = types[i].type;
167 type = INPUT_TYPE_Select;
171 type = INPUT_TYPE_TextArea;
177 type = INPUT_TYPE_Applet;
192 void TGHtml::SizeAndLink(TGFrame *frame, TGHtmlInput *pElem)
195 pElem->fFrame = frame;
196 if (pElem->fFrame == 0) {
198 }
else if (pElem->fItype == INPUT_TYPE_Hidden) {
201 pElem->fFlags &= ~HTML_Visible;
202 pElem->fStyle.fFlags |= STY_Invisible;
204 pElem->fW = frame->GetDefaultWidth();
205 pElem->fH = frame->GetDefaultHeight() + fFormPadding;
206 pElem->fFlags |= HTML_Visible;
210 if (fFirstInput == 0) {
213 fLastInput->fINext = pElem;
220 pElem->fFrame->ChangeOptions(pElem->fFrame->GetOptions() | kOwnBackground);
221 pElem->fFrame->SetBackgroundColor(_defaultFrameBackground);
225 int bg = pElem->fStyle.fBgcolor;
227 ColorStruct_t *cbg = fApColor[bg];
229 pElem->fFrame->ChangeOptions(pElem->fFrame->GetOptions() | kOwnBackground);
230 pElem->fFrame->SetBackgroundColor(cbg->fPixel);
237 pElem->fFrame->MapSubwindows();
238 pElem->fFrame->Layout();
246 void TGHtml::AppendText(TGString *str, TGHtmlElement *pFirs,
249 while (pFirs && pFirs != pEnd) {
250 switch (pFirs->fType) {
252 str->Append(((TGHtmlTextElement *)pFirs)->fZText);
256 if (pFirs->fFlags & HTML_NewLine) {
260 static char zSpaces[] =
" ";
262 while (cnt > (
int)
sizeof(zSpaces) - 1) {
263 str->Append(zSpaces,
sizeof(zSpaces) - 1);
264 cnt -=
sizeof(zSpaces) - 1;
267 str->Append(zSpaces, cnt);
275 pFirs = pFirs->fPNext;
280 class TGHtmlLBEntry :
public TGTextLBEntry {
282 TGHtmlLBEntry(
const TGWindow *p, TGString *s, TGString *val,
int ID) :
283 TGTextLBEntry(p, s, ID) { fVal = val; }
284 virtual ~TGHtmlLBEntry() {
if (fVal)
delete fVal; }
286 const char *GetValue()
const {
return fVal ? fVal->GetString() : 0; }
303 void TGHtml::AddSelectOptions(TGListBox *lb, TGHtmlElement *p,
308 while (p && p != pEnd && p->fType != Html_EndSELECT) {
309 if (p->fType == Html_OPTION) {
313 const char *zValue = p->MarkupArg(
"value",
"");
314 const char *sel = p->MarkupArg(
"selected",
"");
315 if (sel && !strcmp(sel,
"selected"))
320 str =
new TGString(
"");
321 while (p && p != pEnd &&
322 p->fType != Html_EndOPTION &&
323 p->fType != Html_OPTION &&
324 p->fType != Html_EndSELECT) {
325 if (p->fType == Html_Text) {
326 str->Append(((TGHtmlTextElement *)p)->fZText);
327 }
else if (p->fType == Html_Space) {
332 lb->AddEntry(
new TGHtmlLBEntry(lb->GetContainer(), str,
333 new TGString(zValue), id),
334 new TGLayoutHints(kLHintsTop | kLHintsExpandX));
337 lb->Select(selected);
357 int TGHtml::ControlSize(TGHtmlInput *pElem)
361 if (pElem->fSized)
return 0;
363 pElem->fItype = InputType(pElem);
371 switch (pElem->fItype) {
372 case INPUT_TYPE_File:
373 case INPUT_TYPE_Hidden:
374 case INPUT_TYPE_Image:
376 SizeAndLink(0, pElem);
379 case INPUT_TYPE_Checkbox: {
380 pElem->fCnt = ++fNInput;
381 TGCheckButton *f =
new TGCheckButton(fCanvas,
"", pElem->fCnt);
382 if (pElem->MarkupArg(
"checked", 0))
383 ((TGCheckButton *)f)->SetState(kButtonDown);
385 f->Resize(f->GetDefaultSize());
386 SizeAndLink(f, pElem);
390 case INPUT_TYPE_Radio: {
391 pElem->fCnt = ++fNInput;
392 TGRadioButton *f =
new TGRadioButton(fCanvas,
"", pElem->fCnt);
393 if (pElem->MarkupArg(
"checked", 0))
394 ((TGRadioButton *)f)->SetState(kButtonDown);
396 f->Resize(f->GetDefaultSize());
397 SizeAndLink(f, pElem);
401 case INPUT_TYPE_Reset: {
402 pElem->fCnt = ++fNInput;
403 const char *z = pElem->MarkupArg(
"value", 0);
405 TGTextButton *f =
new TGTextButton(fCanvas,
new TGHotString(z), pElem->fCnt);
408 f->Resize(f->GetDefaultSize());
409 SizeAndLink(f, pElem);
413 case INPUT_TYPE_Button:
414 case INPUT_TYPE_Submit: {
415 pElem->fCnt = ++fNInput;
416 const char *z = pElem->MarkupArg(
"value", 0);
417 if (!z) z =
"Submit";
418 TGTextButton *f =
new TGTextButton(fCanvas,
new TGHotString(z), pElem->fCnt);
422 f->Resize(f->GetDefaultSize());
423 SizeAndLink(f, pElem);
427 case INPUT_TYPE_Text: {
428 pElem->fCnt = ++fNInput;
429 const char *z = pElem->MarkupArg(
"maxlength", 0);
430 int maxlen = z ? atoi(z) : 256;
431 if (maxlen < 2) maxlen = 2;
432 z = pElem->MarkupArg(
"size", 0);
433 int size = z ? atoi(z) * 5 : 150;
434 TGTextEntry *f =
new TGTextEntry(fCanvas,
new TGTextBuffer(maxlen),
436 z = pElem->MarkupArg(
"value", 0);
437 if (z) f->AppendText(z);
438 f->Resize(size, f->GetDefaultHeight());
439 SizeAndLink(f, pElem);
443 case INPUT_TYPE_Password: {
444 pElem->fCnt = ++fNInput;
445 const char *z = pElem->MarkupArg(
"maxlength", 0);
446 int maxlen = z ? atoi(z) : 256;
447 if (maxlen < 2) maxlen = 2;
448 z = pElem->MarkupArg(
"size", 0);
449 int size = z ? atoi(z) * 5 : 150;
450 TGTextEntry *f =
new TGTextEntry(fCanvas,
new TGTextBuffer(maxlen),
452 f->SetEchoMode(TGTextEntry::kPassword);
453 z = pElem->MarkupArg(
"value", 0);
454 if (z) f->AppendText(z);
455 f->Resize(size, f->GetDefaultHeight());
456 SizeAndLink(f, pElem);
460 case INPUT_TYPE_Select: {
461 pElem->fCnt = ++fNInput;
462 const char *z = pElem->MarkupArg(
"size", 0);
463 int size = z ? atoi(z) : 1;
464 UInt_t width = 0, height = 0;
466 TGComboBox *cb =
new TGComboBox(fCanvas, pElem->fCnt);
467 TGListBox *lb = cb->GetListBox();
468 AddSelectOptions(lb, pElem, pElem->fPEnd);
469 TGLBEntry *e = lb->GetSelectedEntry();
470 if (e) lb->Select(e->EntryId(), kFALSE);
473 for (
int i=0;i<lb->GetNumberOfEntries();++i) {
474 TGHtmlLBEntry *te = (TGHtmlLBEntry *)lb->GetEntry(i);
475 if (te && te->GetText())
476 width = TMath::Max(width, te->GetDefaultWidth());
478 height = lb->GetItemVsize() ? lb->GetItemVsize()+4 : 22;
479 cb->Resize(width > 0 ? width+30 : 200,
480 height > 22 ? height : 22);
481 if (e) cb->Select(e->EntryId(), kFALSE);
482 SizeAndLink(cb, pElem);
484 TGListBox *lb =
new TGListBox(fCanvas, pElem->fCnt);
485 z = pElem->MarkupArg(
"multiple", 0);
486 if (z) lb->SetMultipleSelections(kTRUE);
487 AddSelectOptions(lb, pElem, pElem->fPEnd);
488 for (
int i=0;i<lb->GetNumberOfEntries();++i) {
489 TGHtmlLBEntry *te = (TGHtmlLBEntry *)lb->GetEntry(i);
490 if (te && te->GetText())
491 width = TMath::Max(width, te->GetDefaultWidth());
493 height = lb->GetItemVsize() ? lb->GetItemVsize() : 22;
494 lb->Resize(width > 0 ? width+30 : 200, height * size);
496 SizeAndLink(lb, pElem);
501 case INPUT_TYPE_TextArea: {
502 pElem->fCnt = ++fNInput;
508 TGTextEdit *f =
new TGTextEdit(fCanvas, 300, 200, pElem->fCnt);
510 AppendText(&str, pElem, pElem->fPEnd);
512 SizeAndLink(f, pElem);
516 case INPUT_TYPE_Applet: {
519 TGFrame *f = ProcessApplet(pElem);
524 pElem->fCnt = ++fNInput;
525 SizeAndLink(f, pElem);
531 pElem->fFlags &= ~HTML_Visible;
532 pElem->fStyle.fFlags |= STY_Invisible;
543 int TGHtml::FormCount(TGHtmlInput *p,
int radio)
545 TGHtmlElement *q = p;
552 if (radio && p->fType == INPUT_TYPE_Radio)
554 return ((TGHtmlForm *)p->fPForm)->fElements;
556 while ((q = q->fPPrev))
557 if (q->fType == Html_SELECT)
return ((TGHtmlInput *)q)->fSubId;
565 void TGHtml::AddFormInfo(TGHtmlElement *p)
569 const char *name, *z;
576 TGHtmlInput *input = (TGHtmlInput *) p;
577 if (!(f = fFormStart))
return;
578 input->fPForm = fFormStart;
582 fFormElemLast->fINext = input;
583 fFormElemLast = input;
584 input->fInpId = fInputIdx++;
585 t = input->fItype = InputType(input);
586 if (t == INPUT_TYPE_Radio) {
587 if ((name = p->MarkupArg(
"name", 0))) {
588 for (q = f->fPFirst; q; q = ((TGHtmlInput *)q)->fINext) {
589 if ((z = q->MarkupArg(
"name", 0)) && !strcmp(z, name)) {
590 input->fSubId = fRadioIdx++;
594 if (!q) input->fSubId = fRadioIdx = 0;
601 fFormStart = (TGHtmlForm *) p;
602 ((TGHtmlForm *)p)->fFormId = fNForm++;
605 case Html_EndTEXTAREA:
615 if (fFormElemLast && fFormElemLast->fType == Html_SELECT)
616 fFormElemLast->fSubId++;
627 static char gNeedEscape[] = {
628 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
629 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
630 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0,
631 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
632 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
633 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
634 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
637 #define NeedToEscape(C) ((C)>0 && (C)<127 && gNeedEscape[(int)(C)])
642 void TGHtml::EncodeText(TGString *str,
const char *z)
647 for (i = 0; z[i] && !NeedToEscape(z[i]); ++i) {}
648 if (i > 0) str->Append(z, i);
650 while (*z && NeedToEscape(*z)) {
653 }
else if (*z ==
'\n') {
654 str->Append(
"%0D%0A", 6);
655 }
else if (*z ==
'\r') {
659 snprintf(zBuf, 10,
"%%%02X", 0xff & *z);
660 str->Append(zBuf, 3);
670 Bool_t TGHtml::ProcessMessage(Long_t msg, Long_t p1, Long_t p2)
770 return TGView::ProcessMessage(msg, p1, p2);