home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CHTMLClickRecord.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  8.7 KB  |  316 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. // CHTMLClickRecord.cp
  20.  
  21. #include "CHTMLClickRecord.h"
  22. #include "CNSContext.h"
  23. #include "CContextMenuAttachment.h"
  24. #include "CApplicationEventAttachment.h"
  25.  
  26. #include "layers.h"
  27. #include "mimages.h"
  28. #include "proto.h"
  29.  
  30. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  31. //    Ñ    
  32. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  33.  
  34. CHTMLClickRecord::CHTMLClickRecord(
  35.     Point                 inLocalWhere,
  36.     const SPoint32&        inImageWhere,
  37.     CNSContext*         inContext,
  38.     LO_Element*         inElementelement,
  39.     CL_Layer*             inLayer)
  40. {
  41.     mLocalWhere = inLocalWhere;
  42.     mImageWhere = inImageWhere;
  43.     mElement = inElementelement;
  44.     mAnchorData= NULL;
  45.     mContext = inContext;
  46.     mLayer = inLayer;
  47.     mClickKind = eWaiting;
  48. }
  49.  
  50. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  51. //    Ñ    
  52. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  53. // Figures out everything (anchors, click kind) about the current cursor position
  54. // called only once -- this is completely horrible
  55.  
  56. void CHTMLClickRecord::Recalc(void)
  57. {
  58.     if (mElement == NULL)
  59.         {
  60.         mClickKind = eNone;
  61.         return;
  62.         }
  63.  
  64.     switch (mElement->type)
  65.         {
  66.         case LO_IMAGE:
  67.             mClickKind = CalcImageClick();
  68.             break;
  69.             
  70.         case LO_TEXT:
  71.             mClickKind = CalcTextClick();
  72.             break;
  73.             
  74.         case LO_EDGE:
  75.             mClickKind = CalcEdgeClick();
  76.             break;
  77.             
  78.         default:
  79.             mClickKind = eNone;
  80.             break;
  81.         }
  82. }
  83.  
  84. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  85. //    Ñ    
  86. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  87.  
  88. EClickKind CHTMLClickRecord::CalcImageClick(void)
  89. {
  90.     EClickKind    theKind;
  91. //    SPoint32    localWhere;
  92.     
  93.     // Get the image URL
  94.     PA_LOCK(mImageURL, char *, (char*)mElement->lo_image.image_url);
  95.     PA_UNLOCK(loImage->image_url);
  96.     
  97.     // Where was the click?
  98. /*
  99.     localWhere.h = mLocalWhere.h;
  100.     localWhere.v = mLocalWhere.v;
  101. */
  102.     // find with layer coordinates (mImageWhere) not local coordinates
  103.     theKind = FindImagePart ( *mContext, &mElement->lo_image, &mImageWhere,
  104.         &mClickURL, &mWindowTarget, mAnchorData );
  105.             
  106.     return theKind;
  107. }
  108.  
  109. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  110. //    Ñ    
  111. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  112.  
  113. EClickKind CHTMLClickRecord::CalcTextClick(void)
  114. {
  115.     EClickKind theKind = eNone;
  116.     if (mElement->lo_text.anchor_href)
  117.         {
  118.         theKind = eTextAnchor;
  119.         PA_LOCK(mClickURL, char*, (char*)mElement->lo_text.anchor_href->anchor);
  120.         PA_UNLOCK(mElement->lo_text.anchor_href->anchor);
  121.  
  122.         PA_LOCK(mWindowTarget, char *,(char*)mElement->lo_text.anchor_href->target);
  123.         PA_UNLOCK(mElement->lo_text.anchor_href->target);
  124.         }
  125.  
  126.     return theKind;
  127. }
  128.  
  129. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  130. //    Ñ    
  131. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  132.  
  133. EClickKind CHTMLClickRecord::CalcEdgeClick(void)
  134. {
  135.     EClickKind theKind = eNone;
  136.     if (mElement->lo_edge.movable)
  137.         {
  138.         theKind = eEdge;
  139.         mIsVerticalEdge = mElement->lo_edge.is_vertical;
  140.         mEdgeLowerBound = mElement->lo_edge.left_top_bound;
  141.         mEdgeUpperBound = mElement->lo_edge.right_bottom_bound;
  142.         }
  143.  
  144.     return theKind;
  145. }
  146.  
  147. Boolean CHTMLClickRecord::IsClickOnAnchor(void) const
  148. {
  149.     return ((mClickKind != eNone) && (mClickKind != eEdge));
  150. }
  151.  
  152. Boolean    CHTMLClickRecord::IsClickOnEdge(void) const
  153. {
  154.     return (mClickKind == eEdge);
  155. }
  156.  
  157. #if 0
  158.  
  159. void CClickRecord::ResetNamedWindow()
  160. {
  161.     fWindowTarget = "";
  162. }
  163.  
  164. #endif
  165.  
  166.  
  167.  
  168. //    Pixels hang below their points, and thus the pixels equal to
  169. //    the top/left points are inside, but equal to the bottom/right
  170. //    of the bounding box are outside.
  171.  
  172. Boolean CHTMLClickRecord::PixelReallyInElement(
  173.     const SPoint32&         inImagePoint,
  174.     LO_Element*             inElement)
  175. {
  176.     // account for image border
  177.     Int32 borderWidth = 0;
  178.     
  179.     if (inElement->type == LO_IMAGE)
  180.         borderWidth = inElement->lo_image.border_width;
  181.     
  182.     Int32 realX = inElement->lo_any.x + inElement->lo_any.x_offset;
  183.     Int32 realY = inElement->lo_any.y + inElement->lo_any.y_offset;
  184.     return 
  185.         realY <= inImagePoint.v
  186.         && inImagePoint.v < (realY + inElement->lo_any.height + (2 * borderWidth))
  187.         && realX <= inImagePoint.h
  188.         && inImagePoint.h < (realX + inElement->lo_any.width + (2 * borderWidth));
  189. }
  190.  
  191. //-----------------------------------
  192. CHTMLClickRecord::EClickState CHTMLClickRecord::WaitForMouseAction(
  193.     const SMouseDownEvent&        inMouseDown,
  194.     LAttachable*                inAttachable,
  195.     Int32                        inDelay,
  196.     Boolean                        inExecuteContextMenuAttachment)
  197. //-----------------------------------
  198. {
  199.     // Ñ The new way. Give a context menu attachment a chance to
  200.     // execute.  If this returns true ("execute host"), there is no attachment,
  201.     // so do things the old way.  If it returns false, assume the popup has been
  202.     // handled. This can go away if the browser folkies decide to use
  203.     // the attachment mechanism.
  204.     
  205.     CContextMenuAttachment::SExecuteParams params;
  206.     params.inMouseDown = &inMouseDown;
  207.     params.outResult = (CContextMenuAttachment::EClickState)eUndefined;
  208.     if (inExecuteContextMenuAttachment)
  209.     {
  210.          inAttachable->ExecuteAttachments(
  211.             CContextMenuAttachment::msg_ContextMenu,
  212.             (void*)¶ms);
  213.     }
  214.     if (params.outResult != eUndefined)
  215.         return (EClickState)params.outResult;
  216.  
  217.     // Ñ The old way.
  218.      return WaitForMouseAction(
  219.                  inMouseDown.whereLocal,
  220.                  inMouseDown.macEvent.when,
  221.                  inDelay);
  222. } // CHTMLClickRecord::WaitForMouseAction
  223.  
  224. //-----------------------------------
  225. CHTMLClickRecord::EClickState CHTMLClickRecord::WaitForMouseAction(
  226.     const Point&     inInitialPoint,
  227.     Int32            inWhen,
  228.     Int32            inDelay)
  229. //-----------------------------------
  230. {
  231.     if (CApplicationEventAttachment::CurrentEventHasModifiers(controlKey))
  232.     {
  233.         return eMouseTimeout;
  234.     }
  235.     
  236.     //    Spin on mouse down and wait for either the user to start
  237.     //    dragging or for the popup delay to expire or for mouse up
  238.     //    (in which case we just fall through)
  239.     while (::StillDown())
  240.         {
  241.         Point theCurrentPoint;
  242.         ::GetMouse(&theCurrentPoint);
  243.         
  244.         if ((abs(theCurrentPoint.h - inInitialPoint.h) >= eMouseHystersis) ||
  245.             (abs(theCurrentPoint.v - inInitialPoint.v) >= eMouseHystersis))
  246.             return eMouseDragging;
  247.  
  248.         Int32 now = ::TickCount();
  249.  
  250.         if (abs( now - inWhen ) > inDelay)
  251.             return eMouseTimeout;
  252.         }
  253.     
  254.     return eMouseUpEarly;
  255. } // CHTMLClickRecord::WaitForMouseAction
  256.  
  257. //-----------------------------------
  258. void CHTMLClickRecord::CalculatePosition()
  259. // Snarfed from mclick.cp
  260. // Figures out everything (anchors, click kind) about the current cursor position
  261. // called only once -- this is completely horrible
  262. //-----------------------------------
  263. {
  264.     if ( mClickKind != eWaiting )
  265.         return;
  266.     
  267.     if ( !mElement )
  268.     {
  269.         mClickKind = eNone;
  270.         return;
  271.     }
  272.  
  273.     if ( mElement->type == LO_IMAGE )
  274.     {
  275.         // Ñ click in the image. Complicated case:
  276.         mClickKind = FindImagePart(*mContext, &mElement->lo_image, &mImageWhere, &mImageURL, &mWindowTarget, mAnchorData);
  277.     }
  278.     else if ( mElement->type == LO_TEXT && mElement->lo_text.anchor_href )
  279.     {
  280.         if ( mElement->lo_text.anchor_href )
  281.         {
  282.             mClickKind = eTextAnchor;
  283.             PA_LOCK( mClickURL, char*, (char*)mElement->lo_text.anchor_href->anchor );
  284.             PA_UNLOCK( mElement->lo_text.anchor_href->anchor );
  285.             PA_LOCK( mWindowTarget, char *,(char*)mElement->lo_text.anchor_href->target );
  286.             PA_UNLOCK( mElement->lo_text.anchor_href->target );
  287.         }
  288.         else
  289.             mClickKind = eNone;
  290.     }
  291.     else if ( mElement->type == LO_EDGE && mElement->lo_edge.movable )
  292.     {
  293.         mClickKind = eEdge;
  294.         mIsVerticalEdge = mElement->lo_edge.is_vertical;
  295.         mEdgeLowerBound = mElement->lo_edge.left_top_bound;
  296.         mEdgeUpperBound = mElement->lo_edge.right_bottom_bound;
  297.     }
  298.     else
  299.         mClickKind = eNone;
  300. }
  301.  
  302.  
  303. Boolean CHTMLClickRecord::IsAnchor()
  304. {
  305.     CalculatePosition();
  306.     return ((mClickKind != eNone) && (mClickKind != eEdge));
  307. }
  308.  
  309. Boolean CHTMLClickRecord::IsEdge()
  310. {
  311.     CalculatePosition();
  312.     return (mClickKind == eEdge);
  313. }
  314.  
  315.  
  316.