annotate foosdk/sdk/foobar2000/foo_sample/listcontrol-advanced.cpp @ 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 // Advanced CListControl use demo
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 // Subclasses a CListControl to use all its features
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "stdafx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include "resource.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include <helpers/atl-misc.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #include <libPPUI/CListControlComplete.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #include <libPPUI/CListControl-Cells.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #include <string>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #include <algorithm>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 #include <vector>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 #include <helpers/DarkMode.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 struct listData_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 std::string m_key, m_value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 bool m_checkState = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 static std::vector<listData_t> makeListData() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 std::vector<listData_t> data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 data.resize( 10 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 for( size_t walk = 0; walk < data.size(); ++ walk ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 auto & rec = data[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 rec.m_key = (PFC_string_formatter() << "Item #" << (walk+1) ).c_str();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 rec.m_value = "edit me";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 return data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 // See CListControlComplete.h for base class description
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 typedef CListControlComplete CListControlDemoParent;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 class CListControlDemo : public CListControlDemoParent {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 typedef CListControlDemoParent parent_t;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 BEGIN_MSG_MAP_EX(CListControlDemo)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 CHAIN_MSG_MAP( parent_t );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 MSG_WM_CREATE(OnCreate)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 MSG_WM_CONTEXTMENU(OnContextMenu)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 END_MSG_MAP()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 // Context menu handler
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 void OnContextMenu(CWindow wnd, CPoint point) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 // did we get a (-1,-1) point due to context menu key rather than right click?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 // GetContextMenuPoint fixes that, returning a proper point at which the menu should be shown
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 point = this->GetContextMenuPoint(point);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 CMenu menu;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 // WIN32_OP_D() : debug build only return value check
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 // Used to check for obscure errors in debug builds, does nothing (ignores errors) in release build
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 WIN32_OP_D(menu.CreatePopupMenu());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 enum { ID_TEST1 = 1, ID_TEST2, ID_SELECTALL, ID_SELECTNONE, ID_INVERTSEL };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 menu.AppendMenu(MF_STRING, ID_TEST1, L"Test 1");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 menu.AppendMenu(MF_STRING, ID_TEST2, L"Test 2");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 menu.AppendMenu(MF_SEPARATOR);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 // Note: Ctrl+A handled automatically by CListControl, no need for us to catch it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 menu.AppendMenu(MF_STRING, ID_SELECTALL, L"Select all\tCtrl+A");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 menu.AppendMenu(MF_STRING, ID_SELECTNONE, L"Select none");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 menu.AppendMenu(MF_STRING, ID_INVERTSEL, L"Invert selection");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 int cmd;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 // Callback object to show menu command descriptions in the status bar.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 // it's actually a hidden window, needs a parent HWND, where we feed our control's HWND
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 CMenuDescriptionMap descriptions(m_hWnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 // Set descriptions of all our items
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 descriptions.Set(ID_TEST1, "This is a test item #1");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 descriptions.Set(ID_TEST2, "This is a test item #2");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 descriptions.Set(ID_SELECTALL, "Selects all items");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 descriptions.Set(ID_SELECTNONE, "Deselects all items");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 descriptions.Set(ID_INVERTSEL, "Invert selection");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 cmd = menu.TrackPopupMenuEx(TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, descriptions, nullptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 switch(cmd) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 case ID_TEST1:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 pfc::string_formatter msg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 msg << "Test command #1 triggered.\r\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 msg << this->GetSelectedCount() << " items selected.";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 // popup_message : non-blocking MessageBox equivalent
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 popup_message::g_show(msg, "Information");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 case ID_TEST2:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 pfc::string_formatter msg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 msg << "Test command #1 triggered.\r\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 msg << "Selected items:\r\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 for( size_t walk = 0; walk < GetItemCount(); ++ walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 if ( this->IsItemSelected( walk ) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 msg << m_data[walk].m_key.c_str() << "\r\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 msg << "End selected items.";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 // popup_message : non-blocking MessageBox equivalent
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 popup_message::g_show(msg, "Information");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 case ID_SELECTALL:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 this->SelectAll(); // trivial
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 case ID_SELECTNONE:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 this->SelectNone(); // trivial
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 case ID_INVERTSEL:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 auto mask = this->GetSelectionMask();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 this->SetSelection(
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 // Items which we alter - all of them
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 pfc::bit_array_true(),
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 // Selection values - NOT'd original selection mask
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 pfc::bit_array_not(mask)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 // Exclusion of footer item from selection handled via CanSelectItem()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 int OnCreate(LPCREATESTRUCT lpCreateStruct) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 InitHeader(); // set up header control with columns
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 SetWindowText(L"List Control Demo"); // screen reader will see this
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 void InitHeader() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 InitializeHeaderCtrl(HDS_FULLDRAG);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 // never hardcode values in pixels, always use screen DPI
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 auto DPI = m_dpi;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 AddColumn( "Check", MulDiv(60, DPI.cx, 96 ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 AddColumn( "Name", MulDiv(100, DPI.cx, 96 ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 AddColumn( "Value", MulDiv(100, DPI.cx, 96 ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 bool CanSelectItem( size_t row ) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 // can not select footer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 return row != footerRow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 size_t footerRow() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 return m_data.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 t_size GetItemCount() const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 return m_data.size() + 1; // footer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 void onFooterClicked() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 SelectNone();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 listData_t obj = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 obj.m_key = "New item";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 size_t index = m_data.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 m_data.push_back( std::move(obj) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 OnItemsInserted(index, 1, true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 void OnSubItemClicked(t_size item, t_size subItem, CPoint pt) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 if ( item == footerRow() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 onFooterClicked(); return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 if ( subItem == 2 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 TableEdit_Start(item, subItem); return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 __super::OnSubItemClicked( item, subItem, pt );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 bool AllowScrollbar(bool vertical) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 t_size InsertIndexFromPointEx(const CPoint & pt, bool & bInside) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 // Drag&drop insertion point hook, for reordering only
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 auto ret = __super::InsertIndexFromPointEx(pt, bInside);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 bInside = false; // never drop *into* an item, only between, as we only allow reorder
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 if ( ret > m_data.size() ) ret = m_data.size(); // never allow drop beyond footer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 void RequestReorder(size_t const * order, size_t count) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 // we've been asked to reorder the items, by either drag&drop or cursors+modifiers
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 // we can either reorder as requested, reorder partially if some of the items aren't moveable, or reject the request
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 PFC_ASSERT( count == GetItemCount() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 // Footer row cannot be moved
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 if ( order[footerRow()] != footerRow() ) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 pfc::reorder_t( m_data, order, count );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 this->OnItemsReordered( order, count );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 void RemoveMask( pfc::bit_array const & mask ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 if ( mask.get(footerRow() ) ) return; // footer row cannot be removed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 auto oldCount = GetItemCount();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 pfc::remove_mask_t( m_data, mask );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 this->OnItemsRemoved( mask, oldCount );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 void RequestRemoveSelection() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 // Delete key etc
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 RemoveMask(GetSelectionMask());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 void ExecuteDefaultAction(t_size index) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 // double click, enter key, etc
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 if ( index == footerRow() ) onFooterClicked();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 bool GetSubItemText(t_size item, t_size subItem, pfc::string_base & out) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 if ( item == footerRow() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 if ( subItem == 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 out = "+ add new";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 auto & rec = m_data[item];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 switch(subItem) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 case 0:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 // pass blank string or return false to create a checkbox only column
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 out = "check";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 case 1:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 out = rec.m_key.c_str();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 case 2:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 out = rec.m_value.c_str();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 size_t GetSubItemSpan(size_t row, size_t column) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 if ( row == footerRow() && column == 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 return GetColumnCount();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 return 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 cellType_t GetCellType(size_t item, size_t subItem) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 // cellType_t is a pointer to a cell class object supplying cell behavior specification & rendering methods
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 // use PFC_SINGLETON to provide static instances of used cells
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 if ( item == footerRow() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 if ( subItem == 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 return & PFC_SINGLETON( CListCell_Button );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 return nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 switch(subItem) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 case 0:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 return & PFC_SINGLETON( CListCell_Checkbox );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 return & PFC_SINGLETON( CListCell_Text );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 bool GetCellTypeSupported() const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 bool GetCellCheckState(size_t item, size_t subItem) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 if ( subItem == 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 auto & rec = m_data[item];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 return rec.m_checkState;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 void SetCellCheckState(size_t item, size_t subItem, bool value) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 if ( subItem == 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 auto & rec = m_data[item];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 if (rec.m_checkState != value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 rec.m_checkState = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 __super::SetCellCheckState(item, subItem, value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 uint32_t QueryDragDropTypes() const override {return dragDrop_reorder;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 // Inplace edit handlers
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 // Overrides of CTableEditHelperV2 methods
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 void TableEdit_SetField(t_size item, t_size subItem, const char * value) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 if ( subItem == 2 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 m_data[item].m_value = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 ReloadItem( item );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 bool TableEdit_IsColumnEditable(t_size subItem) const override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 return subItem == 2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 std::vector< listData_t > m_data = makeListData();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 // Straightforward WTL dialog code
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 class CListControlAdvancedDemoDialog : public CDialogImpl<CListControlAdvancedDemoDialog> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 enum { IDD = IDD_LISTCONTROL_DEMO };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 BEGIN_MSG_MAP_EX(CListControlAdvancedDemoDialog)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 MSG_WM_INITDIALOG(OnInitDialog)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 COMMAND_HANDLER_EX(IDCANCEL, BN_CLICKED, OnCancel)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 END_MSG_MAP()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 void OnCancel(UINT, int, CWindow) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 DestroyWindow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 BOOL OnInitDialog(CWindow, LPARAM) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 // Create replacing existing windows list control
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 // automatically initialize position, font, etc
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 m_list.CreateInDialog( *this, IDC_LIST1 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 // Do this AFTER creating CListControl, so dark mode hook talks to new CListControl rather than shortlived IDC_LIST1 placeholder
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 m_dark.AddDialogWithControls(*this);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 ShowWindow(SW_SHOW);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 return TRUE; // system should set focus
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 CListControlDemo m_list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 fb2k::CDarkModeHooks m_dark;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 // Called from mainmenu.cpp
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 void RunListControlAdvancedDemo() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 // automatically creates the dialog with object lifetime management and modeless dialog registration
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 fb2k::newDialog<CListControlAdvancedDemoDialog>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330