Back to index

lightning-sunbird  0.9+nobinonly
nsImageControlFrame.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.org 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  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include "nsCOMPtr.h"
00038 #include "nsIImageControlFrame.h"
00039 #include "nsImageFrame.h"
00040 #include "nsFormControlHelper.h"
00041 #include "nsIFormControlFrame.h"
00042 #include "nsIFormControl.h"
00043 #include "nsHTMLParts.h"
00044 #include "nsIRenderingContext.h"
00045 #include "nsPresContext.h"
00046 #include "nsIPresShell.h"
00047 #include "nsStyleContext.h"
00048 #include "nsLeafFrame.h"
00049 #include "nsCSSRendering.h"
00050 #include "nsISupports.h"
00051 #include "nsHTMLAtoms.h"
00052 #include "nsIDeviceContext.h"
00053 #include "nsIFontMetrics.h"
00054 #include "nsIImage.h"
00055 #include "nsStyleConsts.h"
00056 #include "nsFormControlFrame.h"
00057 #include "nsGUIEvent.h"
00058 #include "nsLayoutAtoms.h"
00059 #include "nsIServiceManager.h"
00060 #include "nsContainerFrame.h"
00061 #ifdef ACCESSIBILITY
00062 #include "nsIAccessibilityService.h"
00063 #endif
00064 
00065 #define nsImageControlFrameSuper nsImageFrame
00066 class nsImageControlFrame : public nsImageControlFrameSuper,
00067                             public nsIFormControlFrame,
00068                             public nsIImageControlFrame
00069 {
00070 public:
00071   nsImageControlFrame();
00072   ~nsImageControlFrame();
00073 
00074   NS_IMETHOD Destroy(nsPresContext *aPresContext);
00075   NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
00076 
00077   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
00078                     nsHTMLReflowMetrics&     aDesiredSize,
00079                     const nsHTMLReflowState& aReflowState,
00080                     nsReflowStatus&          aStatus);
00081 
00082   NS_IMETHOD HandleEvent(nsPresContext* aPresContext, 
00083                          nsGUIEvent* aEvent,
00084                          nsEventStatus* aEventStatus);
00085 
00086   virtual nsIAtom* GetType() const;
00087 
00088 #ifdef ACCESSIBILITY
00089   NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
00090 #endif
00091 
00092 #ifdef DEBUG
00093   NS_IMETHOD GetFrameName(nsAString& aResult) const {
00094     return MakeFrameName(NS_LITERAL_STRING("ImageControl"), aResult);
00095   }
00096 #endif
00097 
00098   NS_IMETHOD GetCursor(const nsPoint&    aPoint,
00099                        nsIFrame::Cursor& aCursor);
00100 
00101   NS_IMETHOD_(PRInt32) GetFormControlType() const;
00102 
00103   NS_IMETHOD GetName(nsAString* aName);
00104 
00105   void SetFocus(PRBool aOn, PRBool aRepaint);
00106   void ScrollIntoView(nsPresContext* aPresContext);
00107 
00108   NS_IMETHOD GetFormContent(nsIContent*& aContent) const;
00109   virtual nscoord GetVerticalInsidePadding(nsPresContext* aPresContext,
00110                                            float aPixToTwip,
00111                                            nscoord aInnerHeight) const;
00112   virtual nscoord GetHorizontalInsidePadding(nsPresContext* aPresContext,
00113                                              float aPixToTwip, 
00114                                              nscoord aInnerWidth,
00115                                              nscoord aCharWidth) const;
00116 
00117 
00118         // nsIFormControlFrame
00119   NS_IMETHOD SetProperty(nsPresContext* aPresContext, nsIAtom* aName, const nsAString& aValue);
00120   NS_IMETHOD GetProperty(nsIAtom* aName, nsAString& aValue); 
00121   NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
00122   NS_IMETHOD OnContentReset();
00123 
00124   // nsIImageControlFrame
00125   NS_IMETHOD GetClickedX(PRInt32* aX);
00126   NS_IMETHOD GetClickedY(PRInt32* aY);
00127 
00128 protected:
00129   NS_IMETHOD_(nsrefcnt) AddRef(void);
00130   NS_IMETHOD_(nsrefcnt) Release(void);
00131 
00132   nsPoint mLastClickPoint; 
00133 };
00134 
00135 
00136 nsImageControlFrame::nsImageControlFrame()
00137 {
00138   mLastClickPoint = nsPoint(0,0);
00139 }
00140 
00141 nsImageControlFrame::~nsImageControlFrame()
00142 {
00143 }
00144 
00145 NS_IMETHODIMP
00146 nsImageControlFrame::Destroy(nsPresContext *aPresContext)
00147 {
00148   nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
00149 
00150   return nsImageControlFrameSuper::Destroy(aPresContext);
00151 }
00152 
00153 nsresult
00154 NS_NewImageControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
00155 {
00156   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00157   if (nsnull == aNewFrame) {
00158     return NS_ERROR_NULL_POINTER;
00159   }
00160   nsImageControlFrame* it = new (aPresShell) nsImageControlFrame;
00161   if (!it) {
00162     return NS_ERROR_OUT_OF_MEMORY;
00163   }
00164   *aNewFrame = it;
00165   return NS_OK;
00166 }
00167 
00168 // Frames are not refcounted, no need to AddRef
00169 NS_IMETHODIMP
00170 nsImageControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
00171 {
00172   NS_PRECONDITION(0 != aInstancePtr, "null ptr");
00173   if (NULL == aInstancePtr) {
00174     return NS_ERROR_NULL_POINTER;
00175   }
00176   if (aIID.Equals(NS_GET_IID(nsIFormControlFrame))) {
00177     *aInstancePtr = (void*) ((nsIFormControlFrame*) this);
00178     return NS_OK;
00179   } 
00180   if (aIID.Equals(NS_GET_IID(nsIImageControlFrame))) {
00181     *aInstancePtr = (void*) ((nsIImageControlFrame*) this);
00182     return NS_OK;
00183   }
00184 
00185   return nsImageControlFrameSuper::QueryInterface(aIID, aInstancePtr);
00186 }
00187 
00188 #ifdef ACCESSIBILITY
00189 NS_IMETHODIMP nsImageControlFrame::GetAccessible(nsIAccessible** aAccessible)
00190 {
00191   nsCOMPtr<nsIAccessibilityService> accService = do_GetService("@mozilla.org/accessibilityService;1");
00192 
00193   if (accService) {
00194     if (mContent->Tag() == nsHTMLAtoms::button) {
00195       return accService->CreateHTML4ButtonAccessible(NS_STATIC_CAST(nsIFrame*, this), aAccessible);
00196     }
00197     else if (mContent->Tag() == nsHTMLAtoms::input) {
00198       return accService->CreateHTMLButtonAccessible(NS_STATIC_CAST(nsIFrame*, this), aAccessible);
00199     }
00200   }
00201 
00202   return NS_ERROR_FAILURE;
00203 }
00204 #endif
00205 
00206 nsrefcnt nsImageControlFrame::AddRef(void)
00207 {
00208   NS_WARNING("not supported");
00209   return 1;
00210 }
00211 
00212 nsrefcnt nsImageControlFrame::Release(void)
00213 {
00214   NS_WARNING("not supported");
00215   return 1;
00216 }
00217 
00218 nsIAtom*
00219 nsImageControlFrame::GetType() const
00220 {
00221   return nsLayoutAtoms::imageControlFrame; 
00222 }
00223 
00224 NS_METHOD
00225 nsImageControlFrame::Reflow(nsPresContext*         aPresContext,
00226                            nsHTMLReflowMetrics&     aDesiredSize,
00227                            const nsHTMLReflowState& aReflowState,
00228                            nsReflowStatus&          aStatus)
00229 {
00230   DO_GLOBAL_REFLOW_COUNT("nsImageControlFrame", aReflowState.reason);
00231   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
00232   if (aReflowState.reason == eReflowReason_Initial) {
00233     nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
00234   }
00235   return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
00236 }
00237 
00238 NS_METHOD 
00239 nsImageControlFrame::HandleEvent(nsPresContext* aPresContext, 
00240                                  nsGUIEvent* aEvent,
00241                                  nsEventStatus* aEventStatus)
00242 {
00243   NS_ENSURE_ARG_POINTER(aEventStatus);
00244 
00245   // Don't do anything if the event has already been handled by someone
00246   if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
00247     return NS_OK;
00248   }
00249 
00250   // do we have user-input style?
00251   const nsStyleUserInterface* uiStyle = GetStyleUserInterface();
00252   if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE || uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED)
00253     return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
00254 
00255   if (nsFormControlHelper::GetDisabled(mContent)) { // XXX cache disabled
00256     return NS_OK;
00257   }
00258 
00259   *aEventStatus = nsEventStatus_eIgnore;
00260 
00261   switch (aEvent->message) {
00262     case NS_MOUSE_LEFT_BUTTON_UP:
00263     {
00264       // Store click point for GetNamesValues
00265       // Do this on MouseUp because the specs don't say and that's what IE does
00266       TranslateEventCoords(aEvent->point, mLastClickPoint);
00267       break;
00268     }
00269   }
00270   return nsImageControlFrameSuper::HandleEvent(aPresContext, aEvent,
00271                                                aEventStatus);
00272 }
00273 
00274 void 
00275 nsImageControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
00276 {
00277 }
00278 
00279 void
00280 nsImageControlFrame::ScrollIntoView(nsPresContext* aPresContext)
00281 {
00282   if (aPresContext) {
00283     nsIPresShell *presShell = aPresContext->GetPresShell();
00284     if (presShell) {
00285       presShell->ScrollFrameIntoView(this,
00286                    NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
00287     }
00288   }
00289 }
00290 
00291 NS_IMETHODIMP_(PRInt32)
00292 nsImageControlFrame::GetFormControlType() const
00293 {
00294   return NS_FORM_INPUT_IMAGE;
00295 }
00296 
00297 NS_IMETHODIMP
00298 nsImageControlFrame::GetName(nsAString* aResult)
00299 {
00300   return nsFormControlHelper::GetName(mContent, aResult);
00301 }
00302 
00303 NS_IMETHODIMP
00304 nsImageControlFrame::GetCursor(const nsPoint&    aPoint,
00305                                nsIFrame::Cursor& aCursor)
00306 {
00307   // Use style defined cursor if one is provided, otherwise when
00308   // the cursor style is "auto" we use the pointer cursor.
00309   FillCursorInformationFromStyle(GetStyleUserInterface(), aCursor);
00310 
00311   if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
00312     aCursor.mCursor = NS_STYLE_CURSOR_POINTER;
00313   }
00314 
00315   return NS_OK;
00316 }
00317 
00318 NS_IMETHODIMP
00319 nsImageControlFrame::GetFormContent(nsIContent*& aContent) const
00320 {
00321   aContent = GetContent();
00322   NS_IF_ADDREF(aContent);
00323   return NS_OK;
00324 }
00325 
00326 nscoord 
00327 nsImageControlFrame::GetVerticalInsidePadding(nsPresContext* aPresContext,
00328                                               float aPixToTwip, 
00329                                               nscoord aInnerHeight) const
00330 {
00331    return 0;
00332 }
00333 
00334 nscoord 
00335 nsImageControlFrame::GetHorizontalInsidePadding(nsPresContext* aPresContext,
00336                                                float aPixToTwip, 
00337                                                nscoord aInnerWidth,
00338                                                nscoord aCharWidth) const
00339 {
00340   return 0;
00341 }
00342 
00343 NS_IMETHODIMP nsImageControlFrame::SetProperty(nsPresContext* aPresContext,
00344                                                nsIAtom* aName,
00345                                                const nsAString& aValue)
00346 {
00347   return NS_OK;
00348 }
00349 
00350 NS_IMETHODIMP nsImageControlFrame::GetProperty(nsIAtom* aName,
00351                                                nsAString& aValue)
00352 {
00353   aValue.Truncate();
00354   return NS_OK;
00355 }
00356 
00357 NS_IMETHODIMP nsImageControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
00358 {
00359 //  mSuggestedWidth = aWidth;
00360 //  mSuggestedHeight = aHeight;
00361   return NS_OK;
00362 }
00363 
00364 NS_IMETHODIMP
00365 nsImageControlFrame::OnContentReset()
00366 {
00367   return NS_OK;
00368 }
00369 
00370 NS_IMETHODIMP
00371 nsImageControlFrame::GetClickedX(PRInt32* aX)
00372 {
00373   *aX = mLastClickPoint.x;
00374   return NS_OK;
00375 }
00376 
00377 NS_IMETHODIMP
00378 nsImageControlFrame::GetClickedY(PRInt32* aY)
00379 {
00380   *aY = mLastClickPoint.y;
00381   return NS_OK;
00382 }