/*
 * Xailer source code:
 *
 * Bevel.prg
 * Clase TBevel()
 *
 * Copyright 2003, 2007 Jose F. Gimenez
 * Copyright 2003, 2007 Xailer.com
 * All rights reserved
 *
 */

#include "Xailer.ch"

//--------------------------------------------------------------------------

CLASS XBevel FROM TWinControl

PUBLISHED:
   PROPERTY nWidth         INIT 100
   PROPERTY nHeight        INIT 100

   PROPERTY nBorderStyle   INIT bvETCHED
   PROPERTY nBorderSides
   PROPERTY lTransparent   INIT .F.
   PROPERTY lOwnBorder     INIT .F.
   PROPERTY nOpacity       INIT 0

   PROPERTY nPenColor INIT clLightGray WRITE INLINE ::SetPen( Value, nil, nil ) ;
                                       EDITOR PE_Color
   PROPERTY nPenSize  INIT 2           WRITE INLINE ::SetPen( nil, Value, nil )
   PROPERTY nPenStyle INIT psSolid     VALUES psSolid, psDash, psDot, psDashDot,;
                                       psDashDotDot, psNull, psInsideFrame ;
                                       WRITE INLINE ::SetPen( nil, nil, Value )

PROTECTED:
   DATA nClassStyle INIT nOr( CS_PARENTDC, CS_HREDRAW, CS_VREDRAW )
   DATA hPen

   PROPERTY cText
   EVENT OnDblClick()

PUBLIC:
   METHOD Create( oParent ) CONSTRUCTOR
   METHOD Free()
   METHOD SetPen( nColor, nSize, nStyle )

RESERVED:
   PROPERTY cMessage
   PROPERTY l3D
   PROPERTY lBorder
   PROPERTY lTabStop
   PROPERTY lParentFont
   PROPERTY nClrText
   PROPERTY oFont

   METHOD WMEraseBkgnd()   INLINE 1
   METHOD WMPaint()        EXTERN XWinControl_WMEraseBkgnd()
   METHOD WMNCCalcSize()
   METHOD WMNCPaint()

ENDCLASS

//------------------------------------------------------------------------------

METHOD Create( oParent ) CLASS XBevel

   ::Super:Create( oParent )
   ::SetPen()

RETURN Self

//------------------------------------------------------------------------------

METHOD Free() CLASS XBevel

   IF !Empty( ::hPen )
      DeleteObject( ::hPen )
      ::hPen := 0
   ENDIF

RETURN ::Super:Free()

//------------------------------------------------------------------------------

METHOD SetPen( nColor, nSize, nStyle ) CLASS XBevel

   UPDATE ::FnPenColor TO nColor ,;
          ::FnPenSize  TO nSize  ,;
          ::FnPenStyle TO nStyle

   IF !Empty( ::hPen )
      DeleteObject( ::hPen )
   ENDIF

   ::hPen := CreatePen( ::FnPenStyle, ::FnPenSize, ::FnPenColor )

   SetWindowPos( ::Handle, 0, 0, 0, 0, 0, ;
    nOr( SWP_DRAWFRAME, SWP_NOMOVE, SWP_NOSIZE, SWP_NOACTIVATE,SWP_NOZORDER ) )

RETURN NIL

//------------------------------------------------------------------------------

#pragma BEGINDUMP

#include <windows.h>
#include <xailer.h>
#include <constants.ch>

extern void PaintSelected( void );

//------------------------------------------------------------------------------

HB_FUNC_STATIC( XBEVEL_WMNCCALCSIZE )
{
   if ( hb_parnl( 1 ) )
      {
      PHB_ITEM Self = hb_stackSelfItem();
      BOOLEAN lOwnBorder = XA_ObjGetL( Self, "lOwnBorder" );
      LPNCCALCSIZE_PARAMS csp = (LPVOID) hb_parnl( 2 );

      if ( lOwnBorder )
         {
         UINT nMargin = XA_ObjGetNL( Self, "nPenSize" );
         if ( nMargin )
            {
            csp->rgrc[0].left += nMargin;
            csp->rgrc[0].top += nMargin;
            csp->rgrc[0].right -= nMargin;
            csp->rgrc[0].bottom -= nMargin;
            }
         }
      else
         {
         PHB_ITEM tControl;
         tControl = XA_ObjGetItemCopy( Self, "TControl" );
         XA_ObjSendNL2( tControl, "WMNCCalcSize", hb_parnl( 1 ), hb_parnl( 2 ) );
         hb_itemRelease( tControl );
         }
      }

   hb_ret();
}

//------------------------------------------------------------------------------

HB_FUNC_STATIC( XBEVEL_WMNCPAINT )
{
   PHB_ITEM Self = hb_stackSelfItem();
   BOOLEAN lOwnBorder = XA_ObjGetL( Self, "lOwnBorder" );
   HWND hWnd = GetHandleOf( Self );
   int nMargin = XA_ObjGetNL( Self, "nPenSize" );

   if ( lOwnBorder && hWnd && nMargin )
      {
      HDC hdc;
      RECT rect;
      HRGN hrgn = (HRGN) hb_parnl( 1 );
      HPEN hPen;
      UINT nBorderSides = XA_ObjGetNL( Self, "nBorderSides" );

      if( GetRgnBox( hrgn, &rect ) > NULLREGION )
         {
         rect.right += nMargin;
         rect.bottom += nMargin;
         hrgn = CreateRectRgnIndirect( &rect );
         }

      PrevWindowProc( hWnd, WM_NCPAINT, (WPARAM) hrgn, 0 );
      DeleteObject( hrgn );

      hdc = GetWindowDC( hWnd );

      GetWindowRect( hWnd, &rect );
      nMargin = ( nMargin >> 1 );
      rect.right -= rect.left;
      rect.bottom -= rect.top;
      rect.left = 0;
      rect.top = 0;

      hPen = SelectObject( hdc, (HPEN) XA_ObjGetNL( Self, "hPen" ) );

      if( nBorderSides & bsLEFT )
         {
         MoveToEx( hdc, rect.left + nMargin, rect.top, NULL );
         LineTo( hdc, rect.left + nMargin, rect.bottom );
         }

      if( nBorderSides & bsBOTTOM )
         {
         MoveToEx( hdc, rect.left, rect.bottom - max( nMargin, 1 ), NULL );
         LineTo( hdc, rect.right, rect.bottom - max( nMargin, 1 ) );
         }

      if( nBorderSides & bsRIGHT )
         {
         MoveToEx( hdc, rect.right - max( 1, nMargin ), rect.bottom, NULL );
         LineTo( hdc, rect.right - max( 1, nMargin ), rect.top );
         }

      if( nBorderSides & bsTOP )
         {
         MoveToEx( hdc, rect.right, rect.top + nMargin, NULL );
         LineTo( hdc, rect.left, rect.top + nMargin );
         }

      SelectObject( hdc, hPen );
      ReleaseDC( hWnd, hdc );
      PaintSelected();
      }

   else
      {
      PHB_ITEM tControl;
      tControl = XA_ObjGetItemCopy( Self, "TControl" );
      XA_ObjSendNL2( tControl, "WMNCPaint", hb_parnl( 1 ), hb_parnl( 2 ) );
      hb_itemRelease( tControl );
      }

   hb_retnl( 0 );
}

#pragma ENDDUMP
