// $Id: TGHtmlForm.cxx,v 1.3 2007/05/18 16:00:28 brun Exp $ // Author: Valeriy Onuchin 03/05/2007 /************************************************************************* * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ /************************************************************************** HTML widget for xclass. Based on tkhtml 1.28 Copyright (C) 1997-2000 D. Richard Hipp Copyright (C) 2002-2003 Hector Peraza. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **************************************************************************/ // Routines used for processing HTML makeup for forms. #include #include #include #include "TGHtml.h" #include "TGButton.h" #include "TGTextEntry.h" #include "TGListBox.h" #include "TGTextEdit.h" #include "TGComboBox.h" //______________________________________________________________________________ void TGHtml::UnmapControls() { // Unmap any input control that is currently mapped. TGHtmlInput *p; for (p = fFirstInput; p; p = p->fINext) { if (p->fFrame != 0 /*&& p->fFrame->IsMapped()*/) { p->fFrame->UnmapWindow(); } } } //______________________________________________________________________________ int TGHtml::MapControls() { // Map any control that should be visible according to the // current scroll position. At the same time, if any controls that // should not be visible are mapped, unmap them. After this routine // finishes, all controls should be in their proper places // regardless of where they might have been before. // // Return the number of controls that are currently visible. TGHtmlInput *p; // For looping over all controls int x, y, w, h; // Part of the virtual canvas that is visible int cnt = 0; // Number of visible controls x = fVisible.fX; y = fVisible.fY; w = fCanvas->GetWidth(); h = fCanvas->GetHeight(); for (p = fFirstInput; p; p = p->fINext) { if (p->fFrame == 0) continue; if (p->fY < y + h && p->fY + p->fH > y && p->fX < x + w && p->fX + p->fW > x) { // The control should be visible. Make is so if it isn't already p->fFrame->MoveResize(p->fX - x, p->fY + fFormPadding/2 - y, p->fW, p->fH - fFormPadding); /*if (!p->fFrame->IsMapped())*/ p->fFrame->MapWindow(); ++cnt; } else { // This control should not be visible. Unmap it. /*if (p->fFrame->IsMapped())*/ p->fFrame->UnmapWindow(); } } return cnt; } //______________________________________________________________________________ void TGHtml::DeleteControls() { // Delete all input controls. This happens when the TGHtml widget // is cleared. TGHtmlInput *p; // For looping over all controls p = fFirstInput; fFirstInput = 0; fLastInput = 0; fNInput = 0; if (p == 0) return; for (; p; p = p->fINext) { if (p->fPForm && ((TGHtmlForm *)p->fPForm)->fHasctl) { ((TGHtmlForm *)p->fPForm)->fHasctl = 0; } if (p->fFrame) { if (!fExiting) p->fFrame->DestroyWindow(); delete p->fFrame; p->fFrame = 0; } p->fSized = 0; } } //______________________________________________________________________________ static int InputType(TGHtmlElement *p) { // Return an appropriate type value for the given markup. int type = INPUT_TYPE_Unknown; const char *z; int i; static struct { const char *zName; int type; } types[] = { { "checkbox", INPUT_TYPE_Checkbox }, { "file", INPUT_TYPE_File }, { "hidden", INPUT_TYPE_Hidden }, { "image", INPUT_TYPE_Image }, { "password", INPUT_TYPE_Password }, { "radio", INPUT_TYPE_Radio }, { "reset", INPUT_TYPE_Reset }, { "submit", INPUT_TYPE_Submit }, { "text", INPUT_TYPE_Text }, { "name", INPUT_TYPE_Text }, { "textfield", INPUT_TYPE_Text }, { "button", INPUT_TYPE_Button }, { "name", INPUT_TYPE_Text }, }; switch (p->fType) { case Html_INPUT: z = p->MarkupArg("type", "text"); if (z == 0) break; for (i = 0; i < int(sizeof(types) / sizeof(types[0])); i++) { if (strcasecmp(types[i].zName, z) == 0) { type = types[i].type; break; } } break; case Html_SELECT: type = INPUT_TYPE_Select; break; case Html_TEXTAREA: type = INPUT_TYPE_TextArea; break; case Html_APPLET: case Html_IFRAME: case Html_EMBED: type = INPUT_TYPE_Applet; break; default: CANT_HAPPEN; break; } return type; } //______________________________________________________________________________ void TGHtml::SizeAndLink(TGFrame *frame, TGHtmlInput *pElem) { // 'frame' is the child widget that is used to implement an input // element. Query the widget for its size and put that information // in the pElem structure that represents the input. pElem->fFrame = frame; if (pElem->fFrame == 0) { pElem->Empty(); } else if (pElem->fItype == INPUT_TYPE_Hidden) { pElem->fW = 0; pElem->fH = 0; pElem->fFlags &= ~HTML_Visible; pElem->fStyle.fFlags |= STY_Invisible; } else { pElem->fW = frame->GetDefaultWidth(); pElem->fH = frame->GetDefaultHeight() + fFormPadding; pElem->fFlags |= HTML_Visible; pElem->fHtml = this; } pElem->fINext = 0; if (fFirstInput == 0) { fFirstInput = pElem; } else { fLastInput->fINext = pElem; } fLastInput = pElem; pElem->fSized = 1; #if 0 if (pElem->fFrame) { pElem->fFrame->ChangeOptions(pElem->fFrame->GetOptions() | kOwnBackground); pElem->fFrame->SetBackgroundColor(_defaultFrameBackground); } #else if (pElem->fFrame) { int bg = pElem->fStyle.fBgcolor; //int fg = pElem->fStyle.color; ColorStruct_t *cbg = fApColor[bg]; //ColorStruct_t *cfg = fApColor[fg]; pElem->fFrame->ChangeOptions(pElem->fFrame->GetOptions() | kOwnBackground); pElem->fFrame->SetBackgroundColor(cbg->fPixel); } #endif if (pElem->fFrame) { // the following is needed by some embedded widgets like // TGListBox and TGTextEdit pElem->fFrame->MapSubwindows(); pElem->fFrame->Layout(); } } //______________________________________________________________________________ void TGHtml::AppendText(TGString *str, TGHtmlElement *pFirs, TGHtmlElement *pEnd) { // Append all text and space tokens between pStart and pEnd to // the given TString. [ TGTextEdit ] while (pFirs && pFirs != pEnd) { switch (pFirs->fType) { case Html_Text: str->Append(((TGHtmlTextElement *)pFirs)->fZText); break; case Html_Space: if (pFirs->fFlags & HTML_NewLine) { str->Append("\n"); } else { int cnt; static char zSpaces[] = " "; cnt = pFirs->fCount; while (cnt > (int)sizeof(zSpaces) - 1) { str->Append(zSpaces, sizeof(zSpaces) - 1); cnt -= sizeof(zSpaces) - 1; } if (cnt > 0) { str->Append(zSpaces, cnt); } } break; default: break; } pFirs = pFirs->fPNext; } } class TGHtmlLBEntry : public TGTextLBEntry { public: TGHtmlLBEntry(const TGWindow *p, TGString *s, TGString *val, int ID) : TGTextLBEntry(p, s, ID) { fVal = val; } virtual ~TGHtmlLBEntry() { if (fVal) delete fVal; } const char *GetValue() const { return fVal ? fVal->GetString() : 0; } protected: TGString *fVal; }; //______________________________________________________________________________ void TGHtml::AddSelectOptions(TGListBox *lb, TGHtmlElement *p, TGHtmlElement *pEnd) { // The "p" argument points to a ) looking for //