webengine/wmlengine/src/lmgr/src/ImageMapBox.cpp
changeset 74 91031d3aab7d
parent 68 92a765b5b3e7
child 85 e358f2276d3f
equal deleted inserted replaced
68:92a765b5b3e7 74:91031d3aab7d
     1 /*
       
     2 * Copyright (c) 2003-2004 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Box class associated with the handling image maps
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32def.h>  // To avoid NULL redefine warning (no #ifndef NULL)
       
    21 
       
    22 #include "nw_lmgr_imagemapboxi.h"
       
    23 #include "nw_image_cannedimages.h"
       
    24 #include "nw_image_epoc32cannedimage.h"
       
    25 #include "nw_image_virtualimage.h"
       
    26 #include "nw_lmgr_rootbox.h"
       
    27 #include "nw_text_ucs2.h"
       
    28 #include "nw_lmgr_activecontainerbox.h"
       
    29 #include "nw_lmgr_areabox.h"
       
    30 #include "nwx_settings.h"
       
    31 #include "GDIDevicecontext.h"
       
    32 #include "nw_evt_controlkeyevent.h"
       
    33 #include "nw_evt_focusevent.h"
       
    34 #include "nw_evt_scrollevent.h"
       
    35 #include "nw_evt_activateevent.h"
       
    36 #include "nw_hed_hedeventhandler.h"
       
    37 #include "nw_lmgr_animatedimageboxi.h"
       
    38 #include "nw_lmgr_simplepropertylist.h"
       
    39 
       
    40 // ============================= LOCAL FUNCTIONS ===============================
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // NW_LMgr_ImageMapBox_InitializeBorder
       
    44 // Method which initializes the border width, color, and style to set values.
       
    45 //   This method is used by the DrawBorder method.
       
    46 // Returns: TBrowserStatusCode
       
    47 // -----------------------------------------------------------------------------
       
    48 //
       
    49 void
       
    50 NW_LMgr_ImageMapBox_InitializeBorder(CGDIDeviceContext* aDeviceContext,
       
    51                                      NW_LMgr_FrameInfo_t& aBorderWidth,
       
    52                                      NW_LMgr_FrameInfo_t& aBorderColor,
       
    53                                      NW_LMgr_FrameInfo_t& aBorderStyle,
       
    54                                      NW_GDI_Color_t& aInitialBgColor,
       
    55                                      NW_GDI_Color_t& aColor)
       
    56 {
       
    57   aBorderWidth.top    = (NW_GDI_Metric_t)NW_LMgr_Box_MediumBorderWidth;
       
    58   aBorderWidth.bottom = (NW_GDI_Metric_t)NW_LMgr_Box_MediumBorderWidth;
       
    59   aBorderWidth.left   = (NW_GDI_Metric_t)NW_LMgr_Box_MediumBorderWidth;
       
    60   aBorderWidth.right  = (NW_GDI_Metric_t)NW_LMgr_Box_MediumBorderWidth;
       
    61 
       
    62   aBorderColor.bottom = NW_GDI_Color_Blue;
       
    63   aBorderColor.left = NW_GDI_Color_Blue;
       
    64   aBorderColor.right = NW_GDI_Color_Blue;
       
    65   aBorderColor.top = NW_GDI_Color_Blue;
       
    66 
       
    67   aBorderStyle.bottom = NW_CSS_PropValue_solid;
       
    68   aBorderStyle.left = NW_CSS_PropValue_solid;
       
    69   aBorderStyle.right = NW_CSS_PropValue_solid;
       
    70   aBorderStyle.top = NW_CSS_PropValue_solid;
       
    71 
       
    72   aInitialBgColor = aDeviceContext->BackgroundColor();
       
    73   
       
    74   aColor = aBorderColor.bottom;
       
    75   aDeviceContext->SwitchAgainstBG (&aColor);
       
    76   aBorderColor.bottom = aColor;
       
    77   aColor = aBorderColor.left;
       
    78   aDeviceContext->SwitchAgainstBG (&aColor);
       
    79   aBorderColor.left = aColor;
       
    80   aColor = aBorderColor.right;
       
    81   aDeviceContext->SwitchAgainstBG (&aColor);
       
    82   aBorderColor.right = aColor;
       
    83   aColor = aBorderColor.top;
       
    84   aDeviceContext->SwitchAgainstBG (&aColor);
       
    85   aBorderColor.top = aColor;
       
    86 }
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // NW_LMgr_ImageMapBox_InitializeImageMapIcon
       
    90 // This method creates a new image map icon if one does not exist already and
       
    91 //   returns a pointer to the image.
       
    92 // Returns: NW_Image_AbstractImage_t*
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 TBrowserStatusCode
       
    96 NW_LMgr_ImageMapBox_InitializeImageMapIcon(NW_LMgr_ImageMapBox_t* thisObj)
       
    97   {
       
    98   NW_ASSERT(thisObj);
       
    99 
       
   100   NW_TRY (status)
       
   101     {
       
   102     NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( thisObj );
       
   103     NW_Image_AbstractImage_t* abstractImageMap = (NW_Image_AbstractImage_t*)NW_Image_CannedImages_GetImage( 
       
   104      rootBox->cannedImages, NW_Image_ImageMap );
       
   105 
       
   106     NW_ASSERT(abstractImageMap);
       
   107 
       
   108     // this will be deleted in the destructor
       
   109     thisObj->iImageMapIcon = (NW_Image_AbstractImage_t*)NW_Image_Virtual_New( abstractImageMap );
       
   110     NW_THROW_OOM_ON_NULL(thisObj->iImageMapIcon, status);
       
   111     }
       
   112   NW_CATCH (status)
       
   113     {
       
   114     }
       
   115   NW_FINALLY
       
   116     {
       
   117     return status;
       
   118     }
       
   119   NW_END_TRY
       
   120   }
       
   121 
       
   122 TBrowserStatusCode
       
   123 NW_LMgr_ImageMapBox_DrawImageMapIcon(NW_LMgr_ImageMapBox_t* thisObj,
       
   124                                      CGDIDeviceContext* deviceContext)
       
   125   {
       
   126   NW_GDI_Point2D_t imagePos;
       
   127   NW_GDI_Dimension3D_t imageSize;
       
   128   NW_GDI_Rectangle_t innerRect;
       
   129 
       
   130   NW_TRY (status)
       
   131     {
       
   132     // draw the image map icon on top of the image map
       
   133     deviceContext->SetPaintMode (NW_GDI_PaintMode_Copy);
       
   134 
       
   135     // if we don't have an image map icon, create one
       
   136     if (!thisObj->iImageMapIcon)
       
   137       {
       
   138       status = NW_LMgr_ImageMapBox_InitializeImageMapIcon(thisObj);
       
   139       NW_THROW_ON_ERROR(status);
       
   140       }
       
   141 
       
   142     // get image size 
       
   143     status = NW_Image_AbstractImage_GetSize( thisObj->iImageMapIcon, &imageSize );
       
   144     NW_THROW_ON_ERROR(status);
       
   145 
       
   146     NW_LMgr_Box_GetInnerRectangle( NW_LMgr_BoxOf(thisObj), &innerRect );
       
   147     // do not stretch out image map icon
       
   148     if( innerRect.dimension.height < imageSize.height )
       
   149         {
       
   150         imageSize.height = innerRect.dimension.height;
       
   151         }
       
   152     if( innerRect.dimension.width < imageSize.width )
       
   153         {
       
   154         imageSize.width = innerRect.dimension.width;
       
   155         }
       
   156 
       
   157     imagePos.x = innerRect.point.x + NW_LMgr_Box_MediumBorderWidth;
       
   158     imagePos.y = innerRect.point.y + NW_LMgr_Box_MediumBorderWidth;
       
   159 
       
   160     status = NW_Image_AbstractImage_DrawScaled( thisObj->iImageMapIcon, 
       
   161                                                 deviceContext,
       
   162                                                 &imagePos, 
       
   163                                                 &imageSize );
       
   164     NW_THROW_ON_ERROR(status);
       
   165     }
       
   166   NW_CATCH (status)
       
   167     {
       
   168     }
       
   169   NW_FINALLY
       
   170     {
       
   171     return status;
       
   172     }
       
   173   NW_END_TRY
       
   174   }
       
   175 
       
   176 /* ------------------------------------------------------------------------- *
       
   177    static data
       
   178  * ------------------------------------------------------------------------- */
       
   179 
       
   180 // -----------------------------------------------------------------------------
       
   181 static
       
   182 const
       
   183 NW_LMgr_IEventListener_Class_t _NW_LMgr_ImageMapBox_IEventListener_Class = {
       
   184   { /* NW_Object_Core         */
       
   185     /* super                  */ &NW_LMgr_IEventListener_Class,
       
   186     /* queryInterface         */ _NW_Object_Interface_QueryInterface
       
   187   },
       
   188   { /* NW_Object_Interface    */
       
   189     /* offset                 */ offsetof (NW_LMgr_ImageMapBox_t, NW_LMgr_IEventListener)
       
   190   },
       
   191   { /* NW_LMgr_IEventListener */
       
   192     /* processEvent           */ _NW_LMgr_ImageMapBox_IEventListener_ProcessEvent
       
   193   }
       
   194 };
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 static
       
   198 const NW_Object_Class_t* const _NW_LMgr_ImageMapBox_InterfaceList[] = {
       
   199   &_NW_LMgr_ImageMapBox_IEventListener_Class,
       
   200   NULL
       
   201 };
       
   202 
       
   203 // ========================== INTERFACE FUNCTIONS ==============================
       
   204 
       
   205 // -----------------------------------------------------------------------------
       
   206 NW_Uint8
       
   207 _NW_LMgr_ImageMapBox_IEventListener_ProcessEvent(NW_LMgr_IEventListener_t* eventListener,
       
   208                                                  NW_Evt_Event_t* event)
       
   209 {
       
   210   NW_LMgr_ImageMapBox_t* thisObj;
       
   211   NW_Uint8 ret = 0;
       
   212 
       
   213   // parameter assertion block
       
   214   NW_ASSERT (NW_Object_IsInstanceOf (eventListener,
       
   215                                      &NW_LMgr_IEventListener_Class));
       
   216   NW_ASSERT (NW_Object_IsInstanceOf (event, &NW_Evt_Event_Class));
       
   217 
       
   218   // obtain the implementer 
       
   219   thisObj = static_cast<NW_LMgr_ImageMapBox_t*>(NW_Object_Interface_GetImplementer (eventListener));
       
   220 
       
   221   if (thisObj->eventHandler != NULL) 
       
   222   {
       
   223     ret = NW_LMgr_EventHandler_ProcessEvent (thisObj->eventHandler,
       
   224                                              NW_LMgr_BoxOf (thisObj), 
       
   225                                              event);
       
   226   }
       
   227 
       
   228   return ret;
       
   229 }
       
   230 
       
   231 // -----------------------------------------------------------------------------
       
   232 const
       
   233 NW_LMgr_ImageMapBox_Class_t  NW_LMgr_ImageMapBox_Class = {
       
   234   { /* NW_Object_Core            */
       
   235     /* super                     */ &NW_LMgr_AnimatedImageBox_Class,
       
   236     /* queryInterface            */ _NW_Object_Base_QueryInterface
       
   237   },
       
   238   { /* NW_Object_Base            */
       
   239     /* interfaceList             */ _NW_LMgr_ImageMapBox_InterfaceList
       
   240   },
       
   241   { /* NW_Object_Dynamic         */
       
   242     /* instanceSize              */ sizeof (NW_LMgr_ImageMapBox_t),
       
   243     /* construct                 */ _NW_LMgr_ImageMapBox_Construct,
       
   244     /* destruct                  */ _NW_LMgr_ImageMapBox_Destruct
       
   245   },
       
   246   { /* NW_LMgr_Box               */
       
   247     /* split                     */ _NW_LMgr_ImgContainerBox_Split,
       
   248     /* resize                    */ _NW_LMgr_Box_Resize,
       
   249     /* postResize                */ _NW_LMgr_Box_PostResize,
       
   250     /* getMinimumContentSize     */ _NW_LMgr_ImageMapBox_GetMinimumContentSize,
       
   251     /* hasFixedContentSize       */ _NW_LMgr_MediaBox_HasFixedContentSize,
       
   252     /* constrain                 */ _NW_LMgr_Box_Constrain,
       
   253     /* draw                      */ _NW_LMgr_AnimatedImageBox_Draw,
       
   254     /* render                    */ _NW_LMgr_Box_Render,
       
   255     /* getBaseline               */ _NW_LMgr_Box_GetBaseline,
       
   256     /* shift                     */ _NW_LMgr_Box_Shift,
       
   257     /* clone                     */ _NW_LMgr_Box_Clone
       
   258   },
       
   259   { /* NW_LMgr_MediaBox          */
       
   260     /* unused                    */ NW_Object_Unused
       
   261   },
       
   262   { /* NW_LMgr_ImgContainerBox   */
       
   263     /* unused                    */ NW_Object_Unused
       
   264   },
       
   265   { /* NW_LMgr_AnimatedImageBox  */
       
   266     /* unused                    */ NW_Object_Unused
       
   267   },
       
   268   { /* NW_LMgr_ImageMapBox       */
       
   269     /* unused                    */ NW_Object_Unused
       
   270   }
       
   271 };
       
   272 
       
   273 // ============================ MEMBER FUNCTIONS ===============================
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 // _NW_LMgr_ImageMapBox_Construct
       
   277 // Description:  The constructor.  
       
   278 // Returns: TBrowserStatusCode
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 TBrowserStatusCode
       
   282 _NW_LMgr_ImageMapBox_Construct (NW_Object_Dynamic_t* dynamicObject,
       
   283                                 va_list* argp)
       
   284 {
       
   285   NW_TRY (status) 
       
   286   {
       
   287     NW_LMgr_ImageMapBox_t* imageBox;
       
   288 
       
   289     NW_ASSERT(dynamicObject != NULL);
       
   290 
       
   291     // invoke our superclass constructor
       
   292     status = _NW_LMgr_AnimatedImageBox_Construct (dynamicObject, argp);
       
   293     NW_THROW_ON_ERROR(status);
       
   294 
       
   295     // for convenience
       
   296     imageBox = NW_LMgr_ImageMapBoxOf( dynamicObject );
       
   297    
       
   298     // initialize the member variables
       
   299     imageBox->eventHandler = va_arg (*argp, NW_LMgr_EventHandler_t*);
       
   300     
       
   301     imageBox->iUrl = va_arg (*argp, NW_Text_t*);
       
   302 
       
   303     imageBox->iAreaBoxArrayList = NULL;
       
   304 
       
   305     imageBox->iImageMapIcon = NULL;
       
   306   } 
       
   307   NW_CATCH (status) 
       
   308   {
       
   309   } 
       
   310   NW_FINALLY 
       
   311   {
       
   312     return status;
       
   313   } 
       
   314   NW_END_TRY
       
   315 }
       
   316 
       
   317 // -----------------------------------------------------------------------------
       
   318 // _NW_LMgr_ImageMapBox_Destruct
       
   319 // Description:  The destructor.  
       
   320 // Returns: void
       
   321 // -----------------------------------------------------------------------------
       
   322 //
       
   323 void
       
   324 _NW_LMgr_ImageMapBox_Destruct (NW_Object_Dynamic_t* dynamicObject)
       
   325   {
       
   326   NW_LMgr_ImageMapBox_t* thisObj;
       
   327 
       
   328   // for convenience 
       
   329   thisObj = NW_LMgr_ImageMapBoxOf (dynamicObject);
       
   330   // destroy members
       
   331   if (thisObj->iAreaBoxArrayList != NULL)
       
   332     {
       
   333     //
       
   334     NW_ADT_Vector_Metric_t arrayIndex;
       
   335     NW_ADT_Vector_Metric_t elementSize = NW_ADT_Vector_GetSize( thisObj->iAreaBoxArrayList );
       
   336 
       
   337     for( arrayIndex = 0; arrayIndex < elementSize; arrayIndex++ ) 
       
   338       {
       
   339       NW_LMgr_AreaBox_t* areaBox = *(NW_LMgr_AreaBox_t**)NW_ADT_Vector_ElementAt( thisObj->iAreaBoxArrayList, arrayIndex );
       
   340       NW_Object_Delete( areaBox );
       
   341       }
       
   342 
       
   343     NW_Object_Delete (thisObj->iAreaBoxArrayList);
       
   344     thisObj->iAreaBoxArrayList = NULL;
       
   345     }
       
   346 
       
   347   if (thisObj->iImageMapIcon != NULL)
       
   348     {
       
   349     NW_Object_Delete( thisObj->iImageMapIcon );
       
   350     thisObj->iImageMapIcon = NULL;
       
   351     }
       
   352   
       
   353   if (thisObj->iUrl != NULL)
       
   354     {
       
   355     NW_Object_Delete( thisObj->iUrl );
       
   356     thisObj->iUrl = NULL;
       
   357     }
       
   358     
       
   359   if (thisObj->eventHandler != NULL)
       
   360     {
       
   361   	NW_Object_Delete( thisObj->eventHandler );
       
   362   	thisObj->eventHandler = NULL;
       
   363     }
       
   364   }
       
   365 
       
   366 // -----------------------------------------------------------------------------
       
   367 TBrowserStatusCode
       
   368 _NW_LMgr_ImageMapBox_GetMinimumContentSize( NW_LMgr_Box_t* box,
       
   369                                             NW_GDI_Dimension2D_t* size )
       
   370   {
       
   371   NW_TRY (status) 
       
   372     {
       
   373     NW_GDI_Dimension3D_t imageSize;
       
   374     NW_LMgr_ImageMapBox_t* thisObj = NW_LMgr_ImageMapBoxOf( box );
       
   375     NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox( box );
       
   376 
       
   377     // call the parent's class implementation to get the size of the image map box
       
   378     status = _NW_LMgr_ImgContainerBox_GetMinimumContentSize (box, size);
       
   379     NW_THROW_ON_ERROR( status );
       
   380     
       
   381     // we only want to recalculate the size of the image map box if we are
       
   382     // in small screen mode
       
   383     if( NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) )
       
   384       {
       
   385       // now we need to get the size of the icon we are using
       
   386       // if we don't have an image map icon, create one
       
   387       if (!thisObj->iImageMapIcon)
       
   388         {
       
   389         status = NW_LMgr_ImageMapBox_InitializeImageMapIcon(thisObj);
       
   390         NW_THROW_ON_ERROR(status);
       
   391         }
       
   392 
       
   393       status = NW_Image_AbstractImage_GetSize( thisObj->iImageMapIcon, &imageSize );
       
   394       NW_THROW_ON_ERROR(status);
       
   395   
       
   396       // we want to see if the image map box size is less that the icon size plus
       
   397       // the size of the borders (upper/lower)
       
   398       if (size->height < (imageSize.height + (NW_LMgr_Box_MediumBorderWidth * 2)))
       
   399         {
       
   400         size->height = (imageSize.height + (NW_LMgr_Box_MediumBorderWidth * 2));
       
   401         }
       
   402       } 
       
   403     }
       
   404   NW_CATCH (status) 
       
   405     {  
       
   406     } 
       
   407   NW_FINALLY 
       
   408     {
       
   409     return status;  
       
   410     } 
       
   411   NW_END_TRY
       
   412   }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 NW_LMgr_ImageMapBox_t*
       
   416 NW_LMgr_ImageMapBox_New (NW_ADT_Vector_Metric_t aNumProperties, 
       
   417                          NW_Image_AbstractImage_t* aVirtualImage, 
       
   418                          NW_Text_t* aAltText, 
       
   419                          NW_Bool aBrokenImage,
       
   420                          NW_LMgr_EventHandler_t* aEventHandler,
       
   421                          NW_Text_t* aUrl)
       
   422 {
       
   423   return (NW_LMgr_ImageMapBox_t*)NW_Object_New (&NW_LMgr_ImageMapBox_Class, 
       
   424     aNumProperties, aVirtualImage, aAltText, aBrokenImage, aEventHandler, aUrl );
       
   425 }
       
   426 
       
   427 // -----------------------------------------------------------------------------
       
   428 void
       
   429 NW_LMgr_ImageMapBox_SetAreaBoxList (NW_LMgr_ImageMapBox_t* thisObj, 
       
   430                                     NW_ADT_DynamicVector_t* aAreaBoxArrayList)
       
   431 {
       
   432   thisObj->iAreaBoxArrayList = aAreaBoxArrayList;
       
   433 }
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 NW_ADT_DynamicVector_t*
       
   437 NW_LMgr_ImageMapBox_GetAreaBoxList (NW_LMgr_ImageMapBox_t* thisObj)
       
   438 {
       
   439   return thisObj->iAreaBoxArrayList;
       
   440 }
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 TBrowserStatusCode
       
   444 NW_LMgr_ImageMapBox_DrawBorder(NW_LMgr_Box_t* box,
       
   445                                CGDIDeviceContext* deviceContext)
       
   446   {
       
   447   NW_LMgr_FrameInfo_t borderWidth;
       
   448   NW_LMgr_FrameInfo_t borderStyle;
       
   449   NW_LMgr_FrameInfo_t borderColor;
       
   450   NW_GDI_Color_t initialBgColor = 0;
       
   451   NW_GDI_Color_t color = 0;
       
   452   NW_LMgr_ImageMapBox_t* thisObj = NULL; 
       
   453   NW_ADT_Vector_Metric_t arrayIndex;
       
   454   NW_ADT_Vector_Metric_t elementSize;
       
   455   NW_LMgr_AreaBox_t* areaBox = NULL;
       
   456 
       
   457   NW_TRY(status)
       
   458     {  
       
   459     NW_ASSERT(box != NULL);
       
   460     thisObj = NW_LMgr_ImageMapBoxOf( box );
       
   461 
       
   462     NW_LMgr_RootBox_t* rootBox = NW_LMgr_Box_GetRootBox(box);
       
   463     NW_ASSERT(rootBox);
       
   464 
       
   465     NW_HED_AppServices_t* appServices = rootBox->appServices;
       
   466     NW_ASSERT(appServices);
       
   467 
       
   468     NW_LMgr_ImageMapBox_InitializeBorder(deviceContext,
       
   469                                          borderWidth,
       
   470                                          borderColor,
       
   471                                          borderStyle,
       
   472                                          initialBgColor,
       
   473                                          color);
       
   474 
       
   475     // if we are in vertical layout mode (small screen) then we want to "highlight" the
       
   476     // image box and display the image map icon if it has focus, otherwise we are in 
       
   477     // normal layout mode and we will want to highlight the area box that has focus
       
   478     if( NW_LMgr_RootBox_GetSmallScreenOn( rootBox ) )
       
   479       {
       
   480       if( NW_LMgr_Box_HasFocus ( NW_LMgr_BoxOf( thisObj ) ) )
       
   481         {
       
   482         // draw the border around the image map box
       
   483         status = NW_LMgr_Box_DrawBorder(NW_LMgr_Box_GetFormatBounds(box), 
       
   484                                          deviceContext, 
       
   485                                          &borderWidth, 
       
   486                                          &borderStyle, 
       
   487                                          &borderColor);
       
   488         NW_THROW_ON_ERROR(status);
       
   489 
       
   490         // draw the image map icon on the top left corner of the image
       
   491         status = NW_LMgr_ImageMapBox_DrawImageMapIcon(thisObj,
       
   492                                                       deviceContext);
       
   493 
       
   494         NW_THROW_ON_ERROR(status);
       
   495         }
       
   496       }
       
   497     else
       
   498       {
       
   499       // loop through area boxes and see if any are in focus
       
   500       NW_ADT_DynamicVector_t* areaBoxArray = NW_LMgr_ImageMapBox_GetAreaBoxList(thisObj);
       
   501 
       
   502       // It is possible to have an ImageMapBox with no AreaBoxArray
       
   503       // This happens when the usemap id is not present anywhere in the document
       
   504       if (areaBoxArray != NULL)
       
   505         {
       
   506         // find the index of the  node vector
       
   507         elementSize = NW_ADT_Vector_GetSize(areaBoxArray);
       
   508     
       
   509         for (arrayIndex = 0; arrayIndex < elementSize; arrayIndex++) 
       
   510           {
       
   511           areaBox = *(NW_LMgr_AreaBox_t**)NW_ADT_Vector_ElementAt (areaBoxArray, arrayIndex);
       
   512  
       
   513           if( NW_LMgr_Box_HasFocus( NW_LMgr_BoxOf( areaBox ) ) ) 
       
   514             {
       
   515             // draw the border around the area box
       
   516             status = NW_LMgr_Box_DrawBorder (NW_LMgr_AreaBox_GetBounds(NW_LMgr_BoxOf(areaBox)), 
       
   517                                              deviceContext, 
       
   518                                              &borderWidth, 
       
   519                                              &borderStyle, 
       
   520                                              &borderColor);
       
   521 
       
   522             NW_THROW_ON_ERROR(status);
       
   523 
       
   524             // if the image map box is broken, then we will need to display the alt text
       
   525             // of the area boxes if alt text is provided
       
   526             if( appServices->browserAppApi.IsImageMapView() && (NW_LMgr_ImgContainerBox_ImageIsBroken(box))) 
       
   527               {
       
   528               status = NW_LMgr_AreaBox_DisplayAltText( areaBox, deviceContext );
       
   529               NW_THROW_ON_ERROR (status);
       
   530               }
       
   531 
       
   532             break;
       
   533             }
       
   534           }
       
   535         }
       
   536       }
       
   537     }
       
   538   NW_CATCH (status)
       
   539     {
       
   540     }
       
   541   NW_FINALLY
       
   542     {
       
   543     deviceContext->SetBackgroundColor( initialBgColor);
       
   544     return status;
       
   545     }
       
   546   NW_END_TRY
       
   547   }
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 // Function: NW_LMgr_ImageMapBox_Copy
       
   551 // Description: Will return a new box which is a clone of the image map box to be 
       
   552 //  used in the image map box view. The caller is responsible for deletion of the 
       
   553 //  new box
       
   554 // Returns: TBrowserStatusCode
       
   555 // -----------------------------------------------------------------------------
       
   556 //
       
   557 TBrowserStatusCode
       
   558 NW_LMgr_ImageMapBox_Copy(NW_LMgr_Box_t* aBox, 
       
   559                          NW_LMgr_Box_t** aNewBox)
       
   560   {
       
   561   NW_LMgr_ImageMapBox_t* oldImageMapBox = (NW_LMgr_ImageMapBox_t*)aBox;
       
   562   NW_LMgr_ImageMapBox_t* newImageMapBox = NULL;
       
   563   NW_ADT_Vector_Metric_t arrayIndex;
       
   564   NW_ADT_Vector_Metric_t elementSize;
       
   565   NW_LMgr_AreaBox_t* newAreaBox = NULL;
       
   566   NW_LMgr_AreaBox_t* oldAreaBox = NULL;
       
   567   NW_Image_Virtual_t* newVirtualImage = NULL;
       
   568   NW_HED_EventHandler_t* eventHandler = NULL;
       
   569   NW_Text_t* altText = NULL;
       
   570   NW_Text_t* url = NULL;
       
   571   NW_ADT_DynamicVector_t* areaList = NULL;
       
   572   NW_GDI_Rectangle_t bounds;
       
   573   NW_LMgr_SimplePropertyList_t* oldPropertyList = NULL;
       
   574   NW_LMgr_SimplePropertyList_t* newPropertyList = NULL;
       
   575   void** ptr = NULL;
       
   576 
       
   577   NW_ASSERT(oldImageMapBox);
       
   578 
       
   579   NW_TRY( status ) 
       
   580     {
       
   581     // copy the virtual image (each image map box needs it's own.)
       
   582     // it will be deleted in the destructor
       
   583     NW_Image_Virtual_t* virtualImage = (NW_Image_Virtual_t*)oldImageMapBox->super.super.virtualImage;
       
   584     newVirtualImage = NW_Image_Virtual_New( virtualImage->image );
       
   585     NW_THROW_OOM_ON_NULL( newVirtualImage, status );
       
   586 
       
   587     // copy the alt text
       
   588     // the alt text will be deleted in the destructor
       
   589     if (oldImageMapBox->super.super.altText)
       
   590       {
       
   591       altText = NW_Text_Copy(oldImageMapBox->super.super.altText, NW_TRUE);
       
   592       NW_THROW_OOM_ON_NULL( altText, status );
       
   593       }
       
   594 
       
   595     if (oldImageMapBox->iUrl)
       
   596       {
       
   597       url = NW_Text_Copy(oldImageMapBox->iUrl, NW_TRUE);
       
   598       NW_THROW_OOM_ON_NULL( url, status );
       
   599       }
       
   600 
       
   601     // copy the event handler
       
   602     eventHandler = NW_HED_EventHandler_New(NW_HED_EventHandlerOf(oldImageMapBox->eventHandler)->documentNode, NW_HED_EventHandlerOf(oldImageMapBox->eventHandler)->context );
       
   603     NW_THROW_OOM_ON_NULL( eventHandler, status );
       
   604 
       
   605     // the caller of this method is responsible for deleting the new image map box
       
   606     newImageMapBox = NW_LMgr_ImageMapBox_New(5, 
       
   607                                              (NW_Image_AbstractImage_t*)newVirtualImage, 
       
   608                                              altText,
       
   609                                              NW_LMgr_ImgContainerBox_ImageIsBroken((NW_LMgr_Box_t*)oldImageMapBox),
       
   610                                              NW_LMgr_EventHandlerOf(eventHandler),
       
   611                                              url);
       
   612     NW_THROW_OOM_ON_NULL( newImageMapBox, status );
       
   613 
       
   614     // now that the newImageMapBox has taken ownership of the image, alttext, and eventhandlers, set them to NULL
       
   615     newVirtualImage = NULL;
       
   616     altText = NULL;
       
   617     eventHandler = NULL;
       
   618     url = NULL;
       
   619 
       
   620     // create the new image map box's area list 
       
   621     areaList = (NW_ADT_DynamicVector_t*) NW_ADT_ResizableVector_New (sizeof(NW_LMgr_AreaBox_t), 10, 5 );
       
   622     NW_THROW_OOM_ON_NULL (areaList, status);
       
   623       
       
   624     // set the area list on the image map box
       
   625     NW_LMgr_ImageMapBox_SetAreaBoxList(newImageMapBox, areaList);
       
   626 
       
   627     // copy the old image map box's area array to the new image map box's area array
       
   628     NW_ADT_DynamicVector_t* oldAreaList = NW_LMgr_ImageMapBox_GetAreaBoxList(oldImageMapBox);
       
   629 
       
   630     if (oldAreaList != NULL)
       
   631       {
       
   632       // find the index of the  node vector
       
   633       elementSize = NW_ADT_Vector_GetSize(oldAreaList);
       
   634   
       
   635       for (arrayIndex = 0; arrayIndex < elementSize; arrayIndex++) 
       
   636         {
       
   637         oldAreaBox = *(NW_LMgr_AreaBox_t**)NW_ADT_Vector_ElementAt (oldAreaList, arrayIndex);
       
   638          
       
   639         status = NW_LMgr_AreaBox_Copy(oldAreaBox, &newAreaBox);
       
   640         NW_THROW_OOM_ON_NULL (newAreaBox, status);
       
   641 
       
   642         NW_LMgr_AreaBox_SetParentImageMapBox (newAreaBox, newImageMapBox);
       
   643         
       
   644         ptr = NW_ADT_DynamicVector_InsertAt (areaList, &newAreaBox, NW_ADT_Vector_AtEnd);
       
   645         NW_THROW_OOM_ON_NULL(ptr, status);
       
   646         }
       
   647       }
       
   648 
       
   649     // now that the area list has been set on the image map box, set the pointer to NULL
       
   650     areaList = NULL;
       
   651 
       
   652     // set the old image map box bounds as the bounds for the new image map box
       
   653     bounds = NW_LMgr_Box_GetFormatBounds(NW_LMgr_BoxOf(oldImageMapBox));
       
   654     NW_LMgr_Box_SetFormatBounds(NW_LMgr_BoxOf(newImageMapBox), bounds);
       
   655     
       
   656     // in order to have good picture quality once we are in image map mode, we need to delete
       
   657     // the bitmap that was associated with the image map box in small screen mode and redecode 
       
   658     // it.  This will create a new bitmap that will be better for the larger display
       
   659     // of course we only want to do this if we are not a broken image
       
   660     if (!NW_LMgr_ImgContainerBox_ImageIsBroken(aBox))
       
   661       {
       
   662       NW_Image_Epoc32Simple_t* image = NW_Image_Epoc32SimpleOf (virtualImage->image);
       
   663       
       
   664       // delete the image bitmap that was used in small screen mode
       
   665       if(( image->imageDecoding == NW_FALSE ) && (image->bitmap))
       
   666         {
       
   667         // delete the image bitmap
       
   668         CFbsBitmap* oldBitmap = CONST_CAST(CFbsBitmap*, (const CFbsBitmap*)image->bitmap);
       
   669         delete oldBitmap;
       
   670         image->bitmap = NULL;
       
   671         CFbsBitmap* oldMask = CONST_CAST(CFbsBitmap*, (const CFbsBitmap*)image->mask);
       
   672         delete oldMask;
       
   673         image->mask = NULL;
       
   674         image->srcHeight = 0;
       
   675         image->srcWidth = 0;
       
   676         }
       
   677       
       
   678       // force a decode on the image    
       
   679       (void)NW_Image_AbstractImage_ForceImageDecode( NW_Image_AbstractImageOf(virtualImage ));
       
   680       }
       
   681 
       
   682     // copy the old image map box property list to the new image map box property list
       
   683     oldPropertyList = (NW_LMgr_SimplePropertyList_t*)NW_LMgr_Box_PropListGet(NW_LMgr_BoxOf(oldImageMapBox));
       
   684     status = NW_LMgr_SimplePropertyList_CopyEntireList(oldPropertyList, &newPropertyList);
       
   685     NW_THROW_ON_ERROR (status);
       
   686 
       
   687     // Delete the default property list that was allocated when newImageMapBox was created,
       
   688     // otherwise we leak
       
   689     NW_Object_Delete( (NW_LMgr_SimplePropertyList_t*)NW_LMgr_Box_PropListGet(NW_LMgr_BoxOf(newImageMapBox)) );
       
   690 
       
   691     // set the property list on the new image map box
       
   692     status = NW_LMgr_Box_SetPropList(NW_LMgr_BoxOf(newImageMapBox), (NW_LMgr_PropertyList_t*)newPropertyList);
       
   693     NW_THROW_ON_ERROR (status);
       
   694 
       
   695     *aNewBox = (NW_LMgr_Box_t*)newImageMapBox;
       
   696     }
       
   697   NW_CATCH( status ) 
       
   698     {
       
   699     if (newVirtualImage)
       
   700       {
       
   701       NW_Object_Delete(newVirtualImage);
       
   702       }
       
   703 
       
   704     if (altText)
       
   705       {
       
   706       NW_Object_Delete(altText);
       
   707       }
       
   708 
       
   709     if (url)
       
   710       {
       
   711       NW_Object_Delete(url);
       
   712       }
       
   713 
       
   714     if (eventHandler)
       
   715       {
       
   716       NW_Object_Delete(eventHandler);
       
   717       }
       
   718 
       
   719     if (newImageMapBox)
       
   720       {
       
   721       NW_Object_Delete(newImageMapBox);
       
   722       }
       
   723 
       
   724     if (areaList)
       
   725       {
       
   726       NW_Object_Delete(areaList);
       
   727       }
       
   728 
       
   729     if (newPropertyList)
       
   730       {
       
   731       NW_Object_Delete(newPropertyList);
       
   732       }
       
   733     } 
       
   734   NW_FINALLY 
       
   735     {
       
   736     return status;  
       
   737     } 
       
   738   NW_END_TRY
       
   739   }