home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / fmbutton.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  12.1 KB  |  402 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. #include "stdafx.h"
  20. #include "fmbutton.h"
  21. #include "intl_csi.h"
  22. #include "odctrl.h"
  23.  
  24. //    This file is dedicated to form type button elements
  25. //        otherwise known as a button on windows and
  26. //        their implementation as requried by the XP layout
  27. //        library.
  28.  
  29. //    Construction simply clears all members.
  30. CFormButton::CFormButton()
  31. {
  32.     //    No widget yet.
  33.     m_pWidget = NULL;
  34. }
  35.  
  36. //    Destruction cleans out all members.
  37. CFormButton::~CFormButton()
  38. {
  39. }
  40.  
  41. //    How to set the LO form element.
  42. //    This may change during the lifetime of an instance, so use this
  43. //        to update all referencing values.
  44. void CFormButton::SetElement(LO_FormElementStruct *pFormElement)
  45. {
  46.     //    Call the base.
  47.     CFormElement::SetElement(pFormElement);
  48.  
  49.     //    Update the widget if present for correct callbacks.
  50.     if(m_pWidget)    {
  51.         m_pWidget->RegisterForm(GetElement());
  52.     }
  53. }
  54.  
  55. //    Set the owning context.
  56. //    Use this to determine what context we live in and how we should
  57. //        represent ourself (DC or window).
  58. void CFormButton::SetContext(CAbstractCX *pCX)
  59. {
  60.     //    Call the base.
  61.     CFormElement::SetContext(pCX);
  62.  
  63.     //    Update the widget if present for correct callbacks.
  64.     if(m_pWidget)    {
  65.         m_pWidget->RegisterContext(pCX->GetContext());
  66.     }
  67. }
  68.  
  69. //    Display the form element given the particular context we are in.
  70. //    Possibly only use a DC for representation, or have the
  71. //        window move.
  72. void CFormButton::DisplayFormElement(LTRB& Rect)
  73. {
  74.     //    Display only has meaning if our context is a device context.
  75.     if(GetContext() && GetContext()->IsDCContext())    {
  76.         //    Further, need to detect how we're going to be drawing ourselves.
  77.         if(GetContext()->IsPureDCContext())    {
  78.             //    Only works from a DC, needs a GDI drawing representation.
  79.             CDCCX *pDCCX = VOID2CX(GetContext(), CDCCX);
  80.             HDC pDC = pDCCX->GetContextDC();
  81.             if(pDC && Rect.Width() && Rect.Height()) {
  82.                 pDCCX->Display3DBox(Rect, pDCCX->ResolveDarkLineColor(), pDCCX->ResolveLightLineColor(), pDCCX->Pix2TwipsY(2));
  83.  
  84.                 //  Draw the text inside the button.
  85.                 //  This is refiguring the width and height of the text.
  86.                 char *pData = NULL;
  87.                 if(GetElementMinimalData())    {
  88.                     pData = (char *)GetElementMinimalData()->value;
  89.                 }
  90.                 if(pData)    {
  91.                     //  Decide text color.
  92.                     COLORREF rgbUseMe;
  93.                     CyaFont    *pMyFont;
  94.                     rgbUseMe = pDCCX->ResolveTextColor(NULL);
  95.  
  96.                     //  Output text.
  97.                     int iBkMode = ::SetBkMode(pDC, TRANSPARENT);
  98.                     COLORREF rgbTxtClr = ::SetTextColor(pDC, rgbUseMe);
  99.                     pDCCX->SelectNetscapeFont( pDC,  GetTextAttr(), pMyFont );
  100.                     if(pMyFont != NULL)    {
  101.                         SIZE csz;
  102.                         CIntlWin::GetTextExtentPointWithCyaFont(pMyFont, 
  103.                             INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(GetContext()->GetContext())),
  104.                             pDC, pData, XP_STRLEN(pData), &csz);
  105.                         // Center text.
  106.                         int32 lWidth = Rect.Width() - csz.cx;
  107.                         int32 lHeight = Rect.Height() -csz.cy;
  108.                         int32 lX = Rect.left + lWidth / 2;
  109.                         int32 lY = Rect.top + (lHeight / 2);
  110.                         CIntlWin::TextOutWithCyaFont(
  111.                             pMyFont,
  112.                             INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(GetContext()->GetContext())),
  113.                             pDC, 
  114.                             CASTINT(lX),
  115.                             CASTINT(lY),
  116.                             pData,
  117.                             XP_STRLEN(pData));
  118.  
  119.                             ::SetTextColor(pDC, rgbTxtClr);
  120.                             ::SetBkMode(pDC, iBkMode);
  121.                         pDCCX->ReleaseNetscapeFont( pDC, pMyFont );
  122.                     }
  123.                 }
  124.                 pDCCX->ReleaseContextDC(pDC);
  125.             }
  126.         }
  127.         else if(GetContext()->IsWindowContext() && GetRaw())    {
  128.             MoveWindow(GetRaw(), Rect.left, Rect.top);
  129.         }
  130.         else    {
  131.             //    Is undefined....
  132.             ASSERT(0);
  133.         }
  134.     }
  135.  
  136.     //    Call the base.
  137.     CFormElement::DisplayFormElement(Rect);
  138. }
  139.  
  140. //    Destroy the widget (window) implemenation of the form.
  141. void CFormButton::DestroyWidget()
  142. {
  143.     //    Free off the widget if present.
  144.     if(m_pWidget)    {
  145.         m_pWidget->DestroyWindow();
  146.         delete m_pWidget;
  147.         m_pWidget = NULL;
  148.     }
  149. }
  150.  
  151. //    Create the widget (window) implementation of the form
  152. //        but DO NOT DISPLAY.
  153. void CFormButton::CreateWidget()
  154. {
  155.     if(GetContext() && GetElement())    {
  156.         if(GetContext()->IsWindowContext() && VOID2CX(GetContext(), CPaneCX)->GetPane())    {
  157.             //    Widget representation, create one.
  158.             ASSERT(m_pWidget == NULL);
  159.             m_pWidget = new CODNetscapeButton(GetContext()->GetContext(), GetElement());
  160.             if(m_pWidget == NULL)    {
  161.                 return;
  162.             }
  163.             
  164.             //    Create the widget, initially with a bad size and hidden.
  165.             BOOL bCreate = m_pWidget->Create("",
  166.                 WS_CHILD | BS_OWNERDRAW,
  167.                 CRect(1, 1, 0, 0),
  168.                 CWnd::FromHandle(VOID2CX(GetContext(), CPaneCX)->GetPane()),
  169.                 GetDynamicControlID());
  170.             if(!bCreate)    {
  171.                 DestroyWidget();
  172.                 return;
  173.             }
  174.  
  175.             //    Set the font of the widget.
  176.             CyaFont    *pMyFont;
  177.             LO_TextAttr *text_attr = GetElement()->text_attr;
  178.             CDCCX *pDCCX = VOID2CX(GetContext(), CDCCX);
  179.  
  180.             //    Measure what the size of the button should be.
  181.             HDC hDC = NULL;
  182.             if(GetRaw()) {
  183.                 hDC = ::GetDC(GetRaw());
  184.             }
  185.             if(hDC)    {
  186.                 SIZE csz;
  187.                 int32 lWidgetWidth = 0;
  188.                 int32 lWidgetHeight = 0;
  189.                 pDCCX->SelectNetscapeFont( hDC, GetTextAttr(), pMyFont );
  190.                 if(pMyFont == NULL)    {
  191.                     ::ReleaseDC(GetRaw(), hDC);
  192.                     DestroyWidget();
  193.                     return;
  194.                 }
  195.                 else {
  196.  
  197.                     //    Must select the font while measuring.
  198.                     SetWidgetFont(hDC, GetRaw());
  199.                     text_attr->FE_Data = pMyFont;
  200.  
  201.                     CIntlWin::GetTextExtentPointWithCyaFont(pMyFont, 
  202.                         INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(GetContext()->GetContext())),
  203.                         hDC, "hi", 2, &csz);
  204.                     //    Determine what data will be shown.
  205.                     char *pCaption = NULL;
  206.                     if(GetElementMinimalData())    {
  207.                         pCaption = (char *)GetElementMinimalData()->value;
  208.                     }
  209.  
  210.                     //    Measure it if present.
  211.                     if(pCaption && *pCaption)    {
  212.                         CIntlWin::GetTextExtentPointWithCyaFont(pMyFont, 
  213.                             INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(GetContext()->GetContext())),
  214.                             hDC, pCaption, XP_STRLEN(pCaption), &csz);
  215.                     }
  216.  
  217.                     lWidgetWidth = 3 * csz.cx / 2;
  218.                     lWidgetHeight = 3 * csz.cy / 2;
  219.  
  220.                     if (GetElement()->width > lWidgetWidth) {
  221.                         lWidgetWidth = GetElement()->width;
  222.                     }
  223.                     if (GetElement()->height > lWidgetHeight) {
  224.                         lWidgetHeight = GetElement()->height;
  225.                     }
  226.                     //    Done measuring text.
  227.                     pDCCX->ReleaseNetscapeFont( hDC, pMyFont );
  228.  
  229.                     //    Finally, size the widget to the width and height
  230.                     //        we have figured here.
  231.                     ::MoveWindow(GetRaw(), 1, 1, CASTINT(lWidgetWidth), CASTINT(lWidgetHeight), FALSE);
  232.                 }
  233.                 ::ReleaseDC(GetRaw(), hDC);
  234.                 hDC = NULL;
  235.             }
  236.             else    {
  237.                 //    No DC, no widget.
  238.                 DestroyWidget();
  239.                 return;
  240.             }
  241.         }
  242.         else if(GetContext()->IsPureDCContext())    {
  243.             //    Printing representation.
  244.         }
  245.     }
  246. }
  247.  
  248. //    Copy the current data out of the layout struct into the form
  249. //        widget, or mark that you should represent using the current data.
  250. void CFormButton::UseCurrentData()
  251. {
  252.     //    Detect the context type for further action.
  253.     if(GetContext())    {
  254.         if(GetContext()->IsWindowContext())    {
  255.             if(m_pWidget)    {
  256.                 //    Just set it to the value if present.
  257.                 //    No real concept of current or default data in a button yet.
  258.                 char *pData = NULL;
  259.                 if(GetElementMinimalData())    {
  260.                     pData = (char *)GetElementMinimalData()->value;
  261.                 }
  262.                 if(pData && GetRaw())    {
  263.                     ::SetWindowText(GetRaw(), pData);
  264.                 }
  265.             }
  266.         }
  267.         else if(GetContext()->IsPureDCContext())    {
  268.             //    Do some printing specific stuff here...
  269.         }
  270.     }
  271. }
  272.  
  273. //    Copy the default data out of the layout struct into the form
  274. //        widget, or mark that you should represent using the default data.
  275. void CFormButton::UseDefaultData()
  276. {
  277.     //    Detect the context type for further action.
  278.     if(GetContext())    {
  279.         if(GetContext()->IsWindowContext())    {
  280.             if(m_pWidget)    {
  281.                 //    Just set it to the value if present.
  282.                 //    No real concept of current or default data in a button yet.
  283.                 char *pData = NULL;
  284.                 if(GetElementMinimalData())    {
  285.                     pData = (char *)GetElementMinimalData()->value;
  286.                 }
  287.                 if(pData && GetRaw())    {
  288.                     ::SetWindowText(GetRaw(), pData);
  289.                 }
  290.             }
  291.         }
  292.         else if(GetContext()->IsPureDCContext())    {
  293.             //    Do some printing specific stuff here...
  294.         }
  295.     }
  296. }
  297.  
  298. //    Fill in the layout size information in the layout struct regarding
  299. //        the dimensions of the widget.
  300. void CFormButton::FillSizeInfo()
  301. {
  302.     //    Detect the context type for further action.
  303.     if(GetContext() && GetElement())    {
  304.         if(GetContext()->IsWindowContext())    {
  305.             if(GetRaw())    {
  306.                 //    Determine our window position.
  307.                 CRect crWidget;
  308.                 ::GetWindowRect(GetRaw(), crWidget);
  309.  
  310.                 //    This is a recreation of csz.cy in CreateWidget.
  311.                 int32 csz_cy = 2 * crWidget.Height() / 3;
  312.  
  313.                 //    Munge return coordinates a little for
  314.                 //        layout.
  315.                 GetElement()->width = crWidget.Width();
  316.                 GetElement()->height = crWidget.Height();
  317.                 GetElement()->baseline = crWidget.Height() - csz_cy / 4 - 1;
  318.             }
  319.             else    {
  320.                 //    Widget not present, give layout nothing.
  321.                 GetElement()->width = 0;
  322.                 GetElement()->height = 0;
  323.                 GetElement()->baseline = 0;
  324.             }
  325.         }
  326.         else if(GetContext()->IsPureDCContext())    {
  327.             CDCCX *pCX = VOID2CX(GetContext(), CDCCX);
  328.             HDC pDC = pCX->GetAttribDC();
  329.  
  330.             //  Size the Button text.
  331.             int32 lWidth = 0;
  332.             int32 lHeight = 0;
  333.             int32 lBaseline = 0;
  334.             if(pDC) {
  335.                 char *pData = NULL;
  336.                 if(GetElementMinimalData())    {
  337.                     pData = (char *)GetElementMinimalData()->value;
  338.                 }
  339.                 if(pData && *pData)    {
  340.                     //  Size the text.
  341.                     CyaFont    *pMyFont;
  342.                     pCX->SelectNetscapeFont( pDC, GetTextAttr(), pMyFont );
  343.                     if (pMyFont) {
  344.                         SIZE csz;
  345.                         CIntlWin::GetTextExtentPointWithCyaFont(pMyFont, 
  346.                             INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(GetContext()->GetContext())),
  347.                             pDC, pData, XP_STRLEN(pData), &csz);
  348.  
  349.                         //  Give some extra room.
  350.                         //  We'll need to know how to undo this in the display routine.
  351.                         lWidth = 3 * csz.cx / 2;
  352.                         lHeight = 3 * csz.cy / 2;
  353.  
  354.                         // Check and see if we should use preset sizes
  355.                         if (GetElement()->width > lWidth) {
  356.                             lWidth = GetElement()->width;
  357.                         }
  358.                         if (GetElement()->height > lHeight) {
  359.                             lHeight = GetElement()->height;
  360.                         }
  361.  
  362.                         lBaseline = lHeight - csz.cy / 4 - pCX->Pix2TwipsY(1);
  363.                         pCX->ReleaseNetscapeFont( pDC, pMyFont );
  364.                     }
  365.                 }
  366.  
  367.                 //  Done with the DC.
  368.                 pCX->ReleaseContextDC(pDC);
  369.             }
  370.  
  371.             //  Fill in the layout information.
  372.             GetElement()->width = lWidth;
  373.             GetElement()->height = lHeight;
  374.             GetElement()->baseline = lBaseline;
  375.         }
  376.     }
  377. }
  378.  
  379. //    Copy the current data out of the form element back into the
  380. //        layout struct.
  381. void CFormButton::UpdateCurrentData()
  382. {
  383.     //    There is literally no data to update for this element type right now.
  384.     //    Perhaps one day....
  385.     if(GetContext())    {
  386.         if(GetContext()->IsWindowContext())    {
  387.             if(m_pWidget)    {
  388.             }
  389.             else    {
  390.             }
  391.         }
  392.         else if(GetContext()->IsPureDCContext())    {
  393.             //    Do some printing specific stuff here...
  394.         }
  395.     }
  396. }
  397.  
  398. HWND CFormButton::GetRaw()
  399. {
  400.     return(m_pWidget ? m_pWidget->m_hWnd : NULL);
  401. }
  402.