Better method Gradient() for class TWindow

Better method Gradient() for class TWindow

Postby byte-one » Tue Jul 25, 2017 10:35 am

The height and width from gradientfill() is ::nHeight and ::nWidth from the window/dialog. This includes caption, borders, etc and this seems to be wrong.
We should use the real ClientArea!
Use for a test {{0.49,CLR_GRAY,CLR_WHITE},{0.02,CLR_BLACK,CLR_BLACK},{0.49,CLR_WHITE,CLR_GRAY}} as gradient. The black line should located in the middle (V or H) from window/dialog

Code: Select all  Expand view

METHOD Gradient( aGradColors ) CLASS TWindow

   local hDC, hBmp, hBmpOld, aClient := GetClientRect(::hWnd), nHeight := aClient[3]-aClient[1], nWidth := aClient[4]-aClient[2]

   DEFAULT aGradColors := ::aGradColors

   if aGradColors == nil
      return nil
   endif

   hDC = CreateCompatibleDC( ::GetDC() )
   hBmp = CreateCompatibleBitMap( ::hDC, nWidth, nHeight )
   hBmpOld = SelectObject( hDC, hBmp )

   GradientFill( hDC, 0, 0, nHeight, nWidth, aGradColors )

   if ::oBrush != nil
      ::oBrush:End()
   endif

   ::oBrush = TBrush():New()
   ::oBrush:hBitmap = hBmp
   ::oBrush:hBrush = CreatePatternBrush( hBmp )

   SelectObject( hDC, hBmpOld )

   ::ReleaseDC()

return nil
Regards,
Günther
---------------------------------
office@byte-one.com
User avatar
byte-one
 
Posts: 1048
Joined: Mon Oct 24, 2005 9:54 am
Location: Austria

Re: Better method Gradient() for class TWindow

Postby nageswaragunupudi » Fri Jul 28, 2017 2:52 am

You get best results by using Gradient Brush rather than using gradient function.

Please try:
Code: Select all  Expand view
  local oDlg, aGrad, oBrush

   aGrad := {{0.49,CLR_GRAY,CLR_WHITE},{0.02,CLR_BLACK,CLR_BLACK},{0.49,CLR_WHITE,CLR_GRAY}}

   DEFINE BRUSH oBrush GRADIENT aGrad

   DEFINE DIALOG oDlg BRUSH oBrush TITLE "GRADIENT BRUSH"

   ACTIVATE DIALOG oDlg CENTERED

   RELEASE BRUSH oBrush

 

Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10208
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Better method Gradient() for class TWindow

Postby byte-one » Fri Jul 28, 2017 6:00 am

Mr. Rao, right, but in method SetSize() the method gradient() is using and should be correct.
Regards,
Günther
---------------------------------
office@byte-one.com
User avatar
byte-one
 
Posts: 1048
Joined: Mon Oct 24, 2005 9:54 am
Location: Austria

Re: Better method Gradient() for class TWindow

Postby nageswaragunupudi » Fri Jul 28, 2017 5:33 pm

byte-one wrote:Mr. Rao, right, but in method SetSize() the method gradient() is using and should be correct.


SetSize does not affect gradient brush.

We have 2 alternative approaches to show gradient background for a window/dialog. (A) Use gradient method/clause and (B) create a gradient brush and apply the brush to window/dialog.

A) Using gradient method. (Upto ver 17.06)
1) Does not fill the client rect correctly. (This is what you rightly pointed out and your fix also is right)
2) Gradient is not resizeable when the window/dialog is resized.
3) Painting of some controls (eg. TUrlLink) fails.

B) Using Gradient Brushes
1) Exactly fits the ClientRect
2) Resizeable
3) All transparent controls are painted properly

This is a test program to compare:
Code: Select all  Expand view

#include "fivewin.ch"

function Main()

   local oDlg, aGrad, oBrush, oBar, oUrl
   local nChoice

   nChoice := Alert( "Select", { "GRADIENT BRUSH", "GRADIENT METHOD" } )

   aGrad := { { 0.02, CLR_HGREEN, CLR_HGREEN }, ;
              { 0.47, CLR_GRAY,   CLR_WHITE  }, ;
              { 0.02, CLR_BLACK,  CLR_BLACK  }, ;
              { 0.47, CLR_WHITE,  CLR_GRAY   }, ;
              { 0.02, CLR_HRED,   CLR_HRED   }, 0  }

   DEFINE BRUSH oBrush GRADIENT aGrad

   if nChoice == 1
      DEFINE DIALOG oDlg TRUEPIXEL BRUSH oBrush TITLE "GRADIENT BRUSH"
   else
      DEFINE DIALOG oDlg TRUEPIXEL GRADIENT aGrad TITLE "GRADIENT METHOD"
   endif

   // Make Dialog resizeable
   oDlg:nStyle    += ( WS_MAXIMIZEBOX + WS_MINIMIZEBOX + WS_THICKFRAME )

   @ 110,20 URLLINK oUrl URL "www.fivetechsoft.com" PIXEL OF oDlg
   oUrl:lTransparent := .t.

   ACTIVATE DIALOG oDlg CENTERED

   RELEASE BRUSH oBrush

return nil
 


Image

FWH17.07
1) Adopted your suggestion to fix issue (1)
2) Also modified Gradient method and now gradient is resizeable like brushes
3) Yet to find a fix for issue No.3
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10208
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Better method Gradient() for class TWindow

Postby nageswaragunupudi » Fri Jul 28, 2017 5:55 pm

What next?
From FWH17.07, both brush and gradient method function the same way.
Let is add buttonbar and see.

Gradient fills ClientRect, but part of it is occupied by buttonbar, hiding the top part of the gradient. In case we like the gradient to fit the visible client area (excluding oTop(oBar), oBottom(MsgBar),oLeft and oRight) what we can do is:

oDlg:oBrush:lClientArea := .T. // FWH17.07

Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10208
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Better method Gradient() for class TWindow

Postby byte-one » Fri Jul 28, 2017 6:15 pm

Thanks, Mr. Rao! This is perfect.
Regards,
Günther
---------------------------------
office@byte-one.com
User avatar
byte-one
 
Posts: 1048
Joined: Mon Oct 24, 2005 9:54 am
Location: Austria


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: MarcoBoschi and 10 guests