Mercurial > foo_out_sdl
comparison foosdk/sdk/libPPUI/InPlaceEditTable.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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "stdafx.h" | |
| 2 #include "InPlaceEditTable.h" | |
| 3 | |
| 4 #include "win32_op.h" | |
| 5 #include "win32_utility.h" | |
| 6 #include "AutoComplete.h" | |
| 7 | |
| 8 #include "listview_helper.h" | |
| 9 | |
| 10 namespace InPlaceEdit { | |
| 11 | |
| 12 bool CTableEditHelperV2::tableEdit_cancel_task() { | |
| 13 bool rv = false; | |
| 14 if (m_taskKill) { | |
| 15 *m_taskKill = true; m_taskKill = nullptr; | |
| 16 rv = true; | |
| 17 } | |
| 18 return rv; | |
| 19 } | |
| 20 reply_t CTableEditHelperV2::tableEdit_create_task() { | |
| 21 tableEdit_cancel_task(); | |
| 22 auto ks = std::make_shared<bool>(false); | |
| 23 m_taskKill = ks; | |
| 24 return [ks,this](unsigned code) { | |
| 25 if ( ! * ks ) { | |
| 26 this->tableEdit_on_task_completion( code ); | |
| 27 } | |
| 28 }; | |
| 29 } | |
| 30 t_size CTableEditHelperV2::ColumnToPosition(t_size col) const { | |
| 31 PFC_ASSERT(TableEdit_IsColumnEditable(col)); | |
| 32 pfc::array_t<t_size> colOrder; GrabColumnOrder(colOrder); | |
| 33 t_size skipped = 0; | |
| 34 for (t_size walk = 0; walk < colOrder.get_size(); ++walk) { | |
| 35 const t_size curCol = colOrder[walk]; | |
| 36 if (TableEdit_IsColumnEditable(curCol)) { | |
| 37 if (curCol == col) return skipped; | |
| 38 ++skipped; | |
| 39 } | |
| 40 } | |
| 41 PFC_ASSERT(!"Should not get here."); | |
| 42 return SIZE_MAX; | |
| 43 } | |
| 44 t_size CTableEditHelperV2::PositionToColumn(t_size pos) const { | |
| 45 pfc::array_t<t_size> colOrder; GrabColumnOrder(colOrder); | |
| 46 t_size skipped = 0; | |
| 47 for (t_size walk = 0; walk < colOrder.get_size(); ++walk) { | |
| 48 const t_size curCol = colOrder[walk]; | |
| 49 if (TableEdit_IsColumnEditable(curCol)) { | |
| 50 if (skipped == pos) return curCol; | |
| 51 ++skipped; | |
| 52 } | |
| 53 } | |
| 54 PFC_ASSERT(!"Should not get here."); | |
| 55 return SIZE_MAX; | |
| 56 } | |
| 57 t_size CTableEditHelperV2::EditableColumnCount() const { | |
| 58 const t_size total = TableEdit_GetColumnCount(); | |
| 59 t_size found = 0; | |
| 60 for (t_size walk = 0; walk < total; ++walk) { | |
| 61 if (TableEdit_IsColumnEditable(walk)) found++; | |
| 62 } | |
| 63 return found; | |
| 64 } | |
| 65 | |
| 66 bool CTableEditHelperV2::TableEdit_Advance(t_size & p_item, t_size & p_subItem, t_uint32 whathappened) { | |
| 67 size_t guardItem = SIZE_MAX, guardSubItem = SIZE_MAX; // infinite loop guard | |
| 68 size_t item = p_item, subItem = p_subItem; | |
| 69 for ( ;; ) { | |
| 70 unsigned _item((unsigned)item), _subItem((unsigned)ColumnToPosition(subItem)); | |
| 71 if (!InPlaceEdit::TableEditAdvance(_item, _subItem, (unsigned)TableEdit_GetItemCount(), (unsigned)EditableColumnCount(), whathappened)) return false; | |
| 72 item = _item; subItem = PositionToColumn(_subItem); | |
| 73 | |
| 74 if ( guardItem == SIZE_MAX ) { | |
| 75 guardItem = item; guardSubItem = subItem; | |
| 76 } else { | |
| 77 // infinite loop guard | |
| 78 if ( item == guardItem && subItem == guardSubItem ) return false; | |
| 79 } | |
| 80 | |
| 81 if (TableEdit_CanAdvanceHere(item, subItem, whathappened)) break; | |
| 82 } | |
| 83 p_item = item; | |
| 84 p_subItem = subItem; | |
| 85 return true; | |
| 86 } | |
| 87 | |
| 88 void CTableEditHelperV2::TableEdit_Abort(bool forwardContent) { | |
| 89 if (tableEdit_cancel_task()) { | |
| 90 if (forwardContent && (m_editFlags & KFlagReadOnly) == 0) { | |
| 91 if (m_editData.is_valid()) { | |
| 92 pfc::string8 temp(*m_editData); | |
| 93 TableEdit_SetField(m_editItem, m_editSubItem, temp); | |
| 94 } | |
| 95 } | |
| 96 m_editData.release(); | |
| 97 m_editDataCombo.reset(); | |
| 98 ::SetFocus(TableEdit_GetParentWnd()); | |
| 99 TableEdit_Finished(); | |
| 100 } | |
| 101 | |
| 102 } | |
| 103 | |
| 104 HWND CTableEditHelperV2::TableEdit_Start(t_size item, t_size subItem) { | |
| 105 PFC_ASSERT(TableEdit_IsColumnEditable(subItem)); | |
| 106 m_editItem = item; m_editSubItem = subItem; | |
| 107 return _ReStart(); | |
| 108 } | |
| 109 | |
| 110 HWND CTableEditHelperV2::_ReStart() { | |
| 111 PFC_ASSERT(m_editItem < TableEdit_GetItemCount()); | |
| 112 PFC_ASSERT(m_editSubItem < TableEdit_GetColumnCount()); | |
| 113 | |
| 114 TableEdit_SetItemFocus(m_editItem, m_editSubItem); | |
| 115 | |
| 116 m_editFlags = TableEdit_GetEditFlags(m_editItem, m_editSubItem); | |
| 117 | |
| 118 if (this->TableEdit_GetDarkMode()) m_editFlags |= KFlagDark; | |
| 119 | |
| 120 m_editData.release(); | |
| 121 m_editDataCombo.reset(); | |
| 122 | |
| 123 if (m_editFlags & InPlaceEdit::KFlagCombo) { | |
| 124 auto combo = TableEdit_GetCombo(m_editItem, m_editSubItem); | |
| 125 RECT rc = TableEdit_GetItemRect(m_editItem, m_editSubItem); | |
| 126 | |
| 127 auto data = std::make_shared< combo_t >(combo); | |
| 128 m_editDataCombo = data; | |
| 129 | |
| 130 auto task = tableEdit_create_task(); | |
| 131 auto comboTask = [data, task](unsigned status, unsigned sel) { | |
| 132 data->iDefault = sel; | |
| 133 task(status); | |
| 134 }; | |
| 135 | |
| 136 return InPlaceEdit::StartCombo(TableEdit_GetParentWnd(), rc, m_editFlags, combo.strings, combo.iDefault, comboTask ); | |
| 137 } | |
| 138 | |
| 139 m_editData.new_t(); | |
| 140 t_size lineCount = 1; | |
| 141 TableEdit_GetField(m_editItem, m_editSubItem, *m_editData, lineCount); | |
| 142 | |
| 143 RECT rc = TableEdit_GetItemRect(m_editItem, m_editSubItem); | |
| 144 if (lineCount > 1) { | |
| 145 rc.bottom = (LONG)( rc.top + (rc.bottom - rc.top) * lineCount ); | |
| 146 m_editFlags |= KFlagMultiLine; | |
| 147 } | |
| 148 auto ac = this->TableEdit_GetAutoCompleteEx(m_editItem, m_editSubItem ); | |
| 149 return InPlaceEdit::StartEx(TableEdit_GetParentWnd(), rc, m_editFlags, m_editData, tableEdit_create_task(), ac.data.get_ptr(), ac.options); | |
| 150 } | |
| 151 | |
| 152 CTableEditHelperV2::combo_t CTableEditHelperV2::TableEdit_GetCombo(size_t, size_t) { | |
| 153 return combo_t(); | |
| 154 } | |
| 155 CTableEditHelperV2::autoComplete_t CTableEditHelperV2::TableEdit_GetAutoCompleteEx( size_t item, size_t sub ) { | |
| 156 autoComplete_t ret; | |
| 157 if ( this->TableEdit_GetAutoComplete( item, sub, ret.data ) ) ret.options = ret.optsDefault; | |
| 158 return ret; | |
| 159 } | |
| 160 | |
| 161 void CTableEditHelperV2::tableEdit_on_task_completion(unsigned status) { | |
| 162 tableEdit_cancel_task(); | |
| 163 if (m_editData.is_valid()) { | |
| 164 if (status & InPlaceEdit::KEditFlagContentChanged) { | |
| 165 TableEdit_SetField(m_editItem, m_editSubItem, *m_editData); | |
| 166 } | |
| 167 m_editData.release(); | |
| 168 } | |
| 169 if (m_editDataCombo != nullptr) { | |
| 170 unsigned idx = m_editDataCombo->iDefault; | |
| 171 if ( idx < m_editDataCombo->strings.get_count()) { | |
| 172 const char * text = m_editDataCombo->strings.get_item(idx); | |
| 173 TableEdit_SetField(m_editItem, m_editSubItem, text); | |
| 174 } | |
| 175 | |
| 176 m_editDataCombo.reset(); | |
| 177 } | |
| 178 | |
| 179 if (TableEdit_Advance(m_editItem, m_editSubItem, status)) { | |
| 180 _ReStart(); | |
| 181 } else { | |
| 182 TableEdit_Finished(); | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 | |
| 187 | |
| 188 | |
| 189 | |
| 190 void CTableEditHelperV2_ListView::TableEdit_GetColumnOrder(t_size * out, t_size count) const { | |
| 191 pfc::array_t<int> temp; temp.set_size(count); | |
| 192 WIN32_OP_D(ListView_GetColumnOrderArray(TableEdit_GetParentWnd(), count, temp.get_ptr())); | |
| 193 for (t_size walk = 0; walk < count; ++walk) out[walk] = temp[walk]; | |
| 194 } | |
| 195 | |
| 196 RECT CTableEditHelperV2_ListView::TableEdit_GetItemRect(t_size item, t_size subItem) const { | |
| 197 RECT rc; | |
| 198 WIN32_OP_D(ListView_GetSubItemRect(TableEdit_GetParentWnd(), (int)item, (int)subItem, LVIR_LABEL, &rc)); | |
| 199 return rc; | |
| 200 } | |
| 201 | |
| 202 void CTableEditHelperV2_ListView::TableEdit_GetField(t_size item, t_size subItem, pfc::string_base & out, t_size & lineCount) { | |
| 203 listview_helper::get_item_text(TableEdit_GetParentWnd(), (int)item, (int)subItem, out); | |
| 204 lineCount = pfc::is_multiline(out) ? 5 : 1; | |
| 205 } | |
| 206 void CTableEditHelperV2_ListView::TableEdit_SetField(t_size item, t_size subItem, const char * value) { | |
| 207 WIN32_OP_D(listview_helper::set_item_text(TableEdit_GetParentWnd(), (int)item, (int)subItem, value)); | |
| 208 | |
| 209 #if PFC_DEBUG | |
| 210 pfc::string8 meh; | |
| 211 listview_helper::get_item_text(TableEdit_GetParentWnd(), (int)item, (int)subItem, meh); | |
| 212 PFC_ASSERT(meh == value); | |
| 213 #endif | |
| 214 } | |
| 215 t_size CTableEditHelperV2_ListView::TableEdit_GetItemCount() const { | |
| 216 LRESULT temp; | |
| 217 WIN32_OP_D((temp = ListView_GetItemCount(TableEdit_GetParentWnd())) >= 0); | |
| 218 return (t_size)temp; | |
| 219 } | |
| 220 void CTableEditHelperV2_ListView::TableEdit_SetItemFocus(t_size item, t_size) { | |
| 221 WIN32_OP_D(listview_helper::select_single_item(TableEdit_GetParentWnd(), (int) item)); | |
| 222 } | |
| 223 | |
| 224 t_size CTableEditHelperV2_ListView::TableEdit_GetColumnCount() const { | |
| 225 return (t_size)ListView_GetColumnCount(TableEdit_GetParentWnd()); | |
| 226 } | |
| 227 | |
| 228 } |
