1 ///////////////////////////////////////// 2 // 3 // OpenLieroX 4 // 5 // code under LGPL, based on JasonBs work, 6 // enhanced by Dark Charlie and Albert Zeyer 7 // 8 // 9 ///////////////////////////////////////// 10 11 12 // Custom browser class 13 // Created 7/6/02 14 // Jason Boettcher 15 16 17 #ifndef __CBROWSER_H__DEPRECATED_GUI__ 18 #define __CBROWSER_H__DEPRECATED_GUI__ 19 20 21 #include "InputEvents.h" 22 #include <libxml/HTMLparser.h> 23 #include <stack> 24 #include "LieroX.h" 25 #include "Timer.h" 26 #include "Protocol.h" 27 #include "CScrollbar.h" 28 #include "HTTP.h" 29 #include "GfxPrimitives.h" 30 31 32 namespace DeprecatedGUI { 33 34 #define BORDER_SIZE 2 35 36 // Browser messages 37 enum { 38 BRW_NONE = -1, 39 BRW_KEY_PROCESSED = 0, 40 BRW_KEY_NOT_PROCESSED 41 }; 42 43 struct FontFormat { FontFormatFontFormat44 FontFormat() : bold(false), underline(false), italics(false), preformatted(false), size(0) {} 45 bool bold; 46 bool underline; 47 bool italics; 48 bool preformatted; 49 int size; 50 Color color; 51 }; 52 53 54 // Browser class 55 class CBrowser : public CWidget { 56 public: CBrowser()57 CBrowser() : 58 bFinished(false), 59 tHtmlDocument(NULL), 60 tRootNode(NULL), 61 fLastMouseScroll(0), 62 iBorderSize(BORDER_SIZE), 63 iDocumentHeight(0), 64 tCurrentLine(NULL), 65 curX(0), 66 curY(0), 67 iCurIndent(0), 68 iCursorColumn(0), 69 iCursorLine(0), 70 iSelectionStartLine(0), 71 iSelectionStartColumn(0), 72 iSelectionEndLine(0), 73 iSelectionEndColumn(0), 74 bSelectionGrabbed(false), 75 bDrawCursor(true), 76 tTimer(NULL), 77 bmpBuffer(NULL), 78 bNeedsRender(false) 79 { 80 tCurrentContext.tCurrentGroup = NULL; 81 tBgColor = Color(0,0,0,0); 82 } 83 84 public: 85 86 // Everything in the browser is an object - a chunk of text, a link, ... 87 // Objects are included in lines 88 class CBrowserObject { 89 public: 90 enum Type { 91 objNone = -1, 92 objText = 0, 93 objHr, 94 objList 95 }; 96 97 typedef void(CBrowser::*EventHandler)(CBrowserObject *); 98 public: CBrowserObject(CBrowser * parent,const SDL_Rect & rect)99 CBrowserObject(CBrowser *parent, const SDL_Rect& rect) : 100 tRect(rect), 101 tClickFunc(NULL), 102 tMouseMoveFunc(NULL), 103 tParent(parent), 104 iType(objNone), 105 bSelectable(false) 106 {} 107 CBrowserObject()108 CBrowserObject() : 109 tClickFunc(NULL), 110 tMouseMoveFunc(NULL), 111 tParent(NULL), 112 iType(objNone), 113 bSelectable(false) 114 { tRect = MakeRect(0, 0, 0, 0); } 115 CBrowserObject(const CBrowserObject & oth)116 CBrowserObject(const CBrowserObject& oth) { operator=(oth); } 117 ~CBrowserObject()118 virtual ~CBrowserObject() {} 119 120 protected: 121 friend class CBrowser; 122 SDL_Rect tRect; // HINT: position in the document, not on screen! 123 EventHandler tClickFunc; 124 EventHandler tMouseMoveFunc; 125 CBrowser *tParent; 126 Type iType; 127 bool bSelectable; 128 129 public: InBox(int x,int y)130 bool InBox(int x, int y) const { return x >= tRect.x && x < (tRect.x + tRect.w) 131 && y >= tRect.y && y < (tRect.y + tRect.h); } getWidth()132 int getWidth() { return tRect.w; } getHeight()133 int getHeight() { return tRect.h; } isSelectable()134 bool isSelectable() { return bSelectable; } 135 136 protected: DoMouseMove(int x,int y)137 virtual void DoMouseMove(int x, int y) { } DoMouseDown(int x,int y)138 virtual void DoMouseDown(int x, int y) { } DoClick(int x,int y)139 virtual void DoClick(int x, int y) { } CopyPropertiesTo(CBrowserObject * obj)140 void CopyPropertiesTo(CBrowserObject *obj) const { 141 obj->tRect = tRect; 142 obj->tClickFunc = tClickFunc; 143 obj->tMouseMoveFunc = tMouseMoveFunc; 144 obj->tParent = tParent; 145 obj->iType = iType; 146 obj->bSelectable = bSelectable; 147 } 148 149 public: getParent()150 CBrowser *getParent() const { return tParent; } getType()151 Type getType() const { return iType; } setClickHandler(EventHandler h)152 void setClickHandler(EventHandler h) { tClickFunc = h; } setMouseMoveHandler(EventHandler h)153 void setMouseMoveHandler(EventHandler h) { tMouseMoveFunc = h; } 154 Clear()155 virtual void Clear() { tRect = MakeRect(0, 0, 0, 0); 156 tClickFunc = NULL; tMouseMoveFunc = NULL; tClickFunc = NULL; tParent = NULL; } 157 158 CBrowserObject& operator=(const CBrowserObject& oth) { 159 assert(false); 160 return *this; 161 } 162 163 virtual void Render(SDL_Surface *dest, int x, int y) = 0; 164 165 virtual CBrowserObject *Clone() const = 0; 166 167 }; 168 169 // Group of objects 170 // An example of a group is a link (<a></a>) 171 class CObjectGroup { 172 private: 173 std::list<CBrowserObject *> tObjects; 174 175 protected: CopyPropertiesTo(CObjectGroup * oth)176 void CopyPropertiesTo(CObjectGroup *oth) const { 177 oth->tObjects = tObjects; 178 } 179 public: CObjectGroup()180 CObjectGroup() {} CObjectGroup(const CObjectGroup & oth)181 CObjectGroup(const CObjectGroup& oth) { operator=(oth); } 182 CObjectGroup& operator=(const CObjectGroup& oth) { 183 assert(false); 184 return *this; 185 } ~CObjectGroup()186 virtual ~CObjectGroup() {} 187 DoMouseMove(int x,int y)188 virtual void DoMouseMove(int x, int y) {} DoClick(int x,int y)189 virtual void DoClick(int x, int y) {} 190 191 virtual CObjectGroup *Clone() const = 0; 192 getObjects()193 const std::list<CBrowserObject *>& getObjects() { return tObjects; } addObject(CBrowserObject * obj)194 void addObject(CBrowserObject *obj) { tObjects.push_back(obj); } 195 bool InBox(int x, int y); 196 }; 197 198 private: 199 class CBrowserLine { 200 public: CBrowserLine()201 CBrowserLine() : iHeight(0), iLeftMargin(0), iMaxWidth(0), iDocumentY(0) {} CBrowserLine(int margin)202 CBrowserLine(int margin) : iHeight(0), iLeftMargin(margin), iMaxWidth(0), iDocumentY(0) {} 203 CBrowserLine(const CBrowserLine & oth)204 CBrowserLine(const CBrowserLine& oth) { operator=(oth); } 205 CBrowserLine& operator=(const CBrowserLine& oth) { 206 if (&oth != this) { 207 iHeight = oth.iHeight; 208 iLeftMargin = oth.iLeftMargin; 209 iMaxWidth = oth.iMaxWidth; 210 iDocumentY = oth.iDocumentY; 211 tObjects = oth.tObjects; 212 sPureText = oth.sPureText; 213 } 214 return *this; 215 } 216 217 ~CBrowserLine(); 218 private: 219 int iHeight; 220 int iLeftMargin; 221 int iMaxWidth; 222 int iDocumentY; 223 std::list<CBrowserObject *> tObjects; 224 std::string sPureText; // For better selection handling 225 226 public: setHeight(int h)227 void setHeight(int h) { iHeight = h; } setLeftMargin(int m)228 void setLeftMargin(int m) { iLeftMargin = m; } setMaxWidth(int m)229 void setMaxWidth(int m) { iMaxWidth = m; } setDocumentY(int y)230 void setDocumentY(int y) { iDocumentY = y; } getHeight()231 int getHeight() { return iHeight; } getLeftMargin()232 int getLeftMargin() { return iLeftMargin; } getMaxWidth()233 int getMaxWidth() { return iMaxWidth; } getDocumentY()234 int getDocumentY() { return iDocumentY; } isEmpty()235 bool isEmpty() { return tObjects.empty(); } ClearObjects()236 void ClearObjects() { tObjects.clear(); sPureText.clear(); } getPureText()237 const std::string& getPureText() { return sPureText; } 238 getObjects()239 std::list<CBrowserObject *>& getObjects() { return tObjects; } 240 void addObject(CBrowserObject *obj); 241 }; 242 243 class ParseContext { 244 public: 245 FontFormat tFormat; 246 CObjectGroup *tCurrentGroup; 247 }; 248 249 private: 250 // Attributes 251 CHttp cHttp; 252 std::string sURL; 253 std::string sHostName; 254 bool bFinished; 255 htmlDocPtr tHtmlDocument; 256 htmlNodePtr tRootNode; 257 std::vector<CBrowserLine *> tLines; 258 std::list<CObjectGroup *> tGroups; 259 AbsTime fLastMouseScroll; 260 int iBorderSize; 261 size_t iDocumentHeight; 262 263 // Parsing temps 264 ParseContext tCurrentContext; 265 std::stack<ParseContext> tContextStack; 266 CBrowserLine *tCurrentLine; 267 Color tBgColor; 268 int curX; 269 int curY; 270 int iCurIndent; // Where the new lines should start (left margin) 271 272 // Selection & caret 273 size_t iCursorColumn; 274 size_t iCursorLine; 275 size_t iSelectionStartLine; 276 size_t iSelectionStartColumn; 277 size_t iSelectionEndLine; 278 size_t iSelectionEndColumn; 279 280 size_t iSelectionGrabLine; 281 size_t iSelectionGrabColumn; 282 bool bSelectionGrabbed; 283 bool bDrawCursor; 284 Timer *tTimer; // For cursor blink 285 286 // Window attributes 287 CScrollbar cScrollbar; 288 bool bUseScroll; 289 bool bFingerDragged; 290 int iFingerDraggedPos; 291 292 // Other 293 SmartPointer<SDL_Surface> bmpBuffer; 294 bool bNeedsRender; 295 296 // Methods 297 htmlDocPtr ParseHTML(const std::string& data); 298 void AppendDocument(htmlDocPtr doc); 299 void AppendNode(xmlNodePtr node); 300 void UpdateRenderObjects(); 301 void ClearParser(); 302 void InitNodeWalk(); 303 void EndNodeWalk(); 304 void RenderContent(); 305 bool GetDrawSelectionBounds(size_t& top_line, size_t& bot_line); 306 void DrawSelectionForText(CBrowserObject *obj, size_t& line, size_t& column, int scroll_y); 307 void DrawSelection(); 308 void AddObject(CBrowserObject *obj); 309 void AddTextObject(const std::string& text); 310 void ParseText(const std::string& text); 311 void WalkNodes(xmlNodePtr node); 312 void WalkChildren(xmlNodePtr node); 313 bool InSelection(size_t line, size_t column); 314 std::string GetSelectedText(); 315 bool IsSelectionEmpty(); 316 void ClearSelection(); 317 void SwapSelectionEnds(); 318 void EndLine(); 319 void AdjustScrollbar(bool mouse = false); 320 void ReRender(); 321 void DrawCursor(SDL_Surface *bmpDest); 322 void ResetScrollbar(); 323 void AdjustBuffer(); 324 void OnTimerEvent(Timer::EventData ev); PushContext()325 void PushContext() { tContextStack.push(tCurrentContext); } PopContext()326 void PopContext() { tCurrentContext = tContextStack.top(); tContextStack.pop(); } 327 328 329 // Link helper functions 330 void StartLink(const std::string& url); 331 void EndLink(); 332 std::string GetFullURL(const std::string& url); 333 334 335 public: 336 // Methods 337 338 339 void Create(); 340 void Destroy(); 341 ClearDocument()342 void ClearDocument() { ClearParser(); bNeedsRender = true; } 343 344 //These events return an event id, otherwise they return -1 345 int MouseOver(mouse_t *tMouse); 346 int MouseUp(mouse_t *tMouse, int nDown); 347 int MouseWheelDown(mouse_t *tMouse); 348 int MouseWheelUp(mouse_t *tMouse); 349 int MouseDown(mouse_t *tMouse, int nDown); 350 int KeyDown(UnicodeChar c, int keysym, const ModifiersState& modstate); KeyUp(UnicodeChar c,int keysym,const ModifiersState & modstate)351 int KeyUp(UnicodeChar c, int keysym, const ModifiersState& modstate) { return BRW_NONE; } 352 SendMessage(int iMsg,DWORD Param1,DWORD Param2)353 DWORD SendMessage(int iMsg, DWORD Param1, DWORD Param2) { return 0; } SendMessage(int iMsg,const std::string & sStr,DWORD Param)354 DWORD SendMessage(int iMsg, const std::string& sStr, DWORD Param) { return 0; } SendMessage(int iMsg,std::string * sStr,DWORD Param)355 DWORD SendMessage(int iMsg, std::string *sStr, DWORD Param) { return 0; } 356 357 void Draw(SDL_Surface * bmpDest); 358 359 void MousePosToCursorPos(int ms_x, int ms_y, size_t& cur_x, size_t& cur_y); 360 void CursorPosToMousePos(size_t cur_x, size_t cur_y, int& ms_x, int& ms_y); 361 362 void LoadFromHTTP(const std::string& url); 363 void LoadFromFile(const std::string& file); 364 void LoadFromString(const std::string& data); 365 void AppendData(const std::string& data); 366 void ProcessHTTP(); 367 getBorderSize()368 int getBorderSize() { return iBorderSize; } setBorderSize(int size)369 void setBorderSize(int size) { iBorderSize = size; } 370 371 // TODO: create a descendant chatbox class and move the chatbox things there, they do not belong to browser 372 void InitializeChatBox( const std::string & initText = "" ); 373 void AddChatBoxLine(const std::string & text, Color color, TXT_TYPE textType, bool bold = false, bool underline = false); 374 std::string GetChatBoxText(); 375 void CleanUpChatBox( const std::vector<TXT_TYPE> & removedText, int maxLineCount ); 376 void ScrollToLastLine(); NeedsRepaint()377 bool NeedsRepaint() { return bNeedsRender; } 378 IsLoaded()379 bool IsLoaded() { return bFinished; } 380 GetHttp()381 CHttp& GetHttp() { return cHttp; } 382 383 // TODO: add function for getting individual text lines & their color 384 }; 385 386 }; // namespace DeprecatedGUI 387 388 #endif // __CBROWSER_H__DEPRECATED_GUI__ 389