Mercurial > foo_out_sdl
comparison foosdk/sdk/libPPUI/CListControlHeaderImpl.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 class CListCell; | |
| 4 | |
| 5 class CListControlHeaderImpl : public CListControlFontOps { | |
| 6 private: | |
| 7 typedef CListControlFontOps TParent; | |
| 8 public: | |
| 9 CListControlHeaderImpl() {} | |
| 10 | |
| 11 BEGIN_MSG_MAP_EX(CListControlHeaderImpl) | |
| 12 MSG_WM_THEMECHANGED(OnThemeChangedPT) | |
| 13 MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) | |
| 14 MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, MousePassThru); | |
| 15 MSG_WM_MOUSELEAVE(OnMouseLeave) | |
| 16 MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic); | |
| 17 MESSAGE_HANDLER(WM_KEYDOWN,OnKeyDown); | |
| 18 MESSAGE_HANDLER(WM_SYSKEYDOWN,OnKeyDown); | |
| 19 MESSAGE_HANDLER_EX(WM_SIZE,OnSizePassThru); | |
| 20 NOTIFY_CODE_HANDLER(HDN_ITEMCHANGED,OnHeaderItemChanged); | |
| 21 NOTIFY_CODE_HANDLER(HDN_ENDDRAG,OnHeaderEndDrag); | |
| 22 NOTIFY_CODE_HANDLER(HDN_ITEMCLICK,OnHeaderItemClick); | |
| 23 NOTIFY_CODE_HANDLER(HDN_DIVIDERDBLCLICK,OnDividerDoubleClick); | |
| 24 NOTIFY_CODE_HANDLER_EX(NM_CUSTOMDRAW, OnHeaderCustomDraw); | |
| 25 MSG_WM_SETCURSOR(OnSetCursor); | |
| 26 MSG_WM_MOUSEMOVE(OnMouseMove) | |
| 27 MSG_WM_DESTROY(OnDestroy) | |
| 28 MSG_WM_ENABLE(OnEnable) | |
| 29 MSG_WM_KILLFOCUS(OnKillFocus) | |
| 30 MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged) | |
| 31 CHAIN_MSG_MAP(TParent) | |
| 32 END_MSG_MAP() | |
| 33 | |
| 34 typedef uint32_t cellState_t; | |
| 35 typedef CListCell * cellType_t; | |
| 36 | |
| 37 int GetHeaderItemWidth( int which ); | |
| 38 void InitializeHeaderCtrl(DWORD flags = HDS_FULLDRAG); | |
| 39 void InitializeHeaderCtrlSortable() {InitializeHeaderCtrl(HDS_FULLDRAG | HDS_BUTTONS);} | |
| 40 CHeaderCtrl GetHeaderCtrl() const {return m_header;} | |
| 41 void SetSortIndicator( size_t whichColumn, bool isUp ); | |
| 42 void ClearSortIndicator(); | |
| 43 | |
| 44 bool IsHeaderEnabled() const {return m_header.m_hWnd != NULL;} | |
| 45 void ResetColumns(bool update = true); | |
| 46 | |
| 47 static constexpr uint32_t columnWidthMax = (uint32_t)INT32_MAX, | |
| 48 columnWidthAuto = UINT32_MAX, | |
| 49 columnWidthAutoUseContent = UINT32_MAX - 1; | |
| 50 | |
| 51 void AddColumn(const char * label, uint32_t widthPixels, DWORD fmtFlags = HDF_LEFT,bool update = true); | |
| 52 //! Extended AddColumn, specifies width in pixels @ 96DPI instead of screen-specific pixels | |
| 53 void AddColumnEx( const char * label, uint32_t widthPixelsAt96DPI, DWORD fmtFlags = HDF_LEFT, bool update = true ); | |
| 54 //! Extended AddColumn, specifies width in Dialog Length Units (DLU), assumes parent of this list to be a dialog window. | |
| 55 void AddColumnDLU( const char * label, uint32_t widthDLU, DWORD fmtFlags = HDF_LEFT, bool update = true ); | |
| 56 //! Extended AddColumn, specifies width as floating-point value of pixels at 96DPI. \n | |
| 57 //! For DPI-safe storage of user's column widths. | |
| 58 void AddColumnF( const char * label, float widthF, DWORD fmtFlags = HDF_LEFT, bool update = true ); | |
| 59 void AddColumnAutoWidth( const char * label, DWORD fmtFlags = HDF_LEFT, bool bUpdate = true) { AddColumn(label, columnWidthAuto, fmtFlags, bUpdate); } | |
| 60 bool DeleteColumn(size_t index, bool updateView = true); | |
| 61 void DeleteColumns( pfc::bit_array const & mask, bool updateView = true); | |
| 62 void ResizeColumn(t_size index, t_uint32 widthPixels, bool updateView = true); | |
| 63 void SetColumn( size_t which, const char * title, DWORD fmtFlags = HDF_LEFT, bool updateView = true); | |
| 64 void GetColumnText(size_t which, pfc::string_base & out) const; | |
| 65 | |
| 66 uint32_t GetOptimalColumnWidth( size_t index ) const; | |
| 67 uint32_t GetOptimalColumnWidthFixed( const char * fixedText, bool pad = true) const; | |
| 68 uint32_t GetColumnsBlankWidth( size_t colExclude = SIZE_MAX ) const; | |
| 69 void SizeColumnToContent( size_t which, uint32_t minWidth ); | |
| 70 void SizeColumnToContentFillBlank( size_t which ); | |
| 71 | |
| 72 //! If creating a custom headerless multi column scheme, override these to manipulate your columns | |
| 73 virtual size_t GetColumnCount() const; | |
| 74 virtual uint32_t GetSubItemWidth(size_t subItem) const; | |
| 75 //! Returns column width as a floating-point value of pixels at 96DPI. \n | |
| 76 //! For DPI-safe storage of user's column widths. | |
| 77 float GetColumnWidthF( size_t subItem ) const; | |
| 78 //! Indicate how many columns a specific row/column cell spans\n | |
| 79 //! This makes sense only if the columns can't be user-reordered | |
| 80 virtual size_t GetSubItemSpan(size_t row, size_t column) const; | |
| 81 | |
| 82 t_size GetSubItemOrder(t_size subItem) const; | |
| 83 int GetItemWidth() const override; | |
| 84 | |
| 85 void SetHeaderFont(HFONT font); | |
| 86 protected: | |
| 87 CRect GetClientRectHook() const override; | |
| 88 void RenderBackground(CDCHandle dc, CRect const& rc) override; | |
| 89 | |
| 90 struct GetOptimalWidth_Cache { | |
| 91 //! For temporary use. | |
| 92 pfc::string8_fastalloc m_stringTemp, m_stringTempFixAmpersands; | |
| 93 //! For temporary use. | |
| 94 pfc::stringcvt::string_wide_from_utf8_t<pfc::alloc_fast_aggressive> m_convertTemp; | |
| 95 //! Our DC for measuring text. Correct font pre-selected. | |
| 96 CDCHandle m_dc; | |
| 97 | |
| 98 t_uint32 GetStringTempWidth(); | |
| 99 }; | |
| 100 | |
| 101 void UpdateHeaderLayout(); | |
| 102 void OnViewOriginChange(CPoint p_delta) override; | |
| 103 void RenderItemText(t_size item,const CRect & itemRect,const CRect & updateRect,CDCHandle dc, bool allowColors) override; | |
| 104 void RenderGroupHeaderText2(size_t baseItem,const CRect & headerRect,const CRect & updateRect,CDCHandle dc) override; | |
| 105 void RenderGroupOverlay(size_t baseItem, const CRect& p_groupWhole, const CRect& p_updateRect, CDCHandle p_dc) override; | |
| 106 void UpdateGroupOverlayColumnByID(groupID_t groupID, size_t subItem); | |
| 107 | |
| 108 //! Converts an item/subitem rect to a rect in which the text should be rendered, removing spacing to the left/right of the text. | |
| 109 virtual CRect GetItemTextRectHook(size_t item, size_t subItem, CRect const & itemRect) const; | |
| 110 CRect GetItemTextRect(CRect const & itemRect) const; | |
| 111 //! Override for custom spacing to the left/right of the text in each column. | |
| 112 virtual t_uint32 GetColumnSpacing() const {return MulDiv(4,m_dpi.cx,96);} | |
| 113 //! Override for column-header-click sorting. | |
| 114 virtual void OnColumnHeaderClick(t_size index) { (void)index; } | |
| 115 //! Override to supply item labels. | |
| 116 virtual bool GetSubItemText(t_size item, t_size subItem, pfc::string_base& out) const { (void)item; (void)subItem; (void)out; return false; } | |
| 117 //! Override if you support groups. | |
| 118 virtual bool GetGroupHeaderText2(size_t baseItem, pfc::string_base& out) const { (void)baseItem; (void)out; return false; } | |
| 119 //! Override optionally. | |
| 120 virtual void RenderSubItemText(t_size item, t_size subItem,const CRect & subItemRect,const CRect & updateRect,CDCHandle dc, bool allowColors); | |
| 121 virtual void RenderGroupOverlayColumn(size_t baseItem, size_t subItem, const CRect& p_groupWhole, const CRect& p_updateRect, CDCHandle p_dc) { (void)baseItem; (void)subItem; (void)p_groupWhole; (void)p_updateRect; (void)p_dc; } | |
| 122 | |
| 123 virtual void OnColumnsChanged(); | |
| 124 | |
| 125 virtual t_uint32 GetOptimalSubItemWidth(t_size item, t_size subItem, GetOptimalWidth_Cache & cache) const; | |
| 126 | |
| 127 virtual t_uint32 GetOptimalGroupHeaderWidth2(size_t baseItem) const; | |
| 128 | |
| 129 | |
| 130 bool GetItemAtPointAbsEx( CPoint pt, size_t & outItem, size_t & outSubItem ) const; | |
| 131 cellType_t GetCellTypeAtPointAbs( CPoint pt ) const; | |
| 132 virtual cellType_t GetCellType( size_t item, size_t subItem ) const; | |
| 133 virtual bool AllowTypeFindInCell( size_t item, size_t subItem ) const; | |
| 134 virtual bool GetCellTypeSupported() const { return false; } // optimization hint, some expensive checks can be suppressed if cell types are not used for this view | |
| 135 virtual bool GetCellCheckState(size_t item, size_t subItem) const { (void)item; (void)subItem; return false; } | |
| 136 virtual void SetCellCheckState(size_t item, size_t subItem, bool value); | |
| 137 virtual bool ToggleSelectedItemsHook(const pfc::bit_array & mask) override; | |
| 138 | |
| 139 virtual bool RenderCellImageTest(size_t item, size_t subItem) const { (void)item; (void)subItem; return false; } | |
| 140 virtual void RenderCellImage(size_t item, size_t subItem, CDCHandle, const CRect&) const { (void)item; (void)subItem; } | |
| 141 | |
| 142 t_uint32 GetOptimalColumnWidth(t_size which, GetOptimalWidth_Cache & cache) const; | |
| 143 t_uint32 GetOptimalSubItemWidthSimple(t_size item, t_size subItem) const; | |
| 144 | |
| 145 void AutoColumnWidths(const pfc::bit_array & mask,bool expandLast = false); | |
| 146 void AutoColumnWidths() {AutoColumnWidths(pfc::bit_array_true());} | |
| 147 void AutoColumnWidth(t_size which) {AutoColumnWidths(pfc::bit_array_one(which));} | |
| 148 | |
| 149 virtual bool OnColumnHeaderDrag(t_size index, t_size newOrder); | |
| 150 | |
| 151 void OnItemClicked(t_size item, CPoint pt) override; | |
| 152 virtual void OnSubItemClicked(t_size item, t_size subItem,CPoint pt); | |
| 153 bool OnClickedSpecialHitTest(CPoint pt) override; | |
| 154 bool OnClickedSpecial(DWORD status, CPoint pt) override; | |
| 155 static bool CellTypeUsesSpecialHitTests( cellType_t ct ); | |
| 156 | |
| 157 | |
| 158 CRect GetSubItemRectAbs(t_size item,t_size subItem) const; | |
| 159 CRect GetSubItemRect(t_size item,t_size subItem) const; | |
| 160 | |
| 161 t_size SubItemFromPointAbs(CPoint pt) const; | |
| 162 | |
| 163 static bool CellTypeReactsToMouseOver( cellType_t ct ); | |
| 164 virtual CRect CellHotRect( size_t item, size_t subItem, cellType_t ct, CRect rcCell ); | |
| 165 CRect CellHotRect( size_t item, size_t subItem, cellType_t ct ); | |
| 166 virtual double CellTextScale(size_t item, size_t subItem) { (void)item; (void)subItem; return 1; } | |
| 167 virtual bool IsSubItemGrayed(size_t item, size_t subItem) { (void)item; (void)subItem; return !this->IsWindowEnabled(); } | |
| 168 | |
| 169 virtual void CellTrackMouseMove(size_t item, size_t subItem, UINT msg, DWORD status, CPoint pt) { (void)item; (void)subItem; (void)msg; (void)status; (void)pt; } | |
| 170 | |
| 171 // HDF_* constants for this column, override when not using list header control. Used to control text alignment. | |
| 172 virtual DWORD GetColumnFormat(t_size which) const; | |
| 173 void SetColumnFormat(t_size which,DWORD format); | |
| 174 void SetColumnSort(t_size which, bool isUp); | |
| 175 | |
| 176 std::vector<int> GetColumnOrderArray() const; | |
| 177 | |
| 178 bool AllowScrollbar(bool vertical) const override; | |
| 179 | |
| 180 void RenderItemBackground(CDCHandle p_dc,const CRect & p_itemRect,size_t item, uint32_t bkColor) override; | |
| 181 | |
| 182 void ColumnWidthFix(); // Call RecalcItemWidth() / ProcessAutoWidth() | |
| 183 | |
| 184 void ReloadData() override; | |
| 185 | |
| 186 size_t HotItem() const { return m_hotItem; } | |
| 187 size_t HotSubItem() const { return m_hotSubItem; } | |
| 188 | |
| 189 virtual void RequestEditItem(size_t item, size_t subItem); | |
| 190 private: | |
| 191 void OnLButtonDblClk(UINT nFlags, CPoint point); | |
| 192 void OnThemeChangedPT(); | |
| 193 void OnEnable(BOOL) { Invalidate(); } | |
| 194 HBRUSH OnCtlColorStatic(CDCHandle dc, CStatic wndStatic); | |
| 195 void ProcessColumnsChange() { OnColumnsChanged();} | |
| 196 LRESULT OnSizePassThru(UINT,WPARAM,LPARAM); | |
| 197 LRESULT OnHeaderItemClick(int,LPNMHDR,BOOL&); | |
| 198 LRESULT OnHeaderCustomDraw(LPNMHDR); | |
| 199 LRESULT OnDividerDoubleClick(int,LPNMHDR,BOOL&); | |
| 200 LRESULT OnHeaderItemChanged(int,LPNMHDR,BOOL&); | |
| 201 LRESULT OnHeaderEndDrag(int,LPNMHDR,BOOL&); | |
| 202 LRESULT OnKeyDown(UINT,WPARAM,LPARAM,BOOL&); | |
| 203 void OnDestroy(); | |
| 204 BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message); | |
| 205 void OnMouseMove(UINT nFlags, CPoint point); | |
| 206 | |
| 207 void RecalcItemWidth(); // FIXED width math | |
| 208 void ProcessAutoWidth(); // DYNAMIC width math | |
| 209 | |
| 210 bool m_ownColumnsChange = false; | |
| 211 | |
| 212 int m_itemWidth = 0; | |
| 213 int m_clientWidth = 0; | |
| 214 CHeaderCtrl m_header; | |
| 215 bool m_headerDark = false; | |
| 216 CStatic m_headerLine; | |
| 217 | |
| 218 bool HaveAutoWidthColumns() const; | |
| 219 bool HaveAutoWidthContentColumns() const; | |
| 220 | |
| 221 struct colRuntime_t { | |
| 222 bool m_autoWidth = false; | |
| 223 bool m_autoWidthContent = false; | |
| 224 int m_widthPixels = 0; | |
| 225 uint32_t m_userWidth = 0; | |
| 226 std::string m_text; | |
| 227 | |
| 228 bool autoWidth() const { return m_userWidth > columnWidthMax; } | |
| 229 bool autoWidthContent() const { return m_userWidth == columnWidthAutoUseContent; } | |
| 230 bool autoWidthPlain() const { return m_userWidth == columnWidthAuto; } | |
| 231 }; | |
| 232 | |
| 233 std::vector<colRuntime_t> m_colRuntime; | |
| 234 | |
| 235 | |
| 236 //for group headers | |
| 237 GdiplusScope m_gdiPlusScope; | |
| 238 | |
| 239 void SetPressedItem(size_t row, size_t column); | |
| 240 void ClearPressedItem() {SetPressedItem(SIZE_MAX, SIZE_MAX);} | |
| 241 void SetHotItem( size_t row, size_t column ); | |
| 242 void ClearHotItem() { SetHotItem(SIZE_MAX, SIZE_MAX); } | |
| 243 | |
| 244 virtual void HotItemChanged(size_t row, size_t column) { (void)row; (void)column; } | |
| 245 virtual void PressedItemChanged(size_t row, size_t column) { (void)row; (void)column; } | |
| 246 | |
| 247 size_t m_pressedItem = SIZE_MAX, m_pressedSubItem = SIZE_MAX; | |
| 248 size_t m_hotItem = SIZE_MAX, m_hotSubItem = SIZE_MAX; | |
| 249 | |
| 250 private: | |
| 251 // ==== mySetCapture stuff ==== | |
| 252 // SetCapture()-like functionality used for tracking of hot fields. | |
| 253 // Not a part of the API, do not reuse in subclasses. | |
| 254 void mySetCapture(CaptureProc_t proc); | |
| 255 void myReleaseCapture(); | |
| 256 | |
| 257 void TrackMouseLeave(); | |
| 258 | |
| 259 void mySetCaptureMsgHandled(BOOL v) { this->SetMsgHandled(v); } | |
| 260 CaptureProc_t m_captureProc; | |
| 261 | |
| 262 void OnMouseLeave(); | |
| 263 void OnKillFocus(CWindow); | |
| 264 void OnWindowPosChanged(LPWINDOWPOS); | |
| 265 LRESULT MousePassThru(UINT, WPARAM, LPARAM); | |
| 266 }; |
