So I thought it was time to ask another dumb question
Is it possible to force the item text of a (non editable) ComboBox to be central?
Without requiring 10 kilometers of code or a call-back?
ComboBox: How to center text?
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
ComboBox: How to center text?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: ComboBox: How to center text?
HI
You can optimize for speed by calculating gadw and width2 after creating the gadget directly(It is needed only once)
#2 :
Center text Val. & Hal.
You must take care for if the text length exceeds the gadget width
You can optimize for speed by calculating gadw and width2 after creating the gadget directly(It is needed only once)
Code: Select all
Procedure _AddGadgetItem(gad,Text$)
gadw = GadgetWidth(gad,#PB_Gadget_ActualSize) - GadgetWidth(gad,#PB_Gadget_RequiredSize)
StartDrawing(WindowOutput(0))
DrawingFont(FontID(0))
width = TextWidth(Text$)
width2 = TextWidth(" ")
StopDrawing()
trim = (gadw - width)/2/width2
text$ = Space(trim)+text$
AddGadgetItem(gad, -1,text$)
EndProcedure
LoadFont(0,"Tahoma",12)
If OpenWindow(0, 0, 0, 400, 400, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 10, 250, 24)
SetGadgetFont(0,FontID(0))
_AddGadgetItem(0,"IdeasVacuum")
_AddGadgetItem(0,"ComboBox item #!")
_AddGadgetItem(0,"RASHAD")
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Center text Val. & Hal.
You must take care for if the text length exceeds the gadget width
Code: Select all
Procedure _GetGadgetText(gad)
text$ = LTrim(GetGadgetText(gad)," ")
Debug text$
EndProcedure
Procedure _AddGadgetItem(gad,Text$)
gadw = GadgetWidth(gad,#PB_Gadget_ActualSize); - GadgetWidth(gad,#PB_Gadget_RequiredSize)
StartDrawing(WindowOutput(0))
DrawingFont(FontID(0))
width = TextWidth(Text$)
width2 = TextWidth(" ")
StopDrawing()
trim = (gadw - width)/2/width2
text$ = Space(trim)+text$
AddGadgetItem(gad, -1,text$)
EndProcedure
LoadFont(0,"Tahoma",14)
If OpenWindow(0, 0, 0, 400, 400, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 10, 250, 20)
SetGadgetFont(0,FontID(0))
StartDrawing(WindowOutput(0))
DrawingFont(FontID(0))
height = TextHeight("Q")+10
StopDrawing()
ResizeGadget(0,#PB_Ignore,#PB_Ignore,#PB_Ignore,height)
_AddGadgetItem(0,"IdeasVacuum")
_AddGadgetItem(0,"ComboBox item #!")
_AddGadgetItem(0,"RASHAD")
SetGadgetState(0,1)
ButtonGadget(1,10,370,80,25,"Get Text")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
_GetGadgetText(0)
EndSelect
EndSelect
Until Quit = 1
EndIf
Egypt my love
Re: ComboBox: How to center text?
You may also try the following example which uses Windows API functions and is therefore only usable in Windows. Unfortunately it needs a callback! I have tested it successfully in Windows 10 x64 Version 1809 with PB 5.46 x86 and x64 in ASCII and Unicode mode and with PB 5.71 x86.
Code: Select all
EnableExplicit
Procedure WindowCallback(WindowHandle.I, Message.I, WParam.I, LParam.I)
Protected Brush.I
Protected DC.I
Protected *DrawItem.DRAWITEMSTRUCT
Protected ItemText.S
Protected Result.I
Protected Size.SIZE
Protected x.I
Result = #PB_ProcessPureBasicEvents
If Message = #WM_DRAWITEM
*DrawItem = LParam
If *DrawItem\CtlType = #ODT_COMBOBOX
SetBkMode_(*DrawItem\hDC, #TRANSPARENT)
If *DrawItem\ItemState & #ODS_FOCUS
Brush = CreateSolidBrush_($FF901E)
FillRect_(*DrawItem\hDC, *DrawItem\rcItem, Brush)
DeleteObject_(Brush)
SetTextColor_(*DrawItem\hDC, $FFFFFF)
Else
FillRect_(*DrawItem\hDC, *DrawItem\rcItem,
GetStockObject_(#WHITE_BRUSH))
EndIf
If *DrawItem\itemID <> -1
ItemText = Space(128)
SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT,
*DrawItem\itemID, @ItemText)
DC = GetDC_(WindowHandle)
SelectObject_(DC, GadgetID(WParam))
GetTextExtentPoint32_(DC, @ItemText, Len(ItemText), Size)
ReleaseDC_(GadgetID(WParam), DC)
x = *DrawItem\rcItem\left +
(*DrawItem\rcItem\right - *DrawItem\rcItem\left - Size\cx) / 2
TextOut_(*DrawItem\hDC, x, *DrawItem\rcItem\top, ItemText,
Len(ItemText))
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Define i.I
OpenWindow(0, 200, 100, 270, 130, "ComboBoxGadget demo")
SetGadgetFont(#PB_Default, LoadFont(0, "Verdana", 10))
ComboBoxGadget(0, 10, 20, 120, 23)
ComboBoxGadget(1, 140, 20, 120, 23, #CBS_OWNERDRAWFIXED | #CBS_HASSTRINGS)
SetWindowCallback(@WindowCallback())
For i = 1 To 5
AddGadgetItem(0, -1, "Item " + Str(i))
AddGadgetItem(1, -1, "Item " + Str(i))
Next
SetGadgetState(0, 0)
SetGadgetState(1, 0)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ComboBox: How to center text?
Thanks for your help Shardik, Rashad.
I have used the API method before (blasted call-back ).
What I have done recently is to use a monoblock font, verified the text length, packed-out with spaces. Vertical center is done by matching the font height to the gadget height. That method mostly works and of course is a lot "lighter" than API.
I have also DIY'd a combo using a Button and a single column ListIcon for the pop-down, centered with a bit of API:
.... now I'm thinking of another DIY approach, Button with a single column HTML table - the beauty of HTML being that it is so easy to center text, and other effects such as selection highlighting etc.
I always have a generous amount of space around combobox and text buttons because other languages like German and Dutch often have longer words for the equivalent English word.
I have used the API method before (blasted call-back ).
What I have done recently is to use a monoblock font, verified the text length, packed-out with spaces. Vertical center is done by matching the font height to the gadget height. That method mostly works and of course is a lot "lighter" than API.
I have also DIY'd a combo using a Button and a single column ListIcon for the pop-down, centered with a bit of API:
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.LVCOLUMN
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
SetGadgetItemAttribute(iListIconID, 0, #PB_ListIcon_ColumnWidth, iColWidth, iCol)
SendMessage_(GadgetID(iListIconID), #LVM_SETCOLUMN, iCol, @lvc)
EndProcedure
I always have a generous amount of space around combobox and text buttons because other languages like German and Dutch often have longer words for the equivalent English word.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ComboBox: How to center text?
Well, experiments complete. For the current project, Rashad's #2 is a clear winner. HTML a close 2nd.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: ComboBox: How to center text?
Code: Select all
Procedure AddComboItem(iWin.i, iGadget.i, sText.s, iFont.i)
;#---------------------------------------------------------
Protected iGadgetW.i = GadgetWidth(iGadget, #PB_Gadget_ActualSize)
Protected iW1.i, iW2.i, iTrim.i
StartDrawing(WindowOutput(iWin))
DrawingFont(iFont)
iW1 = TextWidth(sText)
iW2 = TextWidth(" ")
StopDrawing()
iTrim = ((iGadgetW - iW1) /2 /iW2)
sText = Space(iTrim) + sText
AddGadgetItem(iGadget, -1, sText)
EndProcedure
Procedure.i ComboHeight(iWin.i, iGadget.i, iFont.i)
;#-------------------------------------------------
Protected iComboHgt.i
Protected iVertPadding.i
StartDrawing(WindowOutput(iWin))
DrawingFont(iFont)
iVertPadding = TextHeight("Q") / 2
iComboHgt = TextHeight("Q") + iVertPadding
StopDrawing()
ProcedureReturn(iComboHgt)
EndProcedure
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.