Mercurial > foo_out_sdl
comparison foosdk/sdk/libPPUI/CListControl.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 // ================================================================================ | |
| 4 // Main CListControl implementation | |
| 5 // | |
| 6 // For ready-to-use CListControl specializations, | |
| 7 // see CListControlSimple.h and CListControlOwnerData.h | |
| 8 // ================================================================================ | |
| 9 | |
| 10 | |
| 11 #pragma comment(lib, "uxtheme.lib") | |
| 12 | |
| 13 #include <functional> | |
| 14 #include <list> | |
| 15 #include <vector> | |
| 16 #include <set> | |
| 17 #include <string> | |
| 18 #include <map> | |
| 19 #include "CMiddleDragImpl.h" | |
| 20 #include "wtl-pp.h" | |
| 21 #include "gesture.h" | |
| 22 #include "gdiplus_helpers.h" | |
| 23 | |
| 24 #define CListControl_ScrollWindowFix | |
| 25 | |
| 26 #ifdef CListControl_ScrollWindowFix | |
| 27 #define WS_EX_COMPOSITED_CListControl 0 | |
| 28 #else | |
| 29 #define WS_EX_COMPOSITED_CListControl WS_EX_COMPOSITED | |
| 30 #endif | |
| 31 | |
| 32 | |
| 33 typedef std::function< bool ( UINT, DWORD, CPoint ) > CaptureProc_t; | |
| 34 | |
| 35 typedef CWinTraits<WS_VSCROLL | WS_HSCROLL | WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_COMPOSITED_CListControl> CListControlTraits; | |
| 36 | |
| 37 class CListControlImpl : public CWindowImpl<CListControlImpl,CWindow,CListControlTraits> { | |
| 38 public: | |
| 39 typedef uint64_t groupID_t; | |
| 40 | |
| 41 CListControlImpl() {} | |
| 42 | |
| 43 static const wchar_t* GetWndClassName() { return L"libPPUI:CListControl"; } | |
| 44 DECLARE_WND_CLASS_EX(GetWndClassName(), CS_DBLCLKS, (-1)); | |
| 45 | |
| 46 // Wrapper around CWindowImpl::Create(). | |
| 47 // Creates CListControl replacing another dialog control with the specified ID. | |
| 48 // Note that m_dlgWantEnter is set to false by this method, as it's typically unwanted in dialogs. | |
| 49 HWND CreateInDialog( CWindow wndDialog, UINT replaceControlID ); | |
| 50 HWND CreateInDialog(CWindow wndDialog, UINT replaceControlID, CWindow wndReplace); | |
| 51 | |
| 52 enum { | |
| 53 MSG_SIZE_ASYNC = WM_USER + 13, | |
| 54 MSG_EXEC_DEFERRED, | |
| 55 UserMsgBase | |
| 56 }; | |
| 57 static UINT msgSetDarkMode(); | |
| 58 const UINT MSG_SET_DARK = msgSetDarkMode(); | |
| 59 | |
| 60 static void wndSetDarkMode(CWindow wndListControl, bool bDark); | |
| 61 | |
| 62 BEGIN_MSG_MAP_EX(CListControlImpl) | |
| 63 MESSAGE_HANDLER_EX(MSG_EXEC_DEFERRED, OnExecDeferred); | |
| 64 MSG_WM_PAINT(OnPaint) | |
| 65 MSG_WM_PRINTCLIENT(OnPrintClient); | |
| 66 MESSAGE_HANDLER(WM_VSCROLL,OnVScroll); | |
| 67 MESSAGE_HANDLER(WM_HSCROLL,OnHScroll); | |
| 68 MESSAGE_HANDLER(WM_SIZE,OnSize); | |
| 69 MESSAGE_HANDLER(WM_MOUSEHWHEEL,OnHWheel); | |
| 70 MESSAGE_HANDLER(WM_MOUSEWHEEL,OnVWheel); | |
| 71 MESSAGE_HANDLER(WM_LBUTTONDOWN,SetFocusPassThru); | |
| 72 MESSAGE_HANDLER(WM_RBUTTONDOWN,SetFocusPassThru); | |
| 73 MESSAGE_HANDLER(WM_MBUTTONDOWN,SetFocusPassThru); | |
| 74 MESSAGE_HANDLER(WM_LBUTTONDBLCLK,SetFocusPassThru); | |
| 75 MESSAGE_HANDLER(WM_RBUTTONDBLCLK,SetFocusPassThru); | |
| 76 MESSAGE_HANDLER(WM_MBUTTONDBLCLK,SetFocusPassThru); | |
| 77 MESSAGE_HANDLER(WM_CREATE,OnCreatePassThru); | |
| 78 MSG_WM_ERASEBKGND(OnEraseBkgnd) | |
| 79 MESSAGE_HANDLER(MSG_SIZE_ASYNC,OnSizeAsync); | |
| 80 MESSAGE_HANDLER(WM_GESTURE, OnGesture) | |
| 81 MSG_WM_THEMECHANGED(OnThemeChanged) | |
| 82 MESSAGE_HANDLER_EX( WM_GETDLGCODE, OnGetDlgCode ) | |
| 83 MESSAGE_HANDLER_EX( MSG_SET_DARK, OnSetDark ) | |
| 84 MSG_WM_KEYDOWN(OnKeyDown) | |
| 85 END_MSG_MAP() | |
| 86 | |
| 87 virtual void ReloadData(); | |
| 88 virtual void ReloadItems(pfc::bit_array const & mask); | |
| 89 | |
| 90 //! Hookable function called in response to reordering of items. Redraws the view and updates internal data to reflect the change. | |
| 91 virtual void OnItemsReordered( const size_t * order, size_t count ); | |
| 92 //! Hookable function called in response to removal of items. Redraws the view and updates internal data to reflect the change. | |
| 93 virtual void OnItemsRemoved(pfc::bit_array const& mask, size_t oldCount) { (void)mask; (void)oldCount; ReloadData(); } | |
| 94 //! Hookable function called in response to insertion of items. Redraws the view and updates internal data to reflect the change. | |
| 95 virtual void OnItemsInsertedEx(pfc::bit_array const& mask, size_t oldCount, size_t newCount, bool bSelect) { (void)mask; (void)oldCount; (void) newCount; (void)bSelect; ReloadData(); } | |
| 96 void OnItemsInserted(size_t at, size_t count, bool bSelect); | |
| 97 | |
| 98 //! Helper around OnItemsRemoved() | |
| 99 void OnItemRemoved(size_t which); | |
| 100 | |
| 101 void ReloadItem(size_t i) { ReloadItems( pfc::bit_array_one(i) ); } | |
| 102 void OnViewAreaChanged() {OnViewAreaChanged(GetViewOrigin());} | |
| 103 void OnViewAreaChanged(CPoint p_originOverride); | |
| 104 void UpdateGroupHeader2(size_t atItem); | |
| 105 void UpdateItems(const pfc::bit_array & p_mask); | |
| 106 void UpdateItemsAndHeaders(const pfc::bit_array & p_mask); | |
| 107 void UpdateItem(t_size p_item) {UpdateItems(pfc::bit_array_one(p_item));} | |
| 108 void UpdateItemsAll() {Invalidate();} | |
| 109 void EnsureItemVisible(t_size p_item, bool bUser = false); | |
| 110 void EnsureHeaderVisible2(size_t atItem); | |
| 111 virtual void EnsureVisibleRectAbs(const CRect & p_rect); | |
| 112 CRect GetItemRect(t_size p_item) const; | |
| 113 bool GetGroupHeaderRect2(size_t atItem,CRect & p_rect) const; | |
| 114 CRect GetItemRectAbs(t_size p_item) const; | |
| 115 int GetItemOffsetAbs(size_t item) const; | |
| 116 int GetItemOffsetAbs2(size_t from, size_t to) const; | |
| 117 int GetItemBottomOffsetAbs(size_t item) const; | |
| 118 int GetItemHeightCached(size_t item) const; | |
| 119 int GetItemContentHeightCached(size_t item) const; | |
| 120 bool GetGroupHeaderRectAbs2(size_t atItem,CRect & p_rect) const; | |
| 121 CPoint GetViewOrigin() const {return m_viewOrigin;} | |
| 122 CPoint GetViewOffset() const {return GetViewOrigin() - GetClientOrigin();} | |
| 123 CPoint PointAbsToClient(CPoint pt) const; | |
| 124 CPoint PointClientToAbs(CPoint pt) const; | |
| 125 CRect RectAbsToClient(CRect rc) const; | |
| 126 CRect RectClientToAbs(CRect rc) const; | |
| 127 int GetViewAreaWidth() const {return GetItemWidth();} | |
| 128 int GetViewAreaHeight() const; | |
| 129 CRect GetViewAreaRectAbs() const; | |
| 130 CRect GetViewAreaRect() const; | |
| 131 CRect GetValidViewOriginArea() const; | |
| 132 bool GetItemRangeAbs(const CRect & p_rect,t_size & p_base,t_size & p_count) const; | |
| 133 bool GetItemRangeAbsInclHeaders(const CRect & p_rect,t_size & p_base,t_size & p_count) const; | |
| 134 bool GetItemRange(const CRect & p_rect,t_size & p_base,t_size & p_count) const; | |
| 135 void MoveViewOriginNoClip(CPoint p_target); | |
| 136 void MoveViewOrigin(CPoint p_target); | |
| 137 CPoint ClipViewOrigin(CPoint p_origin) const; | |
| 138 void MoveViewOriginDelta(CPoint p_delta) {MoveViewOrigin( GetViewOrigin() + p_delta );} | |
| 139 void MoveViewOriginDeltaNoClip(CPoint p_delta) {MoveViewOriginNoClip( GetViewOrigin() + p_delta );} | |
| 140 bool ItemFromPoint(CPoint const & p_pt, t_size & p_item) const; | |
| 141 size_t ItemFromPoint(CPoint const& pt) const; | |
| 142 bool GroupHeaderFromPoint2(CPoint const & p_pt,size_t & p_atItem) const {return GroupHeaderFromPointAbs2( PointClientToAbs(p_pt),p_atItem);} | |
| 143 bool ItemFromPointAbs(CPoint const & p_pt,t_size & p_item) const; | |
| 144 size_t ItemFromPointAbs(CPoint const& p_pt) const; | |
| 145 bool GroupHeaderFromPointAbs2(CPoint const & p_pt,size_t & p_atItem) const; | |
| 146 size_t IndexFromPointAbs(CPoint pt) const; | |
| 147 size_t IndexFromPointAbs(int ptY) const; | |
| 148 | |
| 149 size_t ResolveGroupRange2(t_size p_base) const; | |
| 150 bool ResolveGroupRangeCached(size_t itemInGroup, size_t & outBegin, size_t & outEnd) const; | |
| 151 | |
| 152 virtual int GetGroupHeaderHeight() const {return 0;} | |
| 153 virtual int GetItemHeight() const {return 0;} | |
| 154 | |
| 155 // Variable height items - return -1 to use generic. | |
| 156 // This is intended to be used scarcely. Layout engine assumes that majority of items use the generic height. | |
| 157 // Heavy use of variable height items on large data sets will lead to performance issues. | |
| 158 virtual int GetItemHeight2(size_t which) const; | |
| 159 | |
| 160 // Companion to GetItemHeight2(), returns portion of GetItemHeight2()-defined item which the item content actually occupies | |
| 161 virtual int GetItemHeight2Content(size_t which, int iHeight) const { (void)which; return iHeight; } | |
| 162 | |
| 163 virtual int GetMinGroupHeight() const { return 0; } | |
| 164 virtual int GetMinGroupHeight2(size_t itemInGroup) const { (void)itemInGroup; return GetMinGroupHeight(); } | |
| 165 void MinGroupHeight2Changed(size_t itemInGroup, bool reloadWhole = false); | |
| 166 void MinGroupHeight2ChangedForGroup(groupID_t group, bool reloadWhole = false); | |
| 167 virtual int GetItemWidth() const {return 0;} | |
| 168 virtual t_size GetItemCount() const {return 0;} | |
| 169 | |
| 170 bool IsItemFirstInGroupCached(size_t item) const; | |
| 171 bool IsItemFirstInGroup(size_t item) const; | |
| 172 bool IsItemLastInGroup(size_t item) const; | |
| 173 | |
| 174 virtual groupID_t GetItemGroup(t_size p_item) const { (void)p_item; return 0; } | |
| 175 | |
| 176 virtual void RenderRect(const CRect& p_rect, CDCHandle p_dc); | |
| 177 //override optionally | |
| 178 virtual void RenderItem(t_size p_item,const CRect & p_itemRect,const CRect & p_updateRect,CDCHandle p_dc); | |
| 179 //override optionally | |
| 180 virtual void RenderGroupHeader2(size_t p_item,const CRect & p_headerRect,const CRect & p_updateRect,CDCHandle p_dc); | |
| 181 | |
| 182 virtual void RenderGroupOverlay(size_t baseItem, const CRect& p_groupWhole, const CRect& p_updateRect, CDCHandle p_dc) { (void)baseItem; (void)p_groupWhole; (void)p_updateRect; (void)p_dc; } | |
| 183 void UpdateGroupOverlayByID(groupID_t groupID, int xFrom = 0, int xTo = -1); | |
| 184 bool GetGroupOverlayRectAbs(size_t atItem, CRect & outRect); | |
| 185 | |
| 186 //called by default RenderItem implementation | |
| 187 virtual void RenderItemText(t_size p_item, const CRect& p_itemRect, const CRect& p_updateRect, CDCHandle p_dc, bool allowColors) { (void)p_item; (void)p_itemRect; (void)p_updateRect; (void)p_dc; (void)allowColors; } | |
| 188 //called by default RenderItem implementation | |
| 189 virtual void RenderGroupHeaderText2(size_t p_item, const CRect& p_headerRect, const CRect& p_updateRect, CDCHandle p_dc) { (void)p_item; (void)p_headerRect; (void)p_updateRect; (void)p_dc; } | |
| 190 | |
| 191 virtual void RenderItemBackground(CDCHandle p_dc,const CRect & p_itemRect,size_t item, uint32_t bkColor); | |
| 192 virtual void RenderGroupHeaderBackground(CDCHandle p_dc,const CRect & p_headerRect,int iGroup); | |
| 193 | |
| 194 virtual void RenderBackground( CDCHandle dc, CRect const & rc ); | |
| 195 | |
| 196 virtual void OnViewOriginChange(CPoint p_delta) { (void)p_delta; } | |
| 197 | |
| 198 // RenderOverlay2 takes rect in client coords, not absolute | |
| 199 // p_dc operates on client coords also | |
| 200 virtual void RenderOverlay2(const CRect& p_updaterect, CDCHandle p_dc) { (void)p_updaterect; (void)p_dc; } | |
| 201 | |
| 202 virtual bool FixedOverlayPresent() {return false;} | |
| 203 | |
| 204 virtual CRect GetClientRectHook() const; | |
| 205 | |
| 206 enum { | |
| 207 colorText = COLOR_WINDOWTEXT, | |
| 208 colorBackground = COLOR_WINDOW, | |
| 209 colorHighlight = COLOR_HOTLIGHT, | |
| 210 colorSelection = COLOR_HIGHLIGHT, | |
| 211 }; | |
| 212 | |
| 213 virtual COLORREF GetSysColorHook( int colorIndex ) const; | |
| 214 | |
| 215 //! Called by CListControlWithSelectionBase. | |
| 216 virtual void OnItemClicked(t_size item, CPoint pt) { (void)item; (void)pt; } | |
| 217 //! Called by CListControlWithSelectionBase. | |
| 218 virtual void OnGroupHeaderClicked(groupID_t groupId, CPoint pt) { (void)groupId; (void)pt; } | |
| 219 | |
| 220 //! Return true to indicate that some area of the control has a special purpose and clicks there should not trigger changes in focus/selection. | |
| 221 virtual bool OnClickedSpecialHitTest(CPoint pt) { (void)pt; return false; } | |
| 222 virtual bool OnClickedSpecial(DWORD status, CPoint pt) { (void)status; (void)pt; return false; } | |
| 223 | |
| 224 virtual bool AllowScrollbar(bool vertical) const { (void)vertical; return true; } | |
| 225 | |
| 226 CPoint GetClientOrigin() const {return GetClientRectHook().TopLeft();} | |
| 227 int GetVisibleHeight() const { return GetClientRectHook().Height(); } | |
| 228 | |
| 229 bool IsItemVisible(size_t which) const; | |
| 230 //! Returns first visible item, first invisible item, begin-end style | |
| 231 std::pair<size_t, size_t> GetVisibleRange() const; | |
| 232 CRect GetVisibleRectAbs() const { | |
| 233 return this->RectClientToAbs(GetClientRectHook()); | |
| 234 } | |
| 235 | |
| 236 bool IsSameItemOrHeaderAbs(const CPoint & p_point1, const CPoint & p_point2) const; | |
| 237 | |
| 238 void AddItemToUpdateRgn(HRGN p_rgn, t_size p_index) const; | |
| 239 void AddGroupHeaderToUpdateRgn2(HRGN p_rgn, size_t atItem) const; | |
| 240 | |
| 241 t_size InsertIndexFromPoint(const CPoint & p_pt) const; | |
| 242 //! Translate point to insert location for drag and drop. \n | |
| 243 //! Made virtual so it can be specialized to allow only specific drop locations. | |
| 244 virtual t_size InsertIndexFromPointEx(const CPoint & pt, bool & bInside) const; | |
| 245 | |
| 246 virtual void ListHandleResize(); | |
| 247 | |
| 248 //! Can smooth-scroll *now* ? Used to suppress smooth scroll on temporary basis due to specific user operations in progress | |
| 249 virtual bool CanSmoothScroll() const { return true; } | |
| 250 //! Is smooth scroll enabled by user? | |
| 251 virtual bool UserEnabledSmoothScroll() const; | |
| 252 virtual bool ToggleSelectedItemsHook(pfc::bit_array const& mask) { (void)mask; return false; } | |
| 253 | |
| 254 | |
| 255 SIZE GetDPI() const { return this->m_dpi;} | |
| 256 | |
| 257 // Should this control take enter key in dialogs or not? | |
| 258 // Default to true for compatibility with existing code - but when used in dialogs, you'll want it set to false to hit [OK] with enter. | |
| 259 // Note that CreateInDialog() sets this to false. Change it later if you want enter key presses to reach this control in a dialog. | |
| 260 bool m_dlgWantEnter = true; | |
| 261 | |
| 262 bool WantReturn() const { return m_dlgWantEnter; } | |
| 263 void SetWantReturn(bool v) { m_dlgWantEnter = v; } | |
| 264 | |
| 265 enum { | |
| 266 rowStyleGrid = 0, | |
| 267 rowStyleFlat, | |
| 268 rowStylePlaylist, | |
| 269 rowStylePlaylistDelimited, | |
| 270 | |
| 271 | |
| 272 rowStyleDefault = rowStylePlaylistDelimited | |
| 273 }; | |
| 274 void SetPlaylistStyle() {SetRowStyle(rowStylePlaylist);} | |
| 275 void SetRowStyle(unsigned v) { if (m_rowStyle == v) return; this->m_rowStyle = v; if (m_hWnd) Invalidate(); } | |
| 276 void SetFlatStyle() {SetRowStyle(rowStyleFlat);} | |
| 277 unsigned m_rowStyle = rowStyleDefault; | |
| 278 bool DelimitColumns() const { return m_rowStyle == rowStyleGrid || m_rowStyle == rowStylePlaylistDelimited; } | |
| 279 | |
| 280 static COLORREF BlendGridColor( COLORREF bk, COLORREF tx ); | |
| 281 static COLORREF BlendGridColor( COLORREF bk ); | |
| 282 COLORREF GridColor(); | |
| 283 | |
| 284 void SetDarkMode(bool bDark); | |
| 285 virtual void RefreshDarkMode(); | |
| 286 bool GetDarkMode() const { return m_darkMode; } | |
| 287 private: | |
| 288 void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); | |
| 289 LRESULT OnSetDark(UINT, WPARAM, LPARAM); | |
| 290 int HandleWheel(int & p_accum,int p_delta, bool bHoriz); | |
| 291 | |
| 292 void PaintContent(CRect rcPaint, HDC dc); | |
| 293 void OnPrintClient(HDC dc, UINT uFlags); | |
| 294 void OnPaint(CDCHandle); | |
| 295 LRESULT OnVScroll(UINT,WPARAM,LPARAM,BOOL&); | |
| 296 LRESULT OnHScroll(UINT,WPARAM,LPARAM,BOOL&); | |
| 297 LRESULT OnSize(UINT,WPARAM,LPARAM,BOOL&); | |
| 298 LRESULT OnSizeAsync(UINT,WPARAM,LPARAM,BOOL&) {ListHandleResize();return 0;} | |
| 299 LRESULT OnVWheel(UINT,WPARAM,LPARAM,BOOL&); | |
| 300 LRESULT OnHWheel(UINT,WPARAM,LPARAM,BOOL&); | |
| 301 LRESULT OnGesture(UINT,WPARAM,LPARAM,BOOL&); | |
| 302 LRESULT SetFocusPassThru(UINT,WPARAM,LPARAM,BOOL&); | |
| 303 LRESULT OnCreatePassThru(UINT,WPARAM,LPARAM,BOOL&); | |
| 304 BOOL OnEraseBkgnd(CDCHandle); | |
| 305 LRESULT OnGetDlgCode(UINT, WPARAM, LPARAM); | |
| 306 | |
| 307 void OnThemeChanged(); | |
| 308 int GetScrollThumbPos(int which); | |
| 309 void RefreshSliders(); | |
| 310 void RefreshSlider(bool p_vertical); | |
| 311 | |
| 312 void OnSizeAsync_Trigger(); | |
| 313 static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam); | |
| 314 bool MouseWheelFromHook(UINT msg, LPARAM data); | |
| 315 | |
| 316 bool m_suppressMouseWheel = false; | |
| 317 int m_wheelAccumX = 0, m_wheelAccumY = 0; | |
| 318 CPoint m_viewOrigin = CPoint(0,0); | |
| 319 bool m_sizeAsyncPending = false; | |
| 320 CPoint m_gesturePoint; | |
| 321 | |
| 322 // Prepares group header & variable height item data for view with the specified origin and current client size | |
| 323 // Returns true if layout cache has changed, false otherwise. | |
| 324 // Updates ptOrigin if necessary | |
| 325 bool PrepLayoutCache(CPoint & ptOrigin, size_t indexLo = SIZE_MAX, size_t indexHi = SIZE_MAX); | |
| 326 std::map<size_t, int> m_varItemHeights; | |
| 327 std::set<size_t> m_groupHeaders; | |
| 328 | |
| 329 size_t FindGroupBaseCached(size_t itemFor) const; | |
| 330 size_t FindGroupBase(size_t itemFor) const; | |
| 331 size_t FindGroupBase(size_t itemFor, groupID_t group) const; | |
| 332 | |
| 333 protected: | |
| 334 // Grouped layout mode toggle | |
| 335 // Default mode is greedy, probes whole list layout in advance (no glitches when scrolling) | |
| 336 // In special conditions when probing is expensive, greedy mode should be turned off | |
| 337 bool m_greedyGroupLayout = true; | |
| 338 | |
| 339 pfc::map_t<pfc::string8, CTheme, pfc::comparator_strcmp> m_themeCache; | |
| 340 CTheme & themeFor( const char * what ); | |
| 341 CTheme & theme() { return themeFor("LISTVIEW");} | |
| 342 | |
| 343 const SIZE m_dpi = QueryScreenDPIEx(); | |
| 344 CGestureAPI m_gestureAPI; | |
| 345 bool m_ensureVisibleUser = false; | |
| 346 | |
| 347 void defer( std::function<void () > f ); | |
| 348 LRESULT OnExecDeferred(UINT, WPARAM, LPARAM); | |
| 349 | |
| 350 // Overlays our stuff on top of generic DoDragDrop call. | |
| 351 // Currently catches mouse wheel messages in mid-drag&drop and handles them in our view. | |
| 352 HRESULT DoDragDrop(LPDATAOBJECT pDataObj, LPDROPSOURCE pDropSource, DWORD dwOKEffects, LPDWORD pdwEffect); | |
| 353 | |
| 354 bool paintInProgress() const { return m_paintInProgress; } | |
| 355 private: | |
| 356 bool m_defferredMsgPending = false; | |
| 357 std::list<std::function<void ()> > m_deferred; | |
| 358 bool m_darkMode = false; | |
| 359 | |
| 360 bool m_paintInProgress = false; | |
| 361 }; | |
| 362 | |
| 363 class CListControlFontOps : public CListControlImpl { | |
| 364 private: | |
| 365 typedef CListControlImpl TParent; | |
| 366 public: | |
| 367 CListControlFontOps(); | |
| 368 BEGIN_MSG_MAP_EX(CListControlFontOps) | |
| 369 MESSAGE_HANDLER(WM_GETFONT,OnGetFont); | |
| 370 MESSAGE_HANDLER(WM_SETFONT,OnSetFont); | |
| 371 CHAIN_MSG_MAP(TParent); | |
| 372 END_MSG_MAP() | |
| 373 CFontHandle GetFont() const { return m_font; } | |
| 374 void SetFont(HFONT font, bool bUpdateView = true); | |
| 375 protected: | |
| 376 CFontHandle GetGroupHeaderFont() const {return (HFONT)m_groupHeaderFont;} | |
| 377 virtual double GroupHeaderFontScale() const { return 1.25; } | |
| 378 virtual int GroupHeaderFontWeight(int origVal) const { | |
| 379 //return pfc::min_t<int>(FW_BLACK, origVal + 200); | |
| 380 return origVal; | |
| 381 } | |
| 382 | |
| 383 //! Overridden implementations should always forward the call to the base class. | |
| 384 virtual void OnSetFont(bool bUpdatingView) { (void)bUpdatingView; } | |
| 385 | |
| 386 int GetGroupHeaderHeight() const override {return m_groupHeaderHeight;} | |
| 387 int GetItemHeight() const override {return m_itemHeight;} | |
| 388 | |
| 389 private: | |
| 390 LRESULT OnSetFont(UINT,WPARAM,LPARAM,BOOL&); | |
| 391 LRESULT OnGetFont(UINT,WPARAM,LPARAM,BOOL&); | |
| 392 void UpdateGroupHeaderFont(); | |
| 393 void CalculateHeights(); | |
| 394 int m_itemHeight, m_groupHeaderHeight; | |
| 395 CFontHandle m_font; | |
| 396 CFont m_groupHeaderFont; | |
| 397 }; | |
| 398 | |
| 399 #include "CListControlHeaderImpl.h" | |
| 400 #include "CListControlTruncationTooltipImpl.h" | |
| 401 | |
| 402 | |
| 403 | |
| 404 typedef CMiddleDragImpl<CListControlTruncationTooltipImpl> CListControl; | |
| 405 |
