Pickdate

User avatar
Silvio
Posts: 3107
Joined: Fri Oct 07, 2005 6:28 pm
Location: Teramo,Italy

Post by Silvio »

I think to insert two button instead of vscroll
and into the header of this control can be a TiTle and two buttons as :

@ 6, 2 BITMAP ::oBtnLeft SIZE 8, 11 OF Self NOBORDER
::oBtnLeft:hBitmap := ArrowLeft()
::oBtnLeft:lTransparent := .t.
::oBtnLeft:bLClicked :=......

@ 6, 14 BITMAP ::oBtnRight SIZE 8, 11 OF Self NOBORDER
::oBtnRight:hBitmap := ArrowRight()
::oBtnRight:lTransparent := .t.
::oBtnRight:bLClicked := ....

the functions
ArrowLeft()
ArrowRight()
load window predefined bitmaps
Best Regards, Saludos

Falconi Silvio
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Silvio,
Could you please post your suggestions now all in a working sample.

Thanks in advance
Otto
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Post by xProgrammer »

Hi Otto, Silvio

I am working on a different Calendar control because my needs are different (only want 2 months, and only want to pick single days) and I need it to run with FiveLinux so don't have ready made access to all the "cute" GUI options.

But the aim, I think, should be to end up with a class that can be used pretty much like a TGet, TWBrowse, TRadMenu or whatever on any window or dialog which is where Silvio is headed. But if you are ever only going to use the calendar in one place in one program then the effort would outweigh the advantages.

Just my thoughts
Doug
(xProgrammer)
User avatar
quique
Posts: 408
Joined: Sun Aug 13, 2006 5:38 am
Contact:

Post by quique »

Otto, I think the two scrolls are good, vertical to skip month to month and horizontal to skip year to year. One doesn't replace the other.

xProgrammer, I think if this calendar is like you need, it can be configurable, a DATA with the number of months that you want to show, a DATA to indicate if is possible to change with scrollbar and a DATA to indicate if is possible to pick a range of days or one day. Well I only thinking on the air, after all, the difficult thing already is done.
Saludos
Quique
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Post by xProgrammer »

Hi Quique

Good thinking but I want different layout and logic is very simple for what I want using buttons. I wrote an HTML / JavaScript version some time ago so what little logic is required is all there, it just needs to be translated.

But I am watching this thread with great interest.

One possible feature to think about is if you want the days on the calendar to reflect some status value. In my case not all sites are open on all days so ability to show on calendar which days a site is open would be good. For a booking system in other scenarios it might be good to indicate on which days there are no vacancies etc.

Regards
Doug
(xProgrammer)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Dear Otto, Silvio and others,

Lets do it right :-)

I am reviewing your code and there are many mistakes in it. So my only intention is that you get a clear understanding on building user defined new controls.

Lets focus on Method Paint() by now. Lets forget about the rest for now. We will go for functionality once the painting is ok and stable

Code: Select all

#include "FiveWin.ch" 

//----------------------------------------------------------------------------// 

function Main() 

   local oWnd, oPickDate 

   DEFINE WINDOW oWnd TITLE "Calendar" 

   oPickDate := TPickDate():New( 10, 10,,, oWnd ) 
   
   ACTIVATE WINDOW oWnd 

return nil 

//----------------------------------------------------------------------------// 

CLASS TPickDate FROM TControl 

   DATA nStartRow,  nStartCols 
   DATA oPlanFont, sy, sx 
   DATA ClickRow, syTemp, sxTemp, ClickCol 
   DATA StartDay, EndDay, oBrush 
   DATA hBru, hPen1, hPen3 
   DATA lMove AS LOGIC INIT .F. 
   DATA aPlan AS ARRAY INIT {} 
   DATA aTemp AS ARRAY INIT {} 
   DATA nStartZeile INIT 0 
   DATA nVersion 
   DATA nYear 
   DATA lBorder 
   DATA hPen

   CLASSDATA lRegistered AS LOGICAL 

   METHOD  New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, lBorder, oPlanFont, nClrFore, nClrBack, nVersion ) 
   METHOD  Initiate( hDlg ) INLINE Super:Initiate( hDlg ), ::Default() 
   METHOD  Paint() 
   METHOD  Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0 
   METHOD  SelectPen( hPen ) INLINE SelectObject( ::hDC, hPen ) 
   METHOD  End() INLINE ::Destroy() 
   METHOD  Destroy() 
   METHOD  LButtonUp( nRow, nCol, nKeyFlags ) 
   METHOD  Ldblclick( nRow, nCol, nKeyFlags ) 
   // METHOD  MouseMove( nRow, nCol, nKeyFlags ) 
   METHOD  PreviousYear() 
   METHOD  NextYear() 
   METHOD  EraseBkGnd( hDC ) INLINE 0

ENDCLASS 

//----------------------------------------------------------------------------// 

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, lBorder, oPlanFont, nClrFore,; 
            nClrBack, nVersion ) CLASS TPickDate 

   DEFAULT nWidth    := 800,; 
           nHeight   := 300,; 
           nLeft     := 0,; 
           nTop      := 0,; 
           nYear     := Year( Date() ),; 
           nVersion  := "1.0.0",; 
           oWnd      := GetWndDefault(),; 
           lBorder   := .T. 

   ::nTop       = nTop
   ::nLeft      = nLeft
   ::nBottom    = nTop + nHeight - 1
   ::nRight     = nLeft + nWidth - 1
   
   ::nStartCols := nLeft 
   ::nStartRow  := nTop 
   ::nYear      := nYear 
   ::lBorder    := lBorder 

   ::nStyle = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_BORDER ) 

   ::oWnd := oWnd 

   if ::oPlanFont == nil 
      DEFINE FONT ::oPlanFont NAME "ARIAL" SIZE  0,-11 
   else 
      ::oPlanFont := oPlanFont 
   endif 

   ::nClrText = nClrFore 
   ::nClrPane = nClrBack 

   ::sy          := 1 
   ::sx          := 1 
   ::syTemp      := 0 
   ::sxTemp      := 0 

   ::aPlan       := {} 
   ::ClickCol    := 0 
   ::ClickRow    := 0 
   ::startDay    := "" 
   ::endDay      := "" 
   ::lMove       := .f. 
   ::aTemp       := {} 
   ::nStartZeile := 0 

   AAdd( ::aTemp, { 0, 0 } )                          // 1 
   AAdd( ::aTemp, { 0, 0 } )                          // 2 
   AAdd( ::aTemp, { 0, 0 } )                          // 3 
   AAdd( ::aTemp, { 0, 0 } )                          // 4 
   AAdd( ::aTemp, { 0, 0 } )                          // 5 
   AAdd( ::aTemp, { 0, 0 } )                          // 6 
   AAdd( ::aTemp, { 0, 0 } )                          // 7 
   AAdd( ::aTemp, { 0, 0 } )                          // 8 
   AAdd( ::aTemp, { 0, 0 } )                          // 9 
   AAdd( ::aTemp, { 0, 0 } )                          // 10 
   AAdd( ::aTemp, { 0, 0 } )                          // 11 
   AAdd( ::aTemp, { 0, 0 } )                          // 12 

   #ifdef __XPP__ 
      DEFAULT ::lRegistered := .f. 
   #endif 

   ::Register( nOR( CS_VREDRAW, CS_HREDRAW ) ) 

   if ! Empty( oWnd:hWnd ) 
      ::Create() 
      oWnd:AddControl( Self ) 
   else 
      oWnd:DefControl( Self ) 
   endif 

return self 

//----------------------------------------------------------------------------// 

METHOD Paint() CLASS TPickDate 

   local aInfo := ::DispBegin(), hPen, hOld, oFont, nStep, n

   FillRect( ::hDC, GetClientRect( ::hWnd ), ::oBrush:hBrush )
   
   hPen = CreatePen( PS_SOLID, 1, CLR_BLACK )
   hOld = SelectObject( ::hDC, hPen ) 
   
   DEFINE FONT oFont NAME "Tahoma" SIZE 0, -12
   
   nStep = ::nHeight / 13  
   for n = 1 to 12
      ::Line( n * nStep, 0, n * nStep, ::nWidth - 1 )
      ::Say( n * nStep + 4, 3, cMonth( CToD( Str( n, 2 ) + "/01/" + Str( Year( Date() ), 4 ) ) ),,, oFont, .T. )
   next   

   nStep = ( ::nWidth - 60 ) / 36
   for n = 1 to 35
      ::Line( 0, 60 + ( nStep * n ), ::nHeight - 1, 60 + ( nStep * n ) )
      ::Say( 4, 60 + ( nStep * n ), SubStr( CDoW( CToD( Str( n, 2 ) + "/01/" + Str( Year( Date() ), 4 ) ) ), 1, 2 ),,, oFont, .T. )
   next   
   
   SelectObject( ::hDC, hOld )
   DeleteObject( hPen )
   
   ::DispEnd( aInfo )

return 0 

//----------------------------------------------------------------------------// 

 METHOD LButtonUp( nRow, nCol, nKeyFlags ) CLASS TPickDate 

    ::endDay := ::aPlan[::sx,::sy] 

   IF ::sy > 0 .AND. ::sx > 0 
      if msgYesNo(::startDay + " -- " + ::endDay + "    Tage: " +; 
         str( ctod(::endDay)-ctod(::startDay)  +1   ))=.t. 

      endif 
   ENDIF 
   ::lMove:=.f. 

return nil 

//----------------------------------------------------------------------------// 

METHOD Ldblclick( nRow, nCol, nKeyFlags )   CLASS TPickDate 

        local ITemp := 0 

   ::sx := INT((nRow - ::nStartRow)/::nHeight ) + 1 
   ::sy := INT((nCol - ::nStartCols)/::nWidth ) 

   IF ::sy > 0 .AND. ::sx > 0 
      ::startDay    := ::aPlan[::sx,::sy] 
      ::nStartZeile := ::sx 
      ::ClickRow    := (INT((nRow-::nStartRow)/::nHeight ))*::nHeight + ::nStartRow 
      ::ClickCol    :=  ::nStartCols + ::sy * ::nWidth 

      FOR ITemp := 1 TO 12 
         ::aTemp[ITemp,1]:=0 
      NEXT 

      sysrefresh() 

      ::lMove:=.t. 
   ENDIF 
       Super:LDblClick( nRow, nCol, nKeyFlags ) 

return nil 

 //----------------------------------------------------------------------------// 

 /*
 METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TPickDate 

    Super:MouseMove( nRow, nCol, nKeyFlags ) 

  if IsOverWnd( ::hWnd, nRow, nCol ) 
    if !::lCaptured 
       ::Capture() 
    endif 
 else 
    if !::lCaptured 
       ReleaseCapture() 
    endif 
   ENDIF 


if ::lMove 

 IF ::sx <>  (INT((nRow-::nStartRow)/::nHeight ) + 1) .OR.; 
    ::sx <>  (INT((nCol-::nStartCols )/::nHeight ) + 1 ) 


      ::sx := INT((nRow-::nStartRow)/::nHeight ) + 1 
      ::sy := INT((nCol -::nStartCols )/::nWidth ) 

      IF nRow < ::nStartRow 
         ::sx  := 0 
         nRow     := 0 
      ENDIF 

      ::sxTemp :=   ::nStartRow +  ::sx * ::nHeight 
      ::syTemp :=   ::nStartCols + ::sy * ::nWidth +  ::nWidth 
      ENDIF 

    endif 
    
return nil 
*/

//-----------------------------------------------------------------// 

METHOD Destroy() CLASS TPickDate 

   RELEASE FONT ::oplanFont 

   ::hBru:end() 
   ::hPen:end() 
   ::hPen1:end() 
   ::hPen3:end() 

return nil 

//-----------------------------------------------------------------// 

method PreviousYear() CLASS TPickDate 

   ::nYear := ::nYear - 1 
   ::Paint() 
  *::oWnd:refresh() 
   ::oWnd:cTitle := "Kalender [ " + str(::nYear,4) + " ]" 

return .T. 

//-----------------------------------------------------------------// 

method NextYear() CLASS TPickDate 

   ::nYear := ::nYear + 1 
   ::Paint() 
   *::oWnd:refresh() 
   ::oWnd:cTitle := "Kalender [ " + str(::nYear,4) + " ]" 

return .T. 

//-----------------------------------------------------------------// 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Lets add this line at the beginning, so we can check how the control resizes:

Code: Select all

#include "FiveWin.ch" 

//----------------------------------------------------------------------------// 

function Main() 

   local oWnd, oPickDate 

   DEFINE WINDOW oWnd TITLE "Calendar" 

   oPickDate := TPickDate():New( 10, 10,,, oWnd ) 
   
   oWnd:oClient = oPickDate  // here!
   
   ACTIVATE WINDOW oWnd 

return nil

Now resize the main window and the control will resize to fit the window area
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Just working on the painting for now:

Code: Select all

METHOD Paint() CLASS TPickDate 

   local aInfo := ::DispBegin(), hPen, hOld, oFont, nRowStep, nColStep, n

   FillRect( ::hDC, GetClientRect( ::hWnd ), ::oBrush:hBrush )
   
   hPen = CreatePen( PS_SOLID, 1, CLR_BLACK )
   hOld = SelectObject( ::hDC, hPen ) 
   
   DEFINE FONT oFont NAME "Tahoma" SIZE 0, -12
   
   nRowStep = ::nHeight / 13  
   for n = 1 to 12
      ::Line( n * nRowStep, 0, n * nRowStep, ::nWidth - 1 )
      ::Say( n * nRowStep + ( nRowStep * 0.3 ), 3, cMonth( CToD( Str( n, 2 ) + "/01/" + Str( Year( Date() ), 4 ) ) ),,, oFont, .T. )
   next   

   nColStep = ( ::nWidth - 60 ) / 36
   for n = 1 to 35
      ::Line( 0, 60 + ( nColStep * n ), ::nHeight - 1, 60 + ( nColStep * n ) )
      ::Say( nRowStep * 0.5, 60 - 3 + ( nColStep * n ) + ( nColStep * 0.3 ),;
             SubStr( CDoW( CToD( "01/" + Str( n, 2 ) + "/" + Str( Year( Date() ), 4 ) ) ), 1, 2 ),,, oFont, .T. )
   next   
   
   SelectObject( ::hDC, hOld )
   DeleteObject( hPen )
   
   ::DispEnd( aInfo )

return 0 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Hello Antonio,

thank you very much for your response.

It was Silvios idea to make a “User defined new control”.

I only made pickdate first as a function and then I tried to make a class but not a new control.
I am not that skilled.

The thing I shared is the use of an array I mean to fill the array and to know from the coordinates of the mouse move which day the mouse is over and in which column to position the first day of a month.
This part I think is not that bad.

I would be very happy if you assist to make a real user defined class. We could learn much practicing on that sample.

Could you please post some information what

CLASSDATA lRegistered AS LOGICAL
does exactly.

-----
One question about the use of oFont.
Should oFont not be released or declared as DATA od static?


Regards,
Otto
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

> This part I think is not that bad.

I am sure there is a lot of valuable code in there. I am just reviewing the user defined control Class implementation for now. Silvio's proposal to create a new control Class is the way to go.

> CLASSDATA lRegistered AS LOGICAL

It is needed for new control Classes that are not Windows estandard. Windows API requires to "register" a control class name. It has to be registered only once. That DATA controls that. Estandard Window classes are already "registered" by Windows itself.

>
One question about the use of oFont.
Should oFont not be released or declared as DATA od static?
>

It should be used as a DATA. I am just doing a quick painting test that needs to be improved.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mmercado
Posts: 782
Joined: Wed Dec 19, 2007 7:50 am
Location: Salamanca, Gto., México

Post by mmercado »

Otto wrote:It was Silvios idea to make a “User defined new control”
Why a new class?

Why not just adaptate the Otto's routine or mine (CalAnual posted at spanish forum) for working with a browser (TXBrowse or TSBrowse) and take advantage of all the procedural and graphical facilities that browsers already have?

It's my point of view, regards.

Manuel Mercado.
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Still just focused on painting:

Code: Select all

#include "FiveWin.ch" 

//----------------------------------------------------------------------------// 

function Main() 

   local oWnd, oPickDate 

   DEFINE WINDOW oWnd TITLE "Calendar" 

   oPickDate := TPickDate():New( 10, 10,,, oWnd ) 
   
   oWnd:oClient = oPickDate
   
   ACTIVATE WINDOW oWnd MAXIMIZED

return nil 

//----------------------------------------------------------------------------// 

CLASS TPickDate FROM TControl 

   DATA nStartRow,  nStartCols 
   DATA oPlanFont, sy, sx 
   DATA ClickRow, syTemp, sxTemp, ClickCol 
   DATA StartDay, EndDay, oBrush 
   DATA hBru, hPen1, hPen3 
   DATA lMove AS LOGIC INIT .F. 
   DATA aPlan AS ARRAY INIT {} 
   DATA aTemp AS ARRAY INIT {} 
   DATA nStartZeile INIT 0 
   DATA nVersion 
   DATA nYear 
   DATA lBorder 
   DATA hPen

   CLASSDATA lRegistered AS LOGICAL 

   METHOD  New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, lBorder, oPlanFont, nClrFore, nClrBack, nVersion ) 
   METHOD  Initiate( hDlg ) INLINE Super:Initiate( hDlg ), ::Default() 
   METHOD  Paint() 
   METHOD  Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0 
   METHOD  SelectPen( hPen ) INLINE SelectObject( ::hDC, hPen ) 
   METHOD  End() INLINE ::Destroy() 
   METHOD  Destroy() 
   METHOD  LButtonUp( nRow, nCol, nKeyFlags ) 
   METHOD  Ldblclick( nRow, nCol, nKeyFlags ) 
   // METHOD  MouseMove( nRow, nCol, nKeyFlags ) 
   METHOD  PreviousYear() 
   METHOD  NextYear() 
   METHOD  EraseBkGnd( hDC ) INLINE 0

ENDCLASS 

//----------------------------------------------------------------------------// 

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, lBorder, oPlanFont, nClrFore,; 
            nClrBack, nVersion ) CLASS TPickDate 

   DEFAULT nWidth    := 800,; 
           nHeight   := 300,; 
           nLeft     := 0,; 
           nTop      := 0,; 
           nYear     := Year( Date() ),; 
           nVersion  := "1.0.0",; 
           oWnd      := GetWndDefault(),; 
           lBorder   := .T. 

   ::nTop       = nTop
   ::nLeft      = nLeft
   ::nBottom    = nTop + nHeight - 1
   ::nRight     = nLeft + nWidth - 1
   
   ::nStartCols := nLeft 
   ::nStartRow  := nTop 
   ::nYear      := nYear 
   ::lBorder    := lBorder 

   ::nStyle = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_BORDER ) 

   ::oWnd := oWnd 

   if ::oPlanFont == nil 
      DEFINE FONT ::oPlanFont NAME "ARIAL" SIZE  0,-11 
   else 
      ::oPlanFont := oPlanFont 
   endif 

   ::nClrText = nClrFore 
   ::nClrPane = nClrBack 

   ::sy          := 1 
   ::sx          := 1 
   ::syTemp      := 0 
   ::sxTemp      := 0 

   ::aPlan       := {} 
   ::ClickCol    := 0 
   ::ClickRow    := 0 
   ::startDay    := "" 
   ::endDay      := "" 
   ::lMove       := .f. 
   ::aTemp       := {} 
   ::nStartZeile := 0 

   AAdd( ::aTemp, { 0, 0 } )                          // 1 
   AAdd( ::aTemp, { 0, 0 } )                          // 2 
   AAdd( ::aTemp, { 0, 0 } )                          // 3 
   AAdd( ::aTemp, { 0, 0 } )                          // 4 
   AAdd( ::aTemp, { 0, 0 } )                          // 5 
   AAdd( ::aTemp, { 0, 0 } )                          // 6 
   AAdd( ::aTemp, { 0, 0 } )                          // 7 
   AAdd( ::aTemp, { 0, 0 } )                          // 8 
   AAdd( ::aTemp, { 0, 0 } )                          // 9 
   AAdd( ::aTemp, { 0, 0 } )                          // 10 
   AAdd( ::aTemp, { 0, 0 } )                          // 11 
   AAdd( ::aTemp, { 0, 0 } )                          // 12 

   #ifdef __XPP__ 
      DEFAULT ::lRegistered := .f. 
   #endif 

   ::Register( nOR( CS_VREDRAW, CS_HREDRAW ) ) 

   if ! Empty( oWnd:hWnd ) 
      ::Create() 
      oWnd:AddControl( Self ) 
   else 
      oWnd:DefControl( Self ) 
   endif 

return self 

//----------------------------------------------------------------------------// 

METHOD Paint() CLASS TPickDate 

   local aInfo := ::DispBegin(), hPen, hOld, oFont, nRowStep, nColStep, n, dDate
   local hDC := ::hDC, cDay

   FillRect( hDC, GetClientRect( ::hWnd ), ::oBrush:hBrush )
   
   hPen = CreatePen( PS_SOLID, 1, CLR_BLACK )
   hOld = SelectObject( hDC, hPen ) 
   
   DEFINE FONT oFont NAME "Tahoma" SIZE 0, -12
   
   nRowStep = ::nHeight / 13  
   for n = 1 to 12
      ::Line( n * nRowStep, 0, n * nRowStep, ::nWidth - 1 )
      ::Say( n * nRowStep + ( nRowStep * 0.3 ), 3, cMonth( CToD( Str( n, 2 ) + "/01/" + Str( Year( Date() ), 4 ) ) ),,, oFont, .T. )
   next   

   dDate = CToD( "06/01/2008" )
   nColStep = ( ::nWidth - 60 ) / 36
   for n = 1 to 35
      ::Line( 0, 60 + ( nColStep * n ), ::nHeight - 1, 60 + ( nColStep * n ) )
      cDay = SubStr( CDoW( dDate++ ), 1, 2 )
      ::Say( nRowStep * 0.5,;
             60 + ( nColStep * n ) + ( nColStep / 2 ) - ( GetTextWidth( hDC, cDay, oFont:hFont ) / 2 ) + 1,;
             cDay,,, oFont, .T. )
   next   
   
   SelectObject( hDC, hOld )
   DeleteObject( hPen )
   
   ::DispEnd( aInfo )

return 0 

//----------------------------------------------------------------------------// 

 METHOD LButtonUp( nRow, nCol, nKeyFlags ) CLASS TPickDate 

    ::endDay := ::aPlan[::sx,::sy] 

   IF ::sy > 0 .AND. ::sx > 0 
      if msgYesNo(::startDay + " -- " + ::endDay + "    Tage: " +; 
         str( ctod(::endDay)-ctod(::startDay)  +1   ))=.t. 

      endif 
   ENDIF 
   ::lMove:=.f. 

return nil 

//----------------------------------------------------------------------------// 

METHOD Ldblclick( nRow, nCol, nKeyFlags )   CLASS TPickDate 

        local ITemp := 0 

   ::sx := INT((nRow - ::nStartRow)/::nHeight ) + 1 
   ::sy := INT((nCol - ::nStartCols)/::nWidth ) 

   IF ::sy > 0 .AND. ::sx > 0 
      ::startDay    := ::aPlan[::sx,::sy] 
      ::nStartZeile := ::sx 
      ::ClickRow    := (INT((nRow-::nStartRow)/::nHeight ))*::nHeight + ::nStartRow 
      ::ClickCol    :=  ::nStartCols + ::sy * ::nWidth 

      FOR ITemp := 1 TO 12 
         ::aTemp[ITemp,1]:=0 
      NEXT 

      sysrefresh() 

      ::lMove:=.t. 
   ENDIF 
       Super:LDblClick( nRow, nCol, nKeyFlags ) 

return nil 

 //----------------------------------------------------------------------------// 

 /*
 METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TPickDate 

    Super:MouseMove( nRow, nCol, nKeyFlags ) 

  if IsOverWnd( ::hWnd, nRow, nCol ) 
    if !::lCaptured 
       ::Capture() 
    endif 
 else 
    if !::lCaptured 
       ReleaseCapture() 
    endif 
   ENDIF 


if ::lMove 

 IF ::sx <>  (INT((nRow-::nStartRow)/::nHeight ) + 1) .OR.; 
    ::sx <>  (INT((nCol-::nStartCols )/::nHeight ) + 1 ) 


      ::sx := INT((nRow-::nStartRow)/::nHeight ) + 1 
      ::sy := INT((nCol -::nStartCols )/::nWidth ) 

      IF nRow < ::nStartRow 
         ::sx  := 0 
         nRow     := 0 
      ENDIF 

      ::sxTemp :=   ::nStartRow +  ::sx * ::nHeight 
      ::syTemp :=   ::nStartCols + ::sy * ::nWidth +  ::nWidth 
      ENDIF 

    endif 
    
return nil 
*/

//-----------------------------------------------------------------// 

METHOD Destroy() CLASS TPickDate 

   RELEASE FONT ::oplanFont 

   ::hBru:end() 
   ::hPen:end() 
   ::hPen1:end() 
   ::hPen3:end() 

return nil 

//-----------------------------------------------------------------// 

method PreviousYear() CLASS TPickDate 

   ::nYear := ::nYear - 1 
   ::Paint() 
  *::oWnd:refresh() 
   ::oWnd:cTitle := "Kalender [ " + str(::nYear,4) + " ]" 

return .T. 

//-----------------------------------------------------------------// 

method NextYear() CLASS TPickDate 

   ::nYear := ::nYear + 1 
   ::Paint() 
   *::oWnd:refresh() 
   ::oWnd:cTitle := "Kalender [ " + str(::nYear,4) + " ]" 

return .T. 

//-----------------------------------------------------------------// 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Manuel,

Yes, you are right, a browse could be used for this purpose.

But I see it as a good exercise to teach how to build new controls :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Image

Code: Select all

METHOD Paint() CLASS TPickDate 

   local aInfo := ::DispBegin(), hPen, hOld, oFont, nRowStep, nColStep, n, dDate
   local hDC := ::hDC, cDay, oBrush

   FillRect( hDC, GetClientRect( ::hWnd ), ::oBrush:hBrush )
   
   DEFINE BRUSH oBrush COLOR nRGB( 183, 249, 185 )
   
   hPen = CreatePen( PS_SOLID, 1, CLR_BLACK )
   hOld = SelectObject( hDC, hPen ) 
   
   DEFINE FONT oFont NAME "Tahoma" SIZE 0, -12
   
   nRowStep = ::nHeight / 13  
   for n = 1 to 12
      ::Line( n * nRowStep, 0, n * nRowStep, ::nWidth - 1 )
      ::Say( n * nRowStep + ( nRowStep / 2 ) - ( oFont:nHeight / 2 ), 3, cMonth( CToD( Str( n, 2 ) + "/01/" + Str( Year( Date() ), 4 ) ) ),,, oFont, .T. )
   next   

   dDate = CToD( "06/01/2008" )
   nColStep = ( ::nWidth - 60 ) / 36
   for n = 1 to 35 step 7
      FillRect( hDC, { 0, 60 + ( nColStep * n ), ::nHeight - 1, 60 + ( nColStep * ( n + 1 ) ) }, oBrush:hBrush )
   next    
   for n = 1 to 35
      ::Line( 0, 60 + ( nColStep * n ), ::nHeight - 1, 60 + ( nColStep * n ) )
      cDay = SubStr( CDoW( dDate ), 1, 2 )
      ::Say( nRowStep * 0.5,;
             60 + ( nColStep * n ) + ( nColStep / 2 ) - ( GetTextWidth( hDC, cDay, oFont:hFont ) / 2 ) + 1,;
             cDay,, If( DoW( dDate++ ) == 1, nRGB( 128, 233, 176 ),), oFont, .T. )
   next   
   
   SelectObject( hDC, hOld )
   DeleteObject( hPen )
   
   ::DispEnd( aInfo )
   
   oBrush:End()

return 0 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Post by xProgrammer »

Hi all

I'm doing something much simpler given my needs and it needs to run in FiveLinux. Using TButton. Very basic proof of concept is as follows:

Image

Happy to share code but at this stage its dirty experimental stuff with navigation, links etc yet to come.

Code: Select all

CLASS CALENDAR

DATA aDATEBUTTONS
DATA aDOW
DATA dAnchorDate
DATA iLastBlank
DATA iDaysInMonth
DATA iStartOfMonth
DATA iEndOfMonth

METHOD New() CONSTRUCTOR
METHOD Show()
METHOD HideButtons()

ENDCLASS

METHOD New() CLASS CALENDAR

::dAnchorDate := DATE()
::aDATEBUTTONS := ARRAY( 37 )
::aDOW := { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }

Return self


METHOD Show() CLASS CALENDAR

LOCAL dlg_CALENDAR
LOCAL sTitle
LOCAL ii
LOCAL sLabel
LOCAL oGrp

sTitle := "Calendar"
DEFINE DIALOG dlg_CALENDAR TITLE sTitle SIZE 400, 400

dBOM := BOM( ::dAnchorDate )
::iStartOfMonth := DOW( dBOM )
::iLastBlank    := ::iStartOfMonth - 1
::iDaysInMonth  := DaysInMonth( MONTH( ::dAnchorDate ), IsLeap( ::dAnchorDate ) ) 
::iEndOfMonth   := ::iDaysInMonth + ::iLastBlank

sLabel := CMONTH( ::dAnchorDate ) + " " + STR( YEAR( ::dAnchorDate ) )
@ 9, 1 GROUP oGrp LABEL sLabel OF dlg_CALENDAR SIZE 370, 250 PIXEL
iRow := 120
iCol = 20
FOR ii = -6 TO 37
   IF ii > 0
      @ iRow, iCol BUTTON ::aDATEBUTTONS[ii] PROMPT "Test" OF dlg_CALENDAR PIXEL SIZE 40, 25
     ELSE
      @ iRow, iCol BUTTON ::aDOW[ii + 7] OF dlg_CALENDAR PIXEL SIZE 40, 25 WHEN .F.
   ENDIF
   iCol += 50
   IF iCol > 330
      iRow += 30
      iCol := 20
   ENDIF
NEXT

ACTIVATE DIALOG dlg_CALENDAR ON INIT ::HideButtons() 

RETURN nil


METHOD HideButtons() CLASS CALENDAR

FOR ii = 1 TO ::iLastBlank 
   ::aDATEBUTTONS[ii]:Hide()
NEXT
FOR ii = ::iStartOfMonth TO ::iEndOfMonth
   ::aDATEBUTTONS[ii]:SetText( ALLTRIM( STR( ii - ::iLastBlank ) ) )
   ::aDATEBUTTONS[ii]:Show()
NEXT
FOR ii = ( ::iEndOfMonth + 1 ) TO 37
   ::aDATEBUTTONS[ii]:Hide()
NEXT

RETURN nil
Above code is not suitable for use yet and doesn't really do anything other than put up a 1 month calendar. But it is pretty simple.

Regards
Doug
(xProgrammer)
Post Reply