It is currently Mon Jul 06, 2020 5:27 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: ComboBox: How to center text?
PostPosted: Tue Jun 30, 2020 2:06 am 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 6244
Location: Wales, UK
So I thought it was time to ask another dumb question :shock:

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?

Image

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
Reply with quote  
 Post subject: Re: ComboBox: How to center text?
PostPosted: Tue Jun 30, 2020 3:19 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Apr 12, 2009 6:27 am
Posts: 3640
HI
You can optimize for speed by calculating gadw and width2 after creating the gadget directly(It is needed only once)

Code:
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


#2 :
Center text Val. & Hal.
You must take care for if the text length exceeds the gadget width
Code:
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


Top
 Profile  
Reply with quote  
 Post subject: Re: ComboBox: How to center text?
PostPosted: Tue Jun 30, 2020 8:07 am 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1734
Location: Germany
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:
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


Top
 Profile  
Reply with quote  
 Post subject: Re: ComboBox: How to center text?
PostPosted: Tue Jun 30, 2020 11:42 am 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 6244
Location: Wales, UK
Thanks for your help Shardik, Rashad.

I have used the API method before (blasted call-back :D).

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:
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


.... 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.

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
Reply with quote  
 Post subject: Re: ComboBox: How to center text?
PostPosted: Tue Jun 30, 2020 3:31 pm 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 6244
Location: Wales, UK
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.


Top
 Profile  
Reply with quote  
 Post subject: Re: ComboBox: How to center text?
PostPosted: Tue Jun 30, 2020 5:47 pm 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 6244
Location: Wales, UK
Code:
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.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye