Page 1 of 3

Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 9:18 am
by Natter

Is it possible to show more than one icon/button in an xBrowse cell ?
(or can this be done only by gluing the columns ?)


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 9:55 am
by Silvio.Falconi

oCol:bDrawData := { | oCol, hDC, aRect |

local nLeft := aRect[1]
local nTop := aRect[2]

// First icon
DrawTransparent( hDC, hBmp1, nTop, nLeft )

// second icon
DrawTransparent( hDC, hBmp2, nTop, nLeft + 20 )

return nil
}


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 11:07 am
by Natter

Hi, Silvio !

Did I understand correctly that when scrolling through xBrowse, oCol is performed for each row ?

oCol:bDrawData := { | oCol, hDC, aRect |nLeft := aRect[1], nTop := aRect[2], DrawTransparent( hDC, hBmp1, nTop, nLeft )}


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 1:50 pm
by Silvio.Falconi

You must ser the source xbrowse when insert + and - buttons tò have a samples


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 3:47 pm
by karinha

Maybe,

Code: Select all | Expand

// Example Structure
WITH OBJECT oBrw:aCols[ nCol ]
   :nEditType    := EDIT_BUTTON
   :aBtnBitmaps  := { "btn_one", "btn_two" } // Two icons
   :bBtnAction   := { |nRow, nCol, nFlags, oCol| MyAction( oCol:nBtnClick ) }
END

.or.

Code: Select all | Expand

oCol:bPaintText := { |oCol, hDC, cText, oRect| ;
   FW_DrawImage( hDC, "icon1", {oRect:nTop, oRect:nLeft, oRect:nBottom, oRect:nLeft+20} ),;
   FW_DrawImage( hDC, "icon2", {oRect:nTop, oRect:nLeft+25, oRect:nBottom, oRect:nLeft+45} ),;
   0 }
   

.or.

Code: Select all | Expand

WITH OBJECT oBrw:aCols[ nCol ]
   :nEditType := EDIT_GET_BUTTON
   :bEditBlock := { || ... }
END

viewtopic.php?p=225063#p225063

Regards, saludos.


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 4:50 pm
by Natter

Thanks, Karinha, I'll use it.

oCol:bDrawData is most suitable for my purposes, but I did not find such a block of code in xBrowse. :?:


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 5:20 pm
by karinha
Natter wrote: Fri Apr 17, 2026 4:50 pm

Thanks, Karinha, I'll use it.

oCol:bDrawData is most suitable for my purposes, but I did not find such a block of code in xBrowse. :?:

Maybe,

Code: Select all | Expand

// Exemplo: Desenhando um texto colorido baseado no valor da célula
oCol:bDrawData := { | oCol, xValue, nRow, nCol, nWidth, nHeight | ;
   DrawCellData( oCol, xValue, nRow, nCol, nWidth, nHeight ) }

// Função auxiliar para o desenho personalizado
STATIC FUNCTION DrawCellData( oCol, xValue, nRow, nCol, nWidth, nHeight )
   local oBrw := oCol:oBrw
   local nClrText := CLR_BLACK

   // Logica: Se o valor for negativo, texto vermelho
   IF ValType( xValue ) == "N" .and. xValue < 0
      nClrText := CLR_RED
   ENDIF

   // Desenha o texto formatado na célula
   oCol:DrawText( xValue, nRow, nCol, nWidth, nHeight, nClrText, nil, nil )
RETURN nil

https://fivetechsoft.com/forums/viewtopic.php?t=12654

Regards, saludos.


Re: Multiple icons/buttons in a cell

Posted: Fri Apr 17, 2026 5:23 pm
by karinha

Code: Select all | Expand

oCol:bDrawData := { | oCol, xData, lInvert, oBrush, lSelected | ;
   DrawCustomCell( oCol, xData, lInvert, ... ) }

Code: Select all | Expand

#include "FiveWin.ch"
#include "XBrowse.ch"

function Main()
    local oDlg, oBrw, oCol
    local aData := { {"João", "[email protected]"}, {"Maria", "[email protected]"} }

DEFINE DIALOG oDlg SIZE 400, 300

@ 0, 0 XBROWSE oBrw OF oDlg ARRAY aData AUTOCOLS

// Vamos personalizar a primeira coluna
oCol := oBrw:aCols[1]
oCol:cHeader := "Contatos"

// Define a altura da linha maior para caber os dados
oBrw:nDataLines := 2 

// Custom Drawing
oCol:bDrawData := { | oCol, xData, lInvert, oBrush, lSelected | ;
    DrawCustomCell( oCol, oBrw, lInvert ) }

oBrw:CreateFromCode()
ACTIVATE DIALOG oDlg CENTERED
return nil

// Função que realiza o desenho customizado
static function DrawCustomCell( oCol, oBrw, lInvert )
    local oGraphics := oCol:oBrw:oGraphics // GDI+
    local nRow := oCol:oBrw:nRowSel
    local nCol := oCol:nDisplayCol
    local nWidth := oCol:nWidth
    local nHeight := oCol:nHeight
    local hDC := oCol:oBrw:hDC
    local aRowData := oBrw:aRow // Dados da linha atual
    
// 1. Limpar fundo (opcional, mas recomendado) FillRect( hDC, {oBrw:nRowSel, oCol:nDisplayCol, oBrw:nRowSel + oBrw:nRowHeight, oCol:nDisplayCol + oCol:nWidth }, GetSysColor( COLOR_WINDOW ) ) // 2. Desenhar primeira linha (Nome - Negrito) SetTextColor( hDC, CLR_BLUE ) DrawText( hDC, aRowData[1], {oBrw:nRowSel + 2, oCol:nDisplayCol + 2, oBrw:nRowSel + (oBrw:nRowHeight/2), oCol:nDisplayCol + nWidth}, 0 ) // 3. Desenhar segunda linha (Email - Cinza/Menor) SetTextColor( hDC, CLR_GRAY ) DrawText( hDC, aRowData[2], {oBrw:nRowSel + (oBrw:nRowHeight/2), oCol:nDisplayCol + 2, oBrw:nRowSel + oBrw:nRowHeight, oCol:nDisplayCol + nWidth}, 0 ) return nil

I hope this helps you.

Regards, saludos.


Re: Multiple icons/buttons in a cell

Posted: Sat Apr 25, 2026 9:00 pm
by Natter

Is it possible to place more than 2 buttons/pictures in an xBrowse cell?


Re: Multiple icons/buttons in a cell

Posted: Sun Apr 26, 2026 7:13 am
by Antonio Linares

Dear Yuri,

Code: Select all | Expand

#include "FiveWin.ch"  
#include "XBrowse.ch"
static hBmp1, hBmp2, hBmp3
function Main()
local oDlg, oBrw, oFont, oFontSmall
local aData := { {"João", "[email protected]"}, ;
{"Maria", "[email protected]"}, ;
{"Pedro", "[email protected]"} }
// Load bitmaps (16x16 icons)
hBmp1 := ReadBitmap( 0, "..\bitmaps\16x16\adddbf.bmp" )
hBmp2 := ReadBitmap( 0, "..\bitmaps\16x16\zoom2.bmp" )
hBmp3 := ReadBitmap( 0, "..\bitmaps\16x16\delete.bmp" )
DEFINE FONT oFont NAME "Segoe UI" SIZE 0, -14
DEFINE FONT oFontSmall NAME "Segoe UI" SIZE 0, -11
DEFINE DIALOG oDlg SIZE 500, 400 TITLE "Custom Cell Drawing" FONT oFont
@ 0, 0 XBROWSE oBrw OF oDlg ;
ARRAY aData COLUMNS 1 ;
HEADERS "Contatos" ;
COLSIZES 400 ;
CELL NOBORDER
WITH OBJECT oBrw
:nRowHeight := 50
:nStretchCol := 1
:lRecordSelector := .F.
:CreateFromCode()
:aCols[ 1 ]:bPaintText := { | oCol, hDC, cText, aCoors, aColors, lHighlight | ;
DrawCustomCell( oCol, hDC, cText, aCoors, aColors, lHighlight, oFontSmall ) }
END
oBrw:SetFocus()
ACTIVATE DIALOG oDlg CENTERED ;
ON INIT oBrw:SetFocus()
// Cleanup
DeleteObject( hBmp1 )
DeleteObject( hBmp2 )
DeleteObject( hBmp3 )
oFont:End()
oFontSmall:End()
return nil
//----------------------------------------------------------------------------//
static function DrawCustomCell( oCol, hDC, cText, aCoors, aColors, lHighlight, oFontSmall )
// aCoors = { nTop, nLeft, nBottom, nRight }
local nTop := aCoors[ 1 ]
local nLeft := aCoors[ 2 ]
local nBottom := aCoors[ 3 ]
local nRight := aCoors[ 4 ]
local aRow := oCol:oBrw:aRow
local nMidY := nTop + Int( ( nBottom - nTop ) / 2 )
local nIconY := nTop + Int( ( nBottom - nTop - 16 ) / 2 ) // vertically center 16px icons
local hOldFont
// 1. Draw Name (first line, bold)
SetTextColor( hDC, CLR_BLACK )
DrawTextEx( hDC, aRow[ 1 ], { nTop + 2, nLeft + 2, nMidY, nRight - 60 }, DT_LEFT + DT_VCENTER + DT_SINGLELINE )
// 2. Draw Email (second line, smaller font, gray)
SetTextColor( hDC, CLR_HGRAY )
hOldFont := SelectObject( hDC, oFontSmall:hFont )
DrawTextEx( hDC, aRow[ 2 ], { nMidY, nLeft + 2, nBottom - 2, nRight - 60 }, DT_LEFT + DT_VCENTER + DT_SINGLELINE )
SelectObject( hDC, hOldFont )
// 3. Draw 3 icons on the right side, vertically centered
PalBmpDraw( hDC, nIconY, nRight - 54, hBmp1 ) // icon 1
PalBmpDraw( hDC, nIconY, nRight - 36, hBmp2 ) // icon 2
PalBmpDraw( hDC, nIconY, nRight - 18, hBmp3 ) // icon 3
return nil

Re: Multiple icons/buttons in a cell

Posted: Sun Apr 26, 2026 9:23 am
by Natter

Antonio,YES, that's what you need !!!

Is it possible to:

  1. change the distance between the icons
  2. center the icons horizontally
  3. process the click on the icon

Re: Multiple icons/buttons in a cell

Posted: Sun Apr 26, 2026 9:27 am
by Antonio Linares

Yes, all three are possible. Here's the complete code:

1. Change distance between icons

Simply use a variable nGap to control spacing:

Code: Select all | Expand

local nIconSize := 16   // icon width in pixels
local nGap      := 10   // distance between icons (change this value)

PalBmpDraw( hDC, nIconY, nX,                        hBmp1 )
PalBmpDraw( hDC, nIconY, nX + nIconSize + nGap,     hBmp2 )
PalBmpDraw( hDC, nIconY, nX + 2*(nIconSize + nGap), hBmp3 )
2. Center icons horizontally

Calculate the total width of all icons + gaps, then offset from the cell center:

Code: Select all | Expand

local nTotalWidth := (nIcons * nIconSize) + ((nIcons - 1) * nGap)
local nStartX     := nLeft + Int( (nCellWidth - nTotalWidth) / 2 )
3. Process click on each icon

Use oBrw:bLClicked for single-click detection. It receives (nRow, nCol, nFlags, oBrw) where nCol is the mouse X pixel position. Compare it against the icon positions using oCol:nDisplayCol and oCol:nWidth. 2-cite-0

For double-click, use oCol:bLDClickData which is evaluated as Eval( oCol:bLDClickData, nRow, nCol, nKeyFlags, oCol ). 2-cite-1

Complete working example

Code: Select all | Expand

#include "FiveWin.ch"
#include "XBrowse.ch"

static hBmp1, hBmp2, hBmp3
static nIconSize := 16
static nGap      := 10    // << change this to adjust distance between icons
static nIcons    := 3

function Main()

   local oDlg, oBrw, oFont, oFontSmall
   local aData := { {"João",  "[email protected]"},  ;
                     {"Maria", "[email protected]"}, ;
                     {"Pedro", "[email protected]"} }

   hBmp1 := ReadBitmap( 0, "..\bitmaps\16x16\adddbf.bmp" )
   hBmp2 := ReadBitmap( 0, "..\bitmaps\16x16\zoom2.bmp" )
   hBmp3 := ReadBitmap( 0, "..\bitmaps\16x16\delete.bmp" )

   DEFINE FONT oFont      NAME "Segoe UI" SIZE 0, -14
   DEFINE FONT oFontSmall  NAME "Segoe UI" SIZE 0, -11

   DEFINE DIALOG oDlg SIZE 500, 400 TITLE "Custom Cell Icons" FONT oFont

   @ 0, 0 XBROWSE oBrw OF oDlg ;
      ARRAY aData COLUMNS 1 ;
      HEADERS "Contatos" ;
      COLSIZES 400 ;
      CELL NOBORDER

   WITH OBJECT oBrw
      :nRowHeight  := 50
      :nStretchCol := 1
      :lRecordSelector := .F.

      // Custom painting
      :aCols[ 1 ]:bPaintText := { | oCol, hDC, cText, aCoors, aColors, lHighlight | ;
         DrawCustomCell( oCol, hDC, aCoors, oFontSmall ) }

      // Single-click detection on icons
      :bLClicked := { |nRow, nCol, nFlags, oBrw| ;
         CheckIconClick( nRow, nCol, oBrw ) }

      :CreateFromCode()
   END

   oBrw:SetFocus()

   ACTIVATE DIALOG oDlg CENTERED

   DeleteObject( hBmp1 )
   DeleteObject( hBmp2 )
   DeleteObject( hBmp3 )
   oFont:End()
   oFontSmall:End()

return nil

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

static function DrawCustomCell( oCol, hDC, aCoors, oFontSmall )

   local nTop       := aCoors[ 1 ]
   local nLeft      := aCoors[ 2 ]
   local nBottom    := aCoors[ 3 ]
   local nRight     := aCoors[ 4 ]
   local aRow       := oCol:oBrw:aRow
   local nMidY      := nTop + Int( ( nBottom - nTop ) / 2 )
   local nCellWidth := nRight - nLeft
   local hOldFont

   // -- Total width of all icons + gaps --
   local nTotalWidth := ( nIcons * nIconSize ) + ( ( nIcons - 1 ) * nGap )

   // -- Center icons horizontally --
   local nStartX    := nLeft + Int( ( nCellWidth - nTotalWidth ) / 2 )

   // -- Vertically center icons in top half --
   local nIconY     := nTop + Int( ( nMidY - nTop - nIconSize ) / 2 )

   // 1. Draw 3 icons centered horizontally with configurable gap
   PalBmpDraw( hDC, nIconY, nStartX,                              hBmp1 )
   PalBmpDraw( hDC, nIconY, nStartX + nIconSize + nGap,           hBmp2 )
   PalBmpDraw( hDC, nIconY, nStartX + 2 * ( nIconSize + nGap ),   hBmp3 )

   // 2. Draw Name below icons (centered)
   SetTextColor( hDC, CLR_BLACK )
   DrawTextEx( hDC, aRow[ 1 ], { nMidY, nLeft, nMidY + 14, nRight }, ;
      DT_CENTER + DT_SINGLELINE + DT_VCENTER )

   // 3. Draw Email below name (centered, smaller, gray)
   SetTextColor( hDC, CLR_HGRAY )
   hOldFont := SelectObject( hDC, oFontSmall:hFont )
   DrawTextEx( hDC, aRow[ 2 ], { nMidY + 14, nLeft, nBottom - 2, nRight }, ;
      DT_CENTER + DT_SINGLELINE + DT_VCENTER )
   SelectObject( hDC, hOldFont )

return nil

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

static function CheckIconClick( nRow, nCol, oBrw )

   local oCol       := oBrw:aCols[ 1 ]
   local nLeft      := oCol:nDisplayCol
   local nRight     := nLeft + oCol:nWidth
   local nCellWidth := nRight - nLeft
   local nTotalWidth := ( nIcons * nIconSize ) + ( ( nIcons - 1 ) * nGap )
   local nStartX    := nLeft + Int( ( nCellWidth - nTotalWidth ) / 2 )
   local nIcon1Left, nIcon2Left, nIcon3Left

   // Only process if click is in the data area (not header)
   if oBrw:MouseRowPos( nRow ) <= 0
      return nil
   endif

   // Calculate each icon's horizontal range
   nIcon1Left := nStartX
   nIcon2Left := nStartX + nIconSize + nGap
   nIcon3Left := nStartX + 2 * ( nIconSize + nGap )

   do case
   case nCol >= nIcon1Left .and. nCol <= nIcon1Left + nIconSize
      MsgInfo( "Icon 1 clicked! Row: " + oBrw:aRow[ 1 ], "Add" )

   case nCol >= nIcon2Left .and. nCol <= nIcon2Left + nIconSize
      MsgInfo( "Icon 2 clicked! Row: " + oBrw:aRow[ 1 ], "Zoom" )

   case nCol >= nIcon3Left .and. nCol <= nIcon3Left + nIconSize
      MsgInfo( "Icon 3 clicked! Row: " + oBrw:aRow[ 1 ], "Delete" )

   endcase

return nil
Key points:
  • nGap controls the pixel distance between icons. Change it to any value you want. 2-cite-2

  • Centering is done by computing nStartX := nLeft + Int( ( nCellWidth - nTotalWidth ) / 2 ) where nTotalWidth is the sum of all icon widths plus gaps.

  • Click detection uses oBrw:bLClicked which receives the pixel coordinates (nRow, nCol). The nCol value is compared against each icon's X range. The column's left pixel position is available via oCol:nDisplayCol and its width via oCol:nWidth. 2-cite-3

  • For double-click instead of single-click, use oCol:bLDClickData which receives (nRow, nCol, nKeyFlags, oCol) with the same pixel coordinates. 2-cite-1

  • You can also add vertical hit-testing by checking nRow against nIconY and nIconY + nIconSize if you want clicks to only register when exactly on the icon area.


Re: Multiple icons/buttons in a cell

Posted: Wed Apr 29, 2026 2:15 pm
by Natter

This option involves drawing an icon from a file.

Code: Select all | Expand

hBmp1 := ReadBitmap( 0, "..\bitmaps\16x16\adddbf.bmp" 
PalBmpDraw( hDC, nIconY, nStartX, hBmp1 )

How can I draw an icon from a resource?


Re: Multiple icons/buttons in a cell

Posted: Wed Apr 29, 2026 5:25 pm
by Enrico Maria Giordano

Code: Select all | Expand

hBmp1 := LoadBitmap( GetResources(), cResName )

Re: Multiple icons/buttons in a cell

Posted: Wed Apr 29, 2026 6:17 pm
by Natter

Thanks, Enrico!