Page 1 of 1

Change color of a DCTABPAGE that has focus

Posted: Fri Aug 04, 2017 2:23 pm
by GeneB
What is the best way to change the color of the DCTABPAGE that has focus?

Re: Change color of a DCTABPAGE that has focus

Posted: Sat Aug 05, 2017 4:10 am
by Tom
Use GOTFOCUS to set the focus color and LOSTFOCUS to set the notfocused color. Which may work unless there are visual themes active. Create your own tabmarker with ownerdrawing to catch this with all OS versions.

Re: Change color of a DCTABPAGE that has focus

Posted: Sun Aug 06, 2017 2:18 pm
by GeneB
Thanks, Tom.
Could you give me a sample code block to use inside of GOTFOCUS ?
Something simple that I can play with. I'm not using a visual theme.
I can't find any examples of how to do this anywhere.

Re: Change color of a DCTABPAGE that has focus

Posted: Mon Aug 07, 2017 7:29 am
by rdonnay
Here is a sample program:

Code: Select all

#INCLUDE "dcdialog.CH"

FUNCTION Main()

LOCAL GetList[0], oTab1, oTab2, oTab3, oBrowse1, oBrowse2, oBrowse3, ;
      aDir := Directory(), i, oDlg

@ 0,0 DCTABPAGE oTab1 CAPTION 'Tab 1' SIZE 100, 20 ;
      GOTFOCUS {|a,b,o|TabPageFocus(o,oDlg)}

@ 2,2 DCBROWSE oBrowse1 DATA aDir SIZE 96,17 PARENT oTab1

FOR i := 1 TO 10
  DCBROWSECOL ELEMENT i HEADER Alltrim(Str(i)) PARENT oBrowse1
NEXT

@ 0,0 DCTABPAGE oTab2 RELATIVE oTab1 CAPTION 'Tab 2' ;
      GOTFOCUS {|a,b,o|TabPageFocus(o,oDlg)}

@ 2,2 DCBROWSE oBrowse2 DATA aDir SIZE 96,17 PARENT oTab2

FOR i := 1 TO 10
  DCBROWSECOL ELEMENT i HEADER Alltrim(Str(i)) PARENT oBrowse2
NEXT

@ 0,0 DCTABPAGE oTab3 RELATIVE oTab2 CAPTION 'Tab 3' ;
      GOTFOCUS {|a,b,o|TabPageFocus(o,oDlg)}

@ 2,2 DCBROWSE oBrowse3 DATA aDir SIZE 96,17 PARENT oTab3

FOR i := 1 TO 10
  DCBROWSECOL ELEMENT i HEADER Alltrim(Str(i)) PARENT oBrowse3
NEXT

DCREAD GUI FIT TITLE 'Tab Colors' ;
   EVAL {|o|oDlg := o, TabPageFocus(oTab1,o)}

RETURN nil

* ----------

PROC appsys ; RETURN

* ----------

STATIC FUNCTION TabPageFocus(oTabPage,oDlg)

LOCAL i, aChildList

aChildList := oDlg:drawingArea:childList()

FOR i := 1 TO Len(aChildList)
  IF aChildList[i]:isDerivedFrom('DC_XbpTabPage')
    IF aChildList[i] == oTabPage
      oTabPage:setColorBG(GRA_CLR_CYAN)
    ELSE
      aChildList[i]:setColorBG(GRA_CLR_PALEGRAY)
    ENDIF
  ENDIF
NEXT

RETURN nil

Re: Change color of a DCTABPAGE that has focus

Posted: Mon Aug 07, 2017 11:39 am
by GeneB
Thanks, Roger, this is a very, very nice user feature, especially for screens full of tabs.
Perhaps a DCTABPAGE FOCUSCOLOR in the future?

Re: Change color of a DCTABPAGE that has focus

Posted: Mon Aug 07, 2017 1:15 pm
by rdonnay
Perhaps a DCTABPAGE FOCUSCOLOR in the future?
That's probably a good idea.

It would work similarly to DCTABPAGE IMAGE <img1> SELECTEDIMAGE <img2>
You may want to look at that. The IMAGE feature changes the Icon on the tab page when it is selected.

New syntax could be:

DCTABPAGE UNSELECTEDCOLOR <color1> SELECTEDCOLOR <color2>

Re: Change color of a DCTABPAGE that has focus

Posted: Tue Aug 08, 2017 3:28 pm
by GeneB
SELECTEDIMAGE is a good tool.

Using color on the tab pages would draw the user's attention to the active workspace and would show a selection of tabs that got them there. And the selective use of red pages would also be a good tool.
To really simplify it for the programmer, perhaps also add the default tab page selected/unselected colors to DCGETOPTIONS ?

Re: Change color of a DCTABPAGE that has focus

Posted: Thu Aug 10, 2017 1:44 pm
by rdonnay
This was more difficult than I thought it would be.

I decided that adding Tab Page focus colors at the command level was not a good idea, so instead I added a new Get-Set Function that is used to set both the colors and the caption font when a tab gets and loses focus. Due to anonomolies in the Xbase++ tabpage class, controlling both foreground and background colors is a pain, so some had to be done with owner drawing and some had to be done the old fashioned way.

More and more of my projects are requiring that I use visual style for tabpages. This prevents the tab background color from being changed. Therefore, I needed a different solution, so instead I change the caption font. This solution works with both the classic style and visual style.

If you run TabPageFont.Exe it will display visual style tab pages.
If you run TabPageColor.Exe it will display classis style tab pages.
Both executables are created from the same source code.
The only difference is that TabPageFont.Exe has a manifest embedded to enable the visual style.
Look at TabPageFont.ARC.

The attachment contains the sample program and the changes to the eXpress++ source code with a new function named DC_TabPageOptions().

Copy DCDIALOG.CH to \exp20\include
Copy _DCCLASS.PRG to \exp20\source\dclipx and rebuild DCLIPX.DLL by running BUILD20.BAT.
Copy remaining files to a test folder and run PBUILD TabPageOption.xpj

Run TabPageColor.exe to see the following screen:
tabpagecolor.Jpg
tabpagecolor.Jpg (84.25 KiB) Viewed 15163 times
Run TabPageFont.exe to see the following screen:
tabpagefont.jpg
tabpagefont.jpg (67.09 KiB) Viewed 15163 times
Sample source code:

Code: Select all

 FUNCTION Main()

LOCAL GetList[0], oTab1, oTab2, oTab3, oBrowse1, oBrowse2, oBrowse3, ;
      aDir := Directory(), i, oDlg, aTabOptions

aTabOptions := { ;
   GRA_CLR_DARKRED, ;
   GraMakeRGBColor({200,200,150}), ;
   GRA_CLR_BLACK, ;
   GraMakeRGBColor({200,150,200}), ;
   '11.Arial Bold', ;
   '10.Arial' }

DC_TabPageOptions(aTabOptions)

@ 0,0 DCTABPAGE oTab1 CAPTION 'Tab 1' SIZE 100, 20 ;

@ 2,2 DCBROWSE oBrowse1 DATA aDir SIZE 96,17 PARENT oTab1 USEVISUALSTYLE ;
      CURSORMODE XBPBRW_CURSOR_ROW ;

FOR i := 1 TO 10
  DCBROWSECOL ELEMENT i HEADER 'Column ' + Alltrim(Str(i)) PARENT oBrowse1 ;
    HFONT '10.Lucida Console Bold' WIDTH 10
NEXT

@ 0,0 DCTABPAGE oTab2 RELATIVE oTab1 CAPTION 'Tab 2' ;

@ 2,2 DCBROWSE oBrowse2 DATA aDir SIZE 96,17 PARENT oTab2 USEVISUALSTYLE

FOR i := 1 TO 10
  DCBROWSECOL ELEMENT i HEADER Alltrim(Str(i)) PARENT oBrowse2
NEXT

@ 0,0 DCTABPAGE oTab3 RELATIVE oTab2 CAPTION 'Tab 3' ;

@ 2,2 DCBROWSE oBrowse3 DATA aDir SIZE 96,17 PARENT oTab3 USEVISUALSTYLE

FOR i := 1 TO 10
  DCBROWSECOL ELEMENT i HEADER Alltrim(Str(i)) PARENT oBrowse3
NEXT

DCREAD GUI FIT TITLE 'Tab Option Test' ;
  EVAL {|o|DC_TabActivate(oTab1)}

RETURN nil

* ----------

PROC appsys ; RETURN