Page 1 of 1

Autosize ListIconGadget headings based on heading length?

Posted: Thu Apr 06, 2017 3:16 am
by Fangbeast
I can already automatically resize each column in a ListIconGadget with an API but is there any way to resize the headings as well based on the heading text length?

Then I can resize the columns to fit the heading length.

Thanks

Re: Autosize ListIconGadget headings based on heading length

Posted: Thu Apr 06, 2017 9:44 am
by RASHAD
Hi Fang

Code: Select all

If OpenWindow(0, 0, 0, 640, 300, "Header Auto Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0,  10,  10, 620, 200, "Column 0", 400,#PB_ListIcon_GridLines)
  SetGadgetFont(0,FontID(0))
  AddGadgetColumn(0, 1, "Column 1" , 150)
  AddGadgetColumn(0, 2, "Column 2" , 150)
  For x = 0 To 100
    AddGadgetItem(0, x, "Item "+Str(x)+Chr(10)+"Item "+Str(x)+Chr(10)+"Item "+Str(x))
  Next
  ButtonGadget(1,10,270,60,20,"Auto size")


EndIf
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          SendMessage_(GadgetID(0), #LVM_SETCOLUMNWIDTH,0,#LVSCW_AUTOSIZE_USEHEADER)
          SendMessage_(GadgetID(0), #LVM_SETCOLUMNWIDTH,1,#LVSCW_AUTOSIZE_USEHEADER )
          ;SendMessage_(GadgetID(0), #LVM_SETCOLUMNWIDTH,2,#LVSCW_AUTOSIZE_USEHEADER )
      EndSelect
  EndSelect
Until Quit = 1

Re: Autosize ListIconGadget headings based on heading length

Posted: Thu Apr 06, 2017 9:59 am
by Fangbeast
AHA!!!! I knew there was an API for that!!! Since the data is smaller in length, I wanted the header to be fully visible anyway.

Thanks for that. I can play tomorrow Master RASHAD.

Just imported 28,000 weather station events into my little program and adding listing, viewing and eventually (I hope), graphs. (Was looking at your bar graphs for that, interesting stuff to be sure)

Re: Autosize ListIconGadget headings based on heading length

Posted: Thu Apr 06, 2017 1:28 pm
by Fangbeast
Okay, it's not working the way I thought. It's resizing the columns of data to the size of the biggest item of data but that's not what I wanted.

These are some of my column headings and data the way I want them to look: (All columns of data expanded to the length of their column headings)

Code: Select all

DateTime     Dewpoint  HeatIndex   IndoorHumidity  IndoorTemperature OutdoorHumidity
12/02/2017  12.3         62              14                     22c                       129
This is the way it is now. Neither the columns nor the headings are resized. I want the columns to be resized based on the length of the header in which it belongs.

Code: Select all

DateTi..        DewPo..    Heatin...     IndoorHum.....   IndoorTem........     OutdoorHumi....
23/12/2...    57            76              48                     74.4                      57
Sorry RASHAD, I probably am not explaining it very well. And I could not tab align the data in this forum post.

Re: Autosize ListIconGadget headings based on heading length

Posted: Thu Apr 06, 2017 3:27 pm
by IdeasVacuum
Hi Fang,

Since your header text width is always greater than the value width, you can use a little Procedure to get the widths and then apply them:

Code: Select all

Procedure.i GetHeaderColWidth(sColHeaderTxt.s, iFontID.i)
;#-------------------------------------------------------
;This Procedure does not draw anything, it just verifies text width in pixels
Protected iHeaderColW.i

              If StartDrawing(WindowOutput(#WinMain))

                      DrawingMode(#PB_2DDrawing_Default)
                      DrawingFont(iFontID)
                      iHeaderColW = TextWidth(sColHeaderTxt)
                      StopDrawing()
              EndIf

              ProcedureReturn(iHeaderColW)
EndProcedure
Then you can set the column width and justification:

Code: Select all

Procedure JustifyListCol(iListIconID.i, iCol.i, iFlag.i, iColWidth.i)
;#-------------------------------------------------------------------
;Justify ListIcon and Set Column Width
;Column Flag: 1 = Left, 2 = Right, 3 = Center

Protected lvc.LV_COLUMN

          lvc\Mask = #LVCF_FMT

              Select iFlag

                            Case 1: lvc\fmt = #LVCFMT_LEFT
                            Case 2: lvc\fmt = #LVCFMT_RIGHT
                            Case 3: lvc\fmt = #LVCFMT_CENTER
                           Default: lvc\fmt = #LVCFMT_LEFT
              EndSelect

              SendMessage_(GadgetID(iListIconID), #LVM_SETCOLUMNWIDTH, iCol, iColWidth)
              SendMessage_(GadgetID(iListIconID), #LVM_SETCOLUMN, iCol, @lvc)
EndProcedure
Those two Procedures could of course be combined into one.

If there is a chance that a column value width is wider than the header width, you can:
1) Hide the ListIcon;
2) Find the widest Value for each column, measured in chars, with Len(sVal) and compare to respective Header text width;
3) Size the column to either Header or Value, whichever is widest, via the Procedures above;
4) Populate the ListIcon;
5) Unhide the ListIcon.

If you set the redraw attribute for the ListIcon, you probably won't need to hide it as the whole process should be fast enough anyway:

Code: Select all

SendMessage_(GadgetID(iListID),#WM_SETREDRAW,0,0) ;Faster update
;Define Col widths and populate the ListIcon
SendMessage_(GadgetID(iListID),#WM_SETREDRAW,1,0)
I often define ListIcon columns this way because the sizes can be re-used for PDF table output.

Re: Autosize ListIconGadget headings based on heading length

Posted: Thu Apr 06, 2017 4:34 pm
by RASHAD
Hi Fang
Let MS do it for you :)

Code: Select all

Procedure AUTOSIZE_USEHEADER(gadget,font)
  text$ = GetGadgetItemText(gadget,-1,0)
  li = ListIconGadget(#PB_Any,0,0,0,0,text$,0)
  SetGadgetFont(li,FontID(font))
  Header = SendMessage_(GadgetID(gadget), #LVM_GETHEADER, 0, 0)
  nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
  
  For column = 1 To nColumns
    text$ = GetGadgetItemText(gadget,-1,column)
    AddGadgetColumn(li,column, text$ , 0)
  Next
  
  For column = 0 To nColumns
    SendMessage_(GadgetID(li), #LVM_SETCOLUMNWIDTH,column,#LVSCW_AUTOSIZE_USEHEADER)
  Next
  
  For column = 0 To nColumns
    Value = GetGadgetItemAttribute(li, 0, #PB_ListIcon_ColumnWidth ,column)
    SetGadgetItemAttribute(gadget, 0, #PB_ListIcon_ColumnWidth , Value,column)
  Next
  
  FreeGadget(li)   
EndProcedure

LoadFont(0,"tahoma",12)

If OpenWindow(0, 0, 0, 640, 300, "Header Auto Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0,  10,  10, 620, 200, "Column 0", 400,#PB_ListIcon_GridLines)
  SetGadgetFont(0,FontID(0))
  AddGadgetColumn(0, 1, "Column 1" , 150)
  AddGadgetColumn(0, 2, "Column 2" , 150)
  For x = 0 To 100
    AddGadgetItem(0, x, "Item Item item item item item "+Str(x)+Chr(10)+"Item "+Str(x)+Chr(10)+"Item Item item item item item "+Str(x))
  Next
  ButtonGadget(1,10,270,60,20,"Auto size")

EndIf
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          AUTOSIZE_USEHEADER(0,0)
      EndSelect
  EndSelect
Until Quit = 1

Re: Autosize ListIconGadget headings based on heading length

Posted: Thu Apr 06, 2017 10:16 pm
by Fangbeast
Thank you very much you two geniuses (or should that be "Genii??")

Another problem solved, just several thousand to go:):)

So many programs to rewrite to bring them up to spec..so damned tired.

Re: Autosize ListIconGadget headings based on heading length

Posted: Tue Jun 20, 2017 8:27 pm
by skywalk
Thanks for the api RASHAD,
I prefer to use the max of column data and header text.

Code: Select all

; Go back and get max text widths for each column.
; I'm only using 1 row's value but it could be extended to all.
For index = 0 To columns - 1
  SendMessage_(GadgetID(gadget), #LVM_SETCOLUMNWIDTH, index, #LVSCW_AUTOSIZE_USEHEADER)
  hdrWd = GetGadgetItemAttribute(Gadget, 0, #PB_ListIcon_ColumnWidth, index)
  SendMessage_(GadgetID(gadget), #LVM_SETCOLUMNWIDTH, index, #LVSCW_AUTOSIZE)
  dataWd = GetGadgetItemAttribute(Gadget, 0, #PB_ListIcon_ColumnWidth, index)
  SetGadgetItemAttribute(Gadget, 0, #PB_ListIcon_ColumnWidth, max(hdrWd, dataWd), index)
Next index

Re: Autosize ListIconGadget headings based on heading length

Posted: Wed Jun 21, 2017 1:07 pm
by RASHAD
Hi skywalk
Using Header or Columns without any fake ListIcon()

Code: Select all

Procedure AUTOSIZE_USEHEADER(gad,font)
  Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
  nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
  For col = 0 To ncolumns - 1
      text$ = GetGadgetItemText(gad, -1,col)
      StartDrawing(WindowOutput(0))
        DrawingFont(FontID(font))
        width = TextWidth(Text$)+12
      StopDrawing()
      SetGadgetItemAttribute(gad, -1, #PB_ListIcon_ColumnWidth, width,col)
  Next   
EndProcedure

Procedure AUTOSIZE_USECOLUMN(gad,font)
  Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
  nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
  For col = 0 To ncolumns - 1
    width = 0:oldwidth = 0
    For item = 0 To CountGadgetItems(gad)    
      text$ = GetGadgetItemText(gad,item , col)
      StartDrawing(WindowOutput(0))
        DrawingFont(FontID(font))
        width = TextWidth(Text$)+12
      StopDrawing()
      If width > oldwidth
        SetGadgetItemAttribute(gad, -1, #PB_ListIcon_ColumnWidth, width,col)
      EndIf
      oldwidth = width
    Next
  Next   
EndProcedure

LoadFont(0,"Tahoma",14)

If OpenWindow(0, 0, 0, 640, 300, "Header Auto Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0,  10,  10, 620, 200, "Column 0", 400,#PB_ListIcon_GridLines)
  
  AddGadgetColumn(0, 1, "Column 1" , 150)
  AddGadgetColumn(0, 2, "Column 2" , 150)
  For x = 0 To 100
    AddGadgetItem(0, x, "Item Item item item item item "+Str(x)+Chr(10)+"Item "+Str(x)+Chr(10)+"Item Item item item item item "+Str(x))
  Next
  SetGadgetFont(0,FontID(0))
  ButtonGadget(1,10,270,70,20,"Use Header")
  ButtonGadget(2,100,270,70,20,"Use Column")

EndIf
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          AUTOSIZE_USEHEADER(0,0)
          
        Case 2
          AUTOSIZE_USECOLUMN(0,0)
          
      EndSelect
  EndSelect
Until Quit = 1


Re: Autosize ListIconGadget headings based on heading length?

Posted: Sun Apr 14, 2024 6:43 pm
by Michael Vogel
Hm, time for continuing this thread?

Was wondering if AutoSize_UseColumn could be speeded up a little bit (see line with '***'), everything else is original Rashad code. :wink:

Code: Select all

Procedure AUTOSIZE_USEHEADER(gad,font)
	Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
	nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
	For col = 0 To ncolumns - 1
		text$ = GetGadgetItemText(gad, -1,col)
		StartDrawing(WindowOutput(0))
		DrawingFont(FontID(font))
		width = TextWidth(Text$)+12
		StopDrawing()
		SetGadgetItemAttribute(gad, -1, #PB_ListIcon_ColumnWidth, width,col)
	Next
EndProcedure
Procedure AUTOSIZE_USECOLUMN(gad,font)
	Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
	nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
	For col = 0 To ncolumns - 1
		width = 0:oldwidth = 0
		newwidth=0
		For item = 0 To CountGadgetItems(gad)
			text$ = GetGadgetItemText(gad,item , col)
			StartDrawing(WindowOutput(0))
			DrawingFont(FontID(font))
			width = TextWidth(Text$)+12;	*** would change that to 8 ***
			StopDrawing()
			If width > newwidth; 		***
				newwidth=width;		***
			EndIf;					***
		Next
		SetGadgetItemAttribute(gad, -1, #PB_ListIcon_ColumnWidth, newwidth,col);	***
	Next
EndProcedure

LoadFont(0,"Segoe UI SemiLight",12)

If OpenWindow(0, 0, 0, 570, 305, "Header Auto Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ListIconGadget(0,10,10,550,250, "Column 0", 400,#PB_ListIcon_GridLines)

	AddGadgetColumn(0, 1, "Column 1" , 150)
	AddGadgetColumn(0, 2, "Column 2" , 150)
	For x = 0 To 100
		AddGadgetItem(0, x, "Item Item item item item item "+Str(x)+Chr(10)+"Item "+Str(x)+Chr(10)+"Item Item item item item item "+Str(x))
	Next
	SetGadgetFont(0,FontID(0))
	ButtonGadget(1,10,270,150,28,"Header length")
	ButtonGadget(2,210,270,150,28,"Column content (slow)")
	ButtonGadget(3,410,270,150,28,"Complete width")

EndIf
Repeat
	Select WaitWindowEvent()
	Case #PB_Event_CloseWindow
		Quit = 1
	Case #PB_Event_Gadget
		Select EventGadget()
		Case 1
			AUTOSIZE_USEHEADER(0,0)

		Case 2
			AUTOSIZE_USECOLUMN(0,0)

		Case 3
			SendMessage_(GadgetID(0), #LVM_SETCOLUMNWIDTH,0,#LVSCW_AUTOSIZE_USEHEADER)
			SendMessage_(GadgetID(0), #LVM_SETCOLUMNWIDTH,1,#LVSCW_AUTOSIZE_USEHEADER )
			SendMessage_(GadgetID(0), #LVM_SETCOLUMNWIDTH,2,#LVSCW_AUTOSIZE_USEHEADER )

		EndSelect
	EndSelect
Until Quit = 1

Re: Autosize ListIconGadget headings based on heading length?

Posted: Sun Apr 14, 2024 9:27 pm
by RASHAD
Hi MV

Code: Select all

Procedure AUTOSIZE_USEHEADER(gad,font)
  Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
  nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
  For col = 0 To ncolumns - 1
    text$ = GetGadgetItemText(gad, -1,col)
    StartDrawing(WindowOutput(0))
    DrawingFont(FontID(font))
    width = TextWidth(Text$)+12
    StopDrawing()
    SetGadgetItemAttribute(gad, -1, #PB_ListIcon_ColumnWidth, width,col)
  Next
EndProcedure

Procedure AUTOSIZE_USECOLUMN(gad,font)
  Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
  nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
  For col = 0 To ncolumns - 1
    width = 0:oldwidth = 0
    newwidth=0
    For item = 0 To CountGadgetItems(gad)
      text$ = GetGadgetItemText(gad,item , col)
      StartDrawing(WindowOutput(0))
      DrawingFont(FontID(font))
      width = TextWidth(Text$)+12;	*** would change that to 8 ***
      StopDrawing()
      If width > newwidth; 		***
        newwidth=width   ;		***
      EndIf              ;					***
    Next
    SetGadgetItemAttribute(gad, -1, #PB_ListIcon_ColumnWidth, newwidth,col);	***
  Next
EndProcedure

Procedure Full_AUTOSIZE(gad,font,fontname$,fontsize)
  LoadFont(font,fontname$,fontsize)
  SetGadgetFont(gad,FontID(font))
  Header = SendMessage_(GadgetID(gad), #LVM_GETHEADER, 0, 0)
  nColumns = SendMessage_(Header,  #HDM_GETITEMCOUNT, 0, 0)
  For col = 0 To ncolumns - 1
    SendMessage_(GadgetID(gad), #LVM_SETCOLUMNWIDTH, col,#LVSCW_AUTOSIZE_USEHEADER & #LVSCW_AUTOSIZE)
  Next
EndProcedure

LoadFont(0,"Segoe UI SemiLight",12)

If OpenWindow(0, 0, 0, 570, 305, "Header Auto Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0,10,10,550,250, "Column 0", 150,#PB_ListIcon_GridLines)
  
  AddGadgetColumn(0, 1, "Column 1" , 150)
  AddGadgetColumn(0, 2, "Column 2" , 150)
  For x = 0 To 100
    AddGadgetItem(0, x, "Item Item item item item item "+Str(x)+Chr(10)+"Item "+Str(x)+Chr(10)+"Item Item item item item item "+Str(x))
  Next
  SetGadgetFont(0,FontID(0))
  ButtonGadget(1,10,270,150,28,"Header length")
  ButtonGadget(2,210,270,150,28,"Column content (slow)")
  ButtonGadget(3,410,270,150,28,"Complete width")
  
EndIf
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          AUTOSIZE_USEHEADER(0,0)
          
        Case 2
          AUTOSIZE_USECOLUMN(0,0)
          
        Case 3
          Full_AUTOSIZE(0,1,"Georgia",14)
          
      EndSelect
  EndSelect
Until Quit = 1

Re: Autosize ListIconGadget headings based on heading length?

Posted: Sun Apr 14, 2024 10:18 pm
by Fangbeast
7 years later and this is still very useful. Hello master RASHAD!!! Still hanging in there???

Re: Autosize ListIconGadget headings based on heading length?

Posted: Sun Apr 14, 2024 10:26 pm
by RASHAD
Hi Fang
Very very very glad to here from you :)
Keep in touch from time to time it makes me happy to read from you

Re: Autosize ListIconGadget headings based on heading length?

Posted: Mon Apr 15, 2024 12:52 am
by Fangbeast
RASHAD I tried to a few times but you have PM off and I didn't want to reply in the forum and fill it with my waffle:):)