Back to index

lightning-sunbird  0.9+nobinonly
nsResizerFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Original Author: Eric J. Burley (ericb@neoplanet.com)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsCOMPtr.h"
00040 #include "nsResizerFrame.h"
00041 #include "nsIContent.h"
00042 #include "nsIDocument.h"
00043 #include "nsIDOMXULDocument.h"
00044 #include "nsIDOMNodeList.h"
00045 #include "nsHTMLAtoms.h"
00046 #include "nsINameSpaceManager.h"
00047 
00048 #include "nsIWidget.h"
00049 #include "nsPresContext.h"
00050 #include "nsIDocShell.h"
00051 #include "nsIDocShellTreeItem.h"
00052 #include "nsIDocShellTreeOwner.h"
00053 #include "nsIBaseWindow.h"
00054 #include "nsIScriptGlobalObject.h"
00055 #include "nsIViewManager.h"
00056 #include "nsXULAtoms.h"
00057 #include "nsGUIEvent.h"
00058 
00059 //
00060 // NS_NewXULButtonFrame
00061 //
00062 // Creates a new Button frame and returns it in |aNewFrame|
00063 //
00064 nsresult
00065 NS_NewResizerFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
00066 {
00067   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00068   if (nsnull == aNewFrame) {
00069     return NS_ERROR_NULL_POINTER;
00070   }
00071   nsTitleBarFrame* it = new (aPresShell) nsResizerFrame(aPresShell);
00072   if (nsnull == it)
00073     return NS_ERROR_OUT_OF_MEMORY;
00074 
00075   // it->SetFlags(aFlags);
00076   *aNewFrame = it;
00077   return NS_OK;
00078   
00079 } // NS_NewTitleBarFrame
00080 
00081 nsResizerFrame::nsResizerFrame(nsIPresShell* aPresShell)
00082 :nsTitleBarFrame(aPresShell) 
00083 {
00084        mDirection = topleft; // by default...
00085 }
00086 
00087 NS_IMETHODIMP  nsResizerFrame::Init(nsPresContext*  aPresContext,
00088                 nsIContent*      aContent,
00089                 nsIFrame*        aParent,
00090                 nsStyleContext*  aContext,
00091                 nsIFrame*        asPrevInFlow)
00092 {
00093        nsresult rv = nsTitleBarFrame::Init(aPresContext, aContent, aParent, aContext, asPrevInFlow);
00094 
00095        GetInitialDirection(mDirection);
00096 
00097        return rv;
00098 }
00099 
00100 
00101 NS_IMETHODIMP
00102 nsResizerFrame::HandleEvent(nsPresContext* aPresContext, 
00103                             nsGUIEvent* aEvent,
00104                             nsEventStatus* aEventStatus)
00105 {
00106   PRBool doDefault = PR_TRUE;
00107 
00108   switch (aEvent->message) {
00109 
00110         case NS_MOUSE_LEFT_BUTTON_DOWN:   {
00111                       
00112                       // we're tracking.
00113                       mTrackingMouseMove = PR_TRUE;
00114                       
00115                       // start capture.           
00116                       aEvent->widget->CaptureMouse(PR_TRUE);
00117                       CaptureMouseEvents(aPresContext,PR_TRUE);
00118 
00119 
00120                       
00121                       // remember current mouse coordinates.
00122                       mLastPoint = aEvent->refPoint;
00123                       aEvent->widget->GetScreenBounds(mWidgetRect);
00124 
00125                       *aEventStatus = nsEventStatus_eConsumeNoDefault;
00126                       doDefault = PR_FALSE;
00127                }
00128                break;
00129                
00130 
00131         case NS_MOUSE_LEFT_BUTTON_UP: {
00132 
00133                       if(mTrackingMouseMove)
00134                       {
00135                              // we're done tracking.
00136                              mTrackingMouseMove = PR_FALSE;
00137                              
00138                              // end capture
00139                              aEvent->widget->CaptureMouse(PR_FALSE);                        
00140                              CaptureMouseEvents(aPresContext,PR_FALSE);
00141 
00142                              *aEventStatus = nsEventStatus_eConsumeNoDefault;
00143                              doDefault = PR_FALSE;
00144                       }
00145                }
00146                break;
00147 
00148         case NS_MOUSE_MOVE: {
00149                       if(mTrackingMouseMove)
00150                       {                                                       
00151                         // get the document and the global script object - should this be cached?
00152                         nsIScriptGlobalObject *scriptGlobalObject =
00153            aPresContext->PresShell()->GetDocument()->GetScriptGlobalObject();
00154          NS_ENSURE_TRUE(scriptGlobalObject, NS_ERROR_FAILURE);
00155 
00156          nsCOMPtr<nsIDocShellTreeItem> docShellAsItem =
00157            do_QueryInterface(scriptGlobalObject->GetDocShell());
00158          NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
00159 
00160          nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
00161          docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
00162 
00163          nsCOMPtr<nsIBaseWindow> window(do_QueryInterface(treeOwner));
00164 
00165          if (!window) {
00166            return NS_OK;
00167          }
00168 
00169                              nsPoint nsMoveBy(0,0),nsSizeBy(0,0);
00170                              nsPoint nsMouseMove(aEvent->refPoint - mLastPoint);
00171                                                          
00172 
00173                              switch(mDirection)
00174                              {
00175                                           case topleft:
00176                                                  nsMoveBy = nsMouseMove;
00177                                                  nsSizeBy -= nsMouseMove;
00178                                                  break;
00179                                           case top:
00180                                                  nsMoveBy.y = nsMouseMove.y;
00181                                                  nsSizeBy.y = - nsMouseMove.y;
00182                                                  break;
00183                                           case topright:
00184                                                  nsMoveBy.y = nsMouseMove.y;
00185                                                  nsSizeBy.x = nsMouseMove.x;
00186                                                  mLastPoint.x += nsMouseMove.x;
00187                                                  nsSizeBy.y = -nsMouseMove.y;
00188                                                  break;
00189                                           case left:
00190                                                  nsMoveBy.x = nsMouseMove.x;
00191                                                  nsSizeBy.x = -nsMouseMove.x;
00192                                                  break;                                    
00193                                           case right:
00194                                                  nsSizeBy.x = nsMouseMove.x;                                           
00195                                                  mLastPoint.x += nsMouseMove.x;
00196                                                  break;
00197                                           case bottomleft:
00198                                                  nsMoveBy.x = nsMouseMove.x;
00199                                                  nsSizeBy.y = nsMouseMove.y;
00200                                                  nsSizeBy.x = -nsMouseMove.x;
00201                                                  mLastPoint.y += nsMouseMove.y;                                               
00202                                                  break;
00203                                           case bottom:                                                                                      
00204                                                  nsSizeBy.y = nsMouseMove.y;                                           
00205                                                  mLastPoint.y += nsMouseMove.y;
00206                                                  break;
00207                                           case bottomright:                                              
00208                                                  nsSizeBy = nsMouseMove;            
00209                                                  mLastPoint += nsMouseMove;                                            
00210                                                  break;
00211                              }
00212 
00213 
00214 
00215                              PRInt32 x,y,cx,cy;
00216                              window->GetPositionAndSize(&x,&y,&cx,&cy);
00217 
00218                              x+=nsMoveBy.x;
00219                              y+=nsMoveBy.y;
00220                              cx+=nsSizeBy.x;
00221                              cy+=nsSizeBy.y;
00222 
00223                              window->SetPositionAndSize(x,y,cx,cy,PR_TRUE); // do the repaint.
00224 
00225                              /*
00226                              if(nsSizeBy.x || nsSizeBy.y)
00227                              {
00228                                    window->ResizeBy(nsSizeBy.x,nsSizeBy.y);
00229                              }
00230 
00231                              if(nsMoveBy.x || nsMoveBy.y)
00232                              {
00233                                    window->MoveBy(nsMoveBy.x,nsMoveBy.y);
00234                              }     */
00235                              
00236                              
00237                              
00238                              *aEventStatus = nsEventStatus_eConsumeNoDefault;                            
00239                              
00240                              doDefault = PR_FALSE;
00241                       }
00242                }
00243                break;
00244 
00245 
00246 
00247     case NS_MOUSE_LEFT_CLICK:
00248       MouseClicked(aPresContext, aEvent);
00249       break;
00250   }
00251   
00252   if ( doDefault )  
00253          return nsTitleBarFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
00254   else
00255          return NS_OK;
00256 }
00257 
00258 
00259 
00260 /* returns true if aText represented a valid direction 
00261  */
00262 PRBool 
00263 nsResizerFrame::EvalDirection(nsAutoString& aText,eDirection& aDir)
00264 {
00265        PRBool aResult = PR_TRUE;
00266        
00267        if( aText.Equals( NS_LITERAL_STRING("topleft") ) )
00268        {
00269               aDir = topleft;
00270        }
00271        else if( aText.Equals( NS_LITERAL_STRING("top") ) )
00272        {
00273               aDir = top;
00274        }
00275        else if( aText.Equals( NS_LITERAL_STRING("topright") ) )
00276        {
00277               aDir = topright;
00278        }
00279        else if( aText.Equals( NS_LITERAL_STRING("left") ) )
00280        {
00281               aDir = left;
00282        }      
00283        else if( aText.Equals( NS_LITERAL_STRING("right") ) )
00284        {
00285               aDir = right;
00286        }
00287        else if( aText.Equals( NS_LITERAL_STRING("bottomleft") ) )
00288        {
00289               aDir = bottomleft;
00290        }
00291        else if( aText.Equals( NS_LITERAL_STRING("bottom") ) )
00292        {
00293               aDir = bottom;
00294        }
00295        else if( aText.Equals( NS_LITERAL_STRING("bottomright") ) )
00296        {
00297               aDir = bottomright;
00298        }
00299        else
00300        {
00301               aResult = PR_FALSE;
00302        }
00303        
00304        return aResult;
00305 }
00306 
00307 
00308 /* Returns true if it was set.
00309  */
00310 PRBool
00311 nsResizerFrame::GetInitialDirection(eDirection& aDirection)
00312 {
00313  // see what kind of resizer we are.
00314   nsAutoString value;
00315 
00316   nsCOMPtr<nsIContent> content;
00317   GetContentOf(getter_AddRefs(content));
00318 
00319   if (!content)
00320      return PR_FALSE;
00321 
00322   if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None, nsXULAtoms::dir, value))
00323   {
00324           return EvalDirection(value,aDirection); 
00325   }  
00326 
00327   return PR_FALSE;
00328 }
00329 
00330 
00331 NS_IMETHODIMP
00332 nsResizerFrame::AttributeChanged(nsIContent* aChild,
00333                                  PRInt32 aNameSpaceID,
00334                                  nsIAtom* aAttribute,
00335                                  PRInt32 aModType)
00336 {
00337     nsresult rv = nsTitleBarFrame::AttributeChanged(aChild, aNameSpaceID,
00338                                                     aAttribute, aModType);
00339 
00340     if (aAttribute == nsXULAtoms::dir ) 
00341         {
00342         
00343         GetInitialDirection(mDirection);
00344     }
00345   
00346   return rv;
00347 }
00348 
00349 
00350 
00351 void 
00352 nsResizerFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent) 
00353 {
00354   // Execute the oncommand event handler.
00355   nsEventStatus status = nsEventStatus_eIgnore;
00356 
00357   nsXULCommandEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE,
00358                           NS_XUL_COMMAND, nsnull);
00359 
00360   mContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT,
00361                            &status);
00362 }