]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/applet/appletwindow.cpp
wxRemotelyScrolledTreeCtrl draws its own lines if wxTR_ROW_LINES flag
[wxWidgets.git] / contrib / src / applet / appletwindow.cpp
1 /****************************************************************************
2 *
3 * wxWindows HTML Applet Package
4 *
5 * Copyright (C) 1991-2001 SciTech Software, Inc.
6 * All rights reserved.
7 *
8 * ========================================================================
9 *
10 * The contents of this file are subject to the wxWindows License
11 * Version 3.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.wxwindows.org/licence3.txt
14 *
15 * Software distributed under the License is distributed on an
16 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17 * implied. See the License for the specific language governing
18 * rights and limitations under the License.
19 *
20 * ========================================================================
21 *
22 * Language: ANSI C++
23 * Environment: Any
24 *
25 * Description: Main wxHtmlAppletWindow class implementation
26 *
27 ****************************************************************************/
28
29 // For compilers that support precompilation
30 #include "wx/wxprec.h"
31 #include "wx/utils.h"
32 #include "wx/process.h"
33 #include "wx/spawnbrowser.h"
34 #include "wx/html/forcelnk.h"
35
36 // crt
37 #ifdef __WXMSW__
38 #include <process.h> // spawnl()
39 #endif
40
41 // Include private headers
42 #include "wx/applet/applet.h"
43 #include "wx/applet/window.h"
44 #include "wx/applet/loadpage.h"
45 #include "wx/applet/plugin.h"
46
47 // Preprocessor Stuff
48 #include "wx/applet/prepinclude.h"
49 #include "wx/applet/prepecho.h"
50 #include "wx/applet/prepifelse.h"
51
52 /*---------------------------- Global variables ---------------------------*/
53
54 wxHashTable wxHtmlAppletWindow::m_Cookies;
55
56 /*------------------------- Implementation --------------------------------*/
57
58 // Empty event handler. We include this event handler simply so that
59 // sub-classes of wxApplet can reference wxApplet in the event tables
60 // that they create as necessary.
61 BEGIN_EVENT_TABLE(wxHtmlAppletWindow, wxHtmlWindow)
62 EVT_LOAD_PAGE(wxHtmlAppletWindow::OnLoadPage)
63 EVT_PAGE_LOADED(wxHtmlAppletWindow::OnPageLoaded)
64 END_EVENT_TABLE()
65
66 // Implement the class functions for wxHtmlAppletWindow
67 IMPLEMENT_CLASS(wxHtmlAppletWindow, wxHtmlWindow);
68
69 // Define the wxAppletList implementation
70 #include "wx/listimpl.cpp"
71 WX_DEFINE_LIST(wxAppletList);
72
73 /****************************************************************************
74 REMARKS:
75 Constructor for the applet window class.
76 ****************************************************************************/
77 wxHtmlAppletWindow::wxHtmlAppletWindow(
78 wxWindow *parent,
79 wxWindowID id,
80 wxToolBarBase *navBar,
81 int navBackId,
82 int navForwardId,
83 const wxPoint& pos,
84 const wxSize& size,
85 long style,
86 const wxString& name,
87 const wxPalette& globalPalette)
88 : wxHtmlWindow(parent,id,pos,size,style,name), m_globalPalette(globalPalette)
89 {
90 // Init our locks
91 UnLock();
92
93 // setup client navbars
94 if (navBar) {
95 m_NavBarEnabled = true;
96 m_NavBar = navBar;
97 m_NavBackId = navBackId;
98 m_NavForwardId = navForwardId;
99 }
100 else {
101 m_NavBarEnabled = false;
102 m_NavBar = NULL;
103 }
104
105 m_NavBackId = navBackId;
106 m_NavForwardId = navForwardId;
107
108
109 // Set the key_type for applets
110 m_AppletList = wxAppletList(wxKEY_STRING);
111
112 // Add HTML preprocessors
113 // deleting preprocessors is done by the code within the window
114
115 incPreprocessor = new wxIncludePrep(); // #include preprocessor
116 incPreprocessor->ChangeDirectory(m_FS); // give it access to our filesys object
117
118 wxEchoPrep * echoPreprocessor = new wxEchoPrep(); // #echo preprocessor
119 wxIfElsePrep * ifPreprocessor = new wxIfElsePrep();
120
121 this->AddProcessor(incPreprocessor);
122 this->AddProcessor(echoPreprocessor);
123 this->AddProcessor(ifPreprocessor);
124 }
125
126 /****************************************************************************
127 REMARKS:
128 Destructor for the applet window class.
129 ****************************************************************************/
130 wxHtmlAppletWindow::~wxHtmlAppletWindow()
131 {
132 }
133
134 #include "scitech.h"
135
136 /****************************************************************************
137 PARAMETERS:
138 dc - wxDC object to draw on
139
140 REMARKS:
141 This function handles drawing the HTML applet window. Because the standard
142 wxWindows classes don't properly handle palette management, we add code
143 in here to properly select the global palette that we use for all drawing
144 into the DC before we allow the regular wxWindows code to finish the
145 drawing process.
146 ****************************************************************************/
147 void wxHtmlAppletWindow::OnDraw(
148 wxDC& dc)
149 {
150 // TODO: Only do this for <= 8bpp modes!
151 dc.SetPalette(m_globalPalette);
152 wxHtmlWindow::OnDraw(dc);
153 }
154
155 /****************************************************************************
156 PARAMETERS:
157 className - Name of the applet class to create an object for
158 size - Initial size of the applet to be created
159
160 RETURNS:
161 Pointer to the wxApplet created, or NULL if unable to create the applet.
162
163 REMARKS:
164 This function is used to create new wxApplet objects dynamically based on the
165 class name as a string. This allows instances of wxApplet classes to be
166 created dynamically based on string values embedded in the custom tags of an
167 HTML page.
168 ****************************************************************************/
169 wxApplet *wxHtmlAppletWindow::CreateApplet(
170 const wxString& classId,
171 const wxString& iName,
172 const wxHtmlTag& params,
173 const wxSize& size)
174 {
175 // Dynamically create the class instance at runtime
176 wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
177 if (!info)
178 return NULL;
179 wxObject *obj = info->CreateObject();
180 if (!obj)
181 return NULL;
182 wxApplet *applet = wxDynamicCast(obj,wxApplet);
183 if (!applet)
184 return NULL;
185 if (!applet->Create(this,params,size)) {
186 delete applet;
187 return NULL;
188 }
189 else {
190 // do some fixups on the size if its screwed up
191 wxSize nsize = applet->GetBestSize();
192 if (nsize.x < size.x) nsize.x = size.x;
193 if (nsize.y < size.y) nsize.y = size.y;
194 applet->SetSize(nsize);
195 }
196
197 m_AppletList.Append(iName,(wxObject*)applet);
198 return applet;
199 }
200
201 /****************************************************************************
202 PARAMETERS:
203 classId - Name of the Plugin class to create an object for
204
205 RETURNS:
206 Pointer to the wxplugIn created, or NULL if unable to create the PlugIn.
207
208 REMARKS:
209 This function is used to create new wxPlugIn objects dynamically based on the
210 class name as a string. This allows instances of wxPlugIn classes to be
211 created dynamically based on string values embedded in the custom tags of an
212 HTML page.
213 ****************************************************************************/
214 bool wxHtmlAppletWindow::CreatePlugIn(
215 const wxString& classId )
216 {
217 // Dynamically create the class instance at runtime
218 wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
219 if (!info)
220 return false;
221 wxObject *obj = info->CreateObject();
222 if (!obj)
223 return false;
224 wxPlugIn *plugIn = wxDynamicCast(obj,wxPlugIn);
225 if (!plugIn)
226 return false;
227 if (!plugIn->Create(this)) {
228 delete plugIn;
229 return false;
230 }
231 return true;
232 }
233
234 /****************************************************************************
235 PARAMETERS:
236 appletName - Name of the applet class to find
237
238 RETURNS:
239 Pointer to the wxApplet found, or NULL if not found.
240
241 REMARKS:
242 Find an instance of an applet based on it's name
243 ****************************************************************************/
244 wxApplet *wxHtmlAppletWindow::FindApplet(
245 const wxString& appletName)
246 {
247 wxAppletList::Node *node = m_AppletList.Find(appletName);
248 if (!node)
249 return NULL;
250 return node->GetData();
251 }
252
253 /****************************************************************************
254 PARAMETERS:
255 applet - Pointer to the applet object to remove from the list
256
257 RETURNS:
258 True if the applet was found and removed, false if not. The applet itself
259 is *not* destroyed!
260
261 REMARKS:
262 Remove an applet from the manager. Called during applet destruction
263 ****************************************************************************/
264 bool wxHtmlAppletWindow::RemoveApplet(
265 const wxApplet *applet)
266 {
267 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
268 if (node->GetData() == applet) {
269 m_AppletList.DeleteNode(node);
270 return true;
271 }
272 }
273 return false;
274 }
275
276 /****************************************************************************
277 PARAMETERS:
278 URL - New URL for the page to load
279
280 RETURNS:
281 True if page loaded successfully, false if not
282
283 REMARKS:
284 Remove an applet from the manager. Called during applet destruction
285 ****************************************************************************/
286 bool wxHtmlAppletWindow::LoadPage(
287 const wxString& link)
288 {
289 wxString href(link);
290
291 if (link.GetChar(0) == '?'){
292 wxString cmd = link.BeforeFirst('=');
293 wxString cmdValue = link.AfterFirst('=');
294
295 // Launches the default Internet browser for the system.
296 if(!(cmd.CmpNoCase("?EXTERNAL"))){
297 return wxSpawnBrowser(this, cmdValue.c_str());
298 }
299
300 // Launches an external program on the system.
301 if (!(cmd.CmpNoCase("?EXECUTE"))){
302 int code = spawnl( P_NOWAIT, cmdValue , NULL );
303 return (!code);
304 }
305
306 // Looks for a href in a variable stored as a cookie. The href can be
307 // changed on the fly.
308 if (!(cmd.CmpNoCase("?VIRTUAL"))){
309 VirtualData& temp = *((VirtualData*)FindCookie(cmdValue));
310 if (&temp) {
311 href = temp.GetHref();
312 }
313 else {
314 #ifdef CHECKED
315 wxLogError(_T("VIRTUAL LINK ERROR: '%s' does not exist."), cmdValue.c_str());
316 #endif
317 return true;
318 }
319 }
320
321 // This launches a qlet - It is like an applet but is more generic in that it
322 // can be of any wxWin type so it then has the freedom to do more stuff.
323 if (!(cmd.CmpNoCase("?WXAPPLET"))){
324 if (!cmdValue.IsNull()){
325 if (!CreatePlugIn(cmdValue)){
326 #ifdef CHECKED
327 wxLogError(_T("Launch Applet ERROR: '%s' does not exist."), cmdValue.c_str());
328 #endif
329 }
330 }
331 return true;
332 }
333 }
334
335 // Inform all the applets that the new page is being loaded
336 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
337 (node->GetData())->OnLinkClicked(wxHtmlLinkInfo(href));
338 Show(false);
339
340 bool stat = wxHtmlWindow::LoadPage(href);
341 Show(true);
342
343 // Enable/Dis the navbar tools
344 if (m_NavBarEnabled) {
345 m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
346 m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
347 }
348 return stat;
349 }
350
351 /****************************************************************************
352 PARAMETERS:
353 URL - String URL that we are navigating to
354
355 REMARKS:
356 Called when the user navigates to a new URL from the current page. We simply
357 call the LoadPage function above to load the new page and display it.
358 ****************************************************************************/
359 void wxHtmlAppletWindow::OnLinkClicked(
360 const wxHtmlLinkInfo& link)
361 {
362 LoadPage(link.GetHref());
363 }
364
365 /****************************************************************************
366 REMARKS:
367 Called when the user navigates forward within the HTML history stack.
368 We call all the applets in turn allowing them to handle the navigation
369 command prior to being destructed when the current page is destroyed.
370 ****************************************************************************/
371 bool wxHtmlAppletWindow::HistoryForward()
372 {
373 if (!HistoryCanForward())
374 return false;
375
376 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
377 (node->GetData())->OnHistoryForward();
378
379 return wxHtmlWindow::HistoryForward();
380 }
381
382 /****************************************************************************
383 REMARKS:
384 Called when the user navigates backwards within the HTML history stack.
385 We call all the applets in turn allowing them to handle the navigation
386 command prior to being destructed when the current page is destroyed.
387 ****************************************************************************/
388 bool wxHtmlAppletWindow::HistoryBack()
389 {
390 if (!HistoryCanBack())
391 return false;
392
393 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
394 (node->GetData())->OnHistoryBack();
395
396 return wxHtmlWindow::HistoryBack();
397 }
398
399 /****************************************************************************
400 REMARKS:
401 This function is used to disable the navigation bars. If you want to
402 toggle to the navbars off you must call this function.
403 ****************************************************************************/
404 void wxHtmlAppletWindow::DisableNavBar()
405 {
406 m_NavBarEnabled = false;
407 }
408
409 /****************************************************************************
410 REMARKS:
411 This function is used to enable the nav bars. If you toggle the nav bars on
412 you must call this function.
413 ****************************************************************************/
414 void wxHtmlAppletWindow::EnableNavBar()
415 {
416 m_NavBarEnabled = true;
417 }
418
419 /****************************************************************************
420 REMARKS:
421 This function is used to set the nav bar to a new nav bar if you deleted the
422 one that you were useing. Usally this happens when you toggle a nav bar
423 on or off.
424 ****************************************************************************/
425 void wxHtmlAppletWindow::SetNavBar(wxToolBarBase *navBar)
426 {
427 m_NavBar = navBar;
428 }
429
430 /****************************************************************************
431 PARAMETERS:
432 msg - wxEvent message to be sent to all wxApplets
433
434 REMARKS:
435 This function is called by the wxApplet's when they need to send a message
436 to all other applets on the current page. This is the primary form of
437 communication between applets on the page if they need to inform each
438 other of internal information.
439
440 Note that the event handling terminates as soon as the first wxApplet
441 handles the event. If the event should be handled by all wxApplet's,
442 the event handlers for the applets should not reset the wxEvent::Skip()
443 value (ie: by default it is true).
444 ****************************************************************************/
445 void wxHtmlAppletWindow::SendMessage(
446 wxEvent& msg)
447 {
448 // Preset the skip flag
449 msg.Skip();
450
451 // Process all applets in turn and send them the message
452 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
453 (node->GetData())->OnMessage(msg);
454 if (!msg.GetSkipped()){
455 wxMessageBox("BREAK");
456 break;
457 }
458 }
459 }
460
461 /****************************************************************************
462 PARAMETERS:
463 name - Uniq wxString used as hash key
464 cookie - wxObject data returned when name is found.
465
466 RETURNS:
467 True if new cookie was added, false if cookie with same name already exists.
468
469 REMARKS:
470 This function is called by the wxApplet's when they need register a cookie
471 of data in the applet window's cookie table. Cookies are arbitrary data
472 objects that are references by unique name's by the wxApplet. These
473 values can be used to store and retrieve data that needs to remain
474 persisent across invocations of the wxApplet. Ie: The first time an
475 applet is created it would use the cookie to store data to maintain
476 it's present state so that if you navigated back to the same page
477 is would be able to re-load the prior state as though the applet
478 was never actually destructed.
479
480 Note: If a cookie with the same name already exists, this function returns
481 false. Hence if you wish to replace a cookie you should first call
482 UnRegisterCookie to ensure the cookie is deleted and then call this
483 function.
484 ****************************************************************************/
485 bool wxHtmlAppletWindow::RegisterCookie(
486 const wxString& name,
487 wxObject *cookie)
488 {
489 // Fail if the named cookie already exists!
490 if (m_Cookies.Get(name))
491 return false;
492 m_Cookies.Put(name,cookie);
493 return true;
494 }
495
496 /****************************************************************************
497 PARAMETERS:
498 name - wxString uniq haskey used to remove item from hash
499
500 RETURNS:
501 True if found and deleted, false if not found in table.
502
503 REMARKS:
504 This function is called by the wxApplet's when they need de-register a
505 cookie of data in the applet window's cookie table. The data in the
506 cookie itself is also deleted before it is removed from the table.
507 ****************************************************************************/
508 bool wxHtmlAppletWindow::UnRegisterCookie(
509 const wxString& name)
510 {
511 wxObject *data = m_Cookies.Delete(name);
512 if (data) {
513 delete data;
514 return true;
515 }
516 return false;
517 }
518
519 /****************************************************************************
520 PARAMETERS:
521 msg - wxEvent message to be sent to all wxApplets
522
523 RETURNS:
524 Pointer to the cookie data if found, NULL if not found.
525
526 REMARKS:
527 This function is called by the wxApplet's when they need to find a cookie
528 of data given it's public name. If the cookie is not found, NULL is
529 returned.
530 ****************************************************************************/
531 wxObject *wxHtmlAppletWindow::FindCookie(
532 const wxString& name)
533 {
534 return m_Cookies.Get(name);
535 }
536
537 /****************************************************************************
538 PARAMETERS:
539 event - Event to handle
540
541 REMARKS:
542 This function handles delayed LoadPage events posted from applets that
543 need to change the page for the current window to a new window.
544 ****************************************************************************/
545 void wxHtmlAppletWindow::OnLoadPage(
546 wxLoadPageEvent &event)
547 {
548 // Test the mutex lock.
549 if (!(IsLocked())){
550 Lock();
551 if (event.GetHtmlWindow() == this){
552 if (LoadPage(event.GetHRef())){
553 // wxPageLoadedEvent evt;
554 // NOTE: This is reserved for later use as we might need to send
555 // page loaded events to applets.
556 }
557 }
558 UnLock();
559 }
560 }
561
562 /****************************************************************************
563 PARAMETERS:
564 event - Event to handle
565
566 REMARKS:
567 This function handles delayed LoadPage events posted from applets that
568 need to change the page for the current window to a new window.
569 ****************************************************************************/
570 void wxHtmlAppletWindow::OnPageLoaded(
571 wxPageLoadedEvent &)
572 {
573 Enable(true);
574 }
575
576 /****************************************************************************
577 PARAMETERS:
578 none
579
580 REMARKS:
581 This function tries to lock the mutex. If it can't, returns
582 immediately with false.
583 ***************************************************************************/
584 bool wxHtmlAppletWindow::TryLock()
585 {
586 if (!m_mutexLock) {
587 m_mutexLock = true;
588 return true;
589 }
590 return false;
591 }
592
593 /****************************************************************************
594 PARAMETERS:
595 name - name of the last applet that changed the data in this object
596 group - name of the group the allplet belongs to.
597 href - webpage to go to.
598
599 REMARKS:
600 VirtualData is used to store information on the virtual links.
601 ****************************************************************************/
602 VirtualData::VirtualData(
603 wxString& name,
604 wxString& group,
605 wxString& href )
606 {
607 m_name = name;
608 m_group = group;
609 m_href = href;
610 }
611
612 /****************************************************************************
613 PARAMETERS:
614 REMARKS:
615 VirtualData is used to store information on the virtual links.
616 ****************************************************************************/
617 VirtualData::VirtualData()
618 {
619 m_name.Empty();
620 m_group.Empty();
621 m_href.Empty();
622 }
623
624 /****************************************************************************
625 PARAMETERS:
626 REMARKS:
627 ****************************************************************************/
628 void AppletProcess::OnTerminate(
629 int,
630 int )
631 {
632 // we're not needed any more
633 delete this;
634 }
635
636 #include "wx/html/m_templ.h"
637
638 /****************************************************************************
639 REMARKS:
640 Implementation for the <embed> HTML tag handler. This handler takes care
641 of automatically constructing the wxApplet objects of the appropriate
642 class based on the <embed> tag information.
643 ****************************************************************************/
644 TAG_HANDLER_BEGIN(wxApplet, "WXAPPLET")
645
646 TAG_HANDLER_PROC(tag)
647 {
648 wxWindow *wnd;
649 wxHtmlAppletWindow *appletWindow;
650 wxApplet *applet;
651 wxString classId;
652 wxString name;
653 int width, height;
654
655 wnd = m_WParser->GetWindow();
656
657 if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL){
658 wxSize size = wxDefaultSize;
659 int al;
660 if (tag.HasParam("WIDTH")) {
661 tag.GetParamAsInt("WIDTH", &width);
662 size.SetWidth(width);
663 }
664
665 if (tag.HasParam("HEIGHT")) {
666 tag.GetParamAsInt("HEIGHT", &height);
667 size.SetHeight(height);
668 }
669
670 al = wxHTML_ALIGN_BOTTOM;
671 if (tag.HasParam(wxT("ALIGN"))) {
672 wxString alstr = tag.GetParam(wxT("ALIGN"));
673 alstr.MakeUpper(); // for the case alignment was in ".."
674 if (alstr == wxT("TEXTTOP") || alstr == wxT("TOP"))
675 al = wxHTML_ALIGN_TOP;
676 else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
677 al = wxHTML_ALIGN_CENTER;
678 }
679
680 if (tag.HasParam("CLASSID")){
681 classId = tag.GetParam("CLASSID");
682 if ( classId.IsNull() || classId.Len() == 0 ){
683 wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR);
684 return false;
685 }
686 if (tag.HasParam("NAME"))
687 name = tag.GetParam("NAME");
688
689 // If the name is NULL or len is zero then we assume that the html guy
690 // didn't include the name param which is optional.
691 if ( name.IsNull() || name.Len() == 0 )
692 name = classId;
693
694 // We got all the params and can now create the applet
695 if ((applet = appletWindow->CreateApplet(classId, name, tag , size)) != NULL){
696 applet->Show(true);
697 m_WParser->OpenContainer()->InsertCell(new wxHtmlAppletCell(applet,al));
698 }
699 else
700 wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
701 }
702 else{
703 wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR);
704 return false;
705 }
706 //Add more param parsing here. If or when spec changes.
707 //For now we'll ignore any other params those HTML guys
708 //might put in our tag.
709 }
710
711 return false;
712 }
713
714 TAG_HANDLER_END(wxApplet)
715
716 TAGS_MODULE_BEGIN(wxApplet)
717 TAGS_MODULE_ADD(wxApplet)
718 TAGS_MODULE_END(wxApplet)
719
720 /*********************************************************************************
721 wxHtmlAppletCell
722 *********************************************************************************/
723 wxHtmlAppletCell::wxHtmlAppletCell(wxWindow *wnd, int align) : wxHtmlCell()
724 {
725 int sx, sy;
726 m_Wnd = wnd;
727 m_Wnd->GetSize(&sx, &sy);
728 m_Width = sx, m_Height = sy;
729
730 switch (align) {
731 case wxHTML_ALIGN_TOP :
732 m_Descent = m_Height;
733 break;
734 case wxHTML_ALIGN_CENTER :
735 m_Descent = m_Height / 2;
736 break;
737 case wxHTML_ALIGN_BOTTOM :
738 default :
739 m_Descent = 0;
740 break;
741 }
742
743 SetCanLiveOnPagebreak(FALSE);
744 }
745
746
747 void wxHtmlAppletCell::Draw(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(view_y1), int WXUNUSED(view_y2))
748 {
749 int absx = 0, absy = 0, stx, sty;
750 wxHtmlCell *c = this;
751
752 while (c)
753 {
754 absx += c->GetPosX();
755 absy += c->GetPosY();
756 c = c->GetParent();
757 }
758
759 ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
760 m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy - wxHTML_SCROLL_STEP * sty);
761 }
762
763
764
765 void wxHtmlAppletCell::DrawInvisible(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y))
766 {
767 int absx = 0, absy = 0, stx, sty;
768 wxHtmlCell *c = this;
769
770 while (c)
771 {
772 absx += c->GetPosX();
773 absy += c->GetPosY();
774 c = c->GetParent();
775 }
776
777 ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
778 m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy - wxHTML_SCROLL_STEP * sty);
779 }
780
781
782
783 void wxHtmlAppletCell::Layout(int w)
784 {
785 int sx, sy;
786 m_Wnd->GetSize(&sx, &sy);
787 m_Width = sx, m_Height = sy;
788
789 wxHtmlCell::Layout(w);
790 }
791
792
793
794
795 // This is our little forcelink hack.
796 FORCE_LINK(loadpage)
797