diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/libPPUI/InPlaceEditTable.cpp	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,228 @@
+#include "stdafx.h"
+#include "InPlaceEditTable.h"
+
+#include "win32_op.h"
+#include "win32_utility.h"
+#include "AutoComplete.h"
+
+#include "listview_helper.h"
+
+namespace InPlaceEdit {
+
+	bool CTableEditHelperV2::tableEdit_cancel_task() {
+		bool rv = false;
+		if (m_taskKill) {
+			*m_taskKill = true; m_taskKill = nullptr;
+			rv = true;
+		}
+		return rv;
+	}
+	reply_t CTableEditHelperV2::tableEdit_create_task() {
+		tableEdit_cancel_task();
+		auto ks = std::make_shared<bool>(false);
+		m_taskKill = ks;
+		return [ks,this](unsigned code) {
+			if ( ! * ks ) {
+				this->tableEdit_on_task_completion( code );
+			}
+		};
+	}
+	t_size CTableEditHelperV2::ColumnToPosition(t_size col) const {
+		PFC_ASSERT(TableEdit_IsColumnEditable(col));
+		pfc::array_t<t_size> colOrder; GrabColumnOrder(colOrder);
+		t_size skipped = 0;
+		for (t_size walk = 0; walk < colOrder.get_size(); ++walk) {
+			const t_size curCol = colOrder[walk];
+			if (TableEdit_IsColumnEditable(curCol)) {
+				if (curCol == col) return skipped;
+				++skipped;
+			}
+		}
+		PFC_ASSERT(!"Should not get here.");
+		return SIZE_MAX;
+	}
+	t_size CTableEditHelperV2::PositionToColumn(t_size pos) const {
+		pfc::array_t<t_size> colOrder; GrabColumnOrder(colOrder);
+		t_size skipped = 0;
+		for (t_size walk = 0; walk < colOrder.get_size(); ++walk) {
+			const t_size curCol = colOrder[walk];
+			if (TableEdit_IsColumnEditable(curCol)) {
+				if (skipped == pos) return curCol;
+				++skipped;
+			}
+		}
+		PFC_ASSERT(!"Should not get here.");
+		return SIZE_MAX;
+	}
+	t_size CTableEditHelperV2::EditableColumnCount() const {
+		const t_size total = TableEdit_GetColumnCount();
+		t_size found = 0;
+		for (t_size walk = 0; walk < total; ++walk) {
+			if (TableEdit_IsColumnEditable(walk)) found++;
+		}
+		return found;
+	}
+
+	bool CTableEditHelperV2::TableEdit_Advance(t_size & p_item, t_size & p_subItem, t_uint32 whathappened) {
+		size_t guardItem = SIZE_MAX, guardSubItem = SIZE_MAX; // infinite loop guard
+		size_t item = p_item, subItem = p_subItem;
+		for ( ;; ) {
+			unsigned _item((unsigned)item), _subItem((unsigned)ColumnToPosition(subItem));
+			if (!InPlaceEdit::TableEditAdvance(_item, _subItem, (unsigned)TableEdit_GetItemCount(), (unsigned)EditableColumnCount(), whathappened)) return false;
+			item = _item; subItem = PositionToColumn(_subItem);
+			
+			if ( guardItem == SIZE_MAX ) {
+				guardItem = item; guardSubItem = subItem;
+			} else {
+				// infinite loop guard
+				if ( item == guardItem && subItem == guardSubItem ) return false;
+			}
+
+			if (TableEdit_CanAdvanceHere(item, subItem, whathappened)) break;
+		}
+		p_item = item;
+		p_subItem = subItem;
+		return true;
+	}
+
+	void CTableEditHelperV2::TableEdit_Abort(bool forwardContent) {
+		if (tableEdit_cancel_task()) {
+			if (forwardContent && (m_editFlags & KFlagReadOnly) == 0) {
+				if (m_editData.is_valid()) {
+					pfc::string8 temp(*m_editData);
+					TableEdit_SetField(m_editItem, m_editSubItem, temp);
+				}
+			}
+			m_editData.release();
+			m_editDataCombo.reset();
+			::SetFocus(TableEdit_GetParentWnd());
+			TableEdit_Finished();
+		}
+
+	}
+
+	HWND CTableEditHelperV2::TableEdit_Start(t_size item, t_size subItem) {
+		PFC_ASSERT(TableEdit_IsColumnEditable(subItem));
+		m_editItem = item; m_editSubItem = subItem;
+		return _ReStart();
+	}
+
+	HWND CTableEditHelperV2::_ReStart() {
+		PFC_ASSERT(m_editItem < TableEdit_GetItemCount());
+		PFC_ASSERT(m_editSubItem < TableEdit_GetColumnCount());
+
+		TableEdit_SetItemFocus(m_editItem, m_editSubItem);
+
+		m_editFlags = TableEdit_GetEditFlags(m_editItem, m_editSubItem);
+
+		if (this->TableEdit_GetDarkMode()) m_editFlags |= KFlagDark;
+
+		m_editData.release();
+		m_editDataCombo.reset();
+
+		if (m_editFlags & InPlaceEdit::KFlagCombo) {
+			auto combo = TableEdit_GetCombo(m_editItem, m_editSubItem);
+			RECT rc = TableEdit_GetItemRect(m_editItem, m_editSubItem);
+
+			auto data = std::make_shared< combo_t >(combo);
+			m_editDataCombo = data;
+
+			auto task = tableEdit_create_task();
+			auto comboTask = [data, task](unsigned status, unsigned sel) {
+				data->iDefault = sel;
+				task(status);
+			};
+
+			return InPlaceEdit::StartCombo(TableEdit_GetParentWnd(), rc, m_editFlags, combo.strings, combo.iDefault, comboTask );
+		}
+
+		m_editData.new_t();
+		t_size lineCount = 1;
+		TableEdit_GetField(m_editItem, m_editSubItem, *m_editData, lineCount);
+
+		RECT rc = TableEdit_GetItemRect(m_editItem, m_editSubItem);
+		if (lineCount > 1) {
+			rc.bottom = (LONG)( rc.top + (rc.bottom - rc.top) * lineCount );
+			m_editFlags |= KFlagMultiLine;
+		}
+		auto ac = this->TableEdit_GetAutoCompleteEx(m_editItem, m_editSubItem );
+		return InPlaceEdit::StartEx(TableEdit_GetParentWnd(), rc, m_editFlags, m_editData, tableEdit_create_task(), ac.data.get_ptr(), ac.options);
+	}
+
+	CTableEditHelperV2::combo_t CTableEditHelperV2::TableEdit_GetCombo(size_t, size_t) {
+		return combo_t();
+	}
+	CTableEditHelperV2::autoComplete_t CTableEditHelperV2::TableEdit_GetAutoCompleteEx( size_t item, size_t sub ) {
+		autoComplete_t ret;
+		if ( this->TableEdit_GetAutoComplete( item, sub, ret.data ) ) ret.options = ret.optsDefault;
+		return ret;
+	}
+
+	void CTableEditHelperV2::tableEdit_on_task_completion(unsigned status) {
+		tableEdit_cancel_task();
+		if (m_editData.is_valid()) {
+			if (status & InPlaceEdit::KEditFlagContentChanged) {
+				TableEdit_SetField(m_editItem, m_editSubItem, *m_editData);
+			}
+			m_editData.release();
+		}
+		if (m_editDataCombo != nullptr) {
+			unsigned idx = m_editDataCombo->iDefault;
+			if ( idx < m_editDataCombo->strings.get_count()) {
+				const char * text = m_editDataCombo->strings.get_item(idx);
+				TableEdit_SetField(m_editItem, m_editSubItem, text);
+			}
+
+			m_editDataCombo.reset();
+		}
+
+		if (TableEdit_Advance(m_editItem, m_editSubItem, status)) {
+			_ReStart();
+		} else {
+			TableEdit_Finished();
+		}
+	}
+
+
+
+
+
+	void CTableEditHelperV2_ListView::TableEdit_GetColumnOrder(t_size * out, t_size count) const {
+		pfc::array_t<int> temp; temp.set_size(count);
+		WIN32_OP_D(ListView_GetColumnOrderArray(TableEdit_GetParentWnd(), count, temp.get_ptr()));
+		for (t_size walk = 0; walk < count; ++walk) out[walk] = temp[walk];
+	}
+
+	RECT CTableEditHelperV2_ListView::TableEdit_GetItemRect(t_size item, t_size subItem) const {
+		RECT rc;
+		WIN32_OP_D(ListView_GetSubItemRect(TableEdit_GetParentWnd(), (int)item, (int)subItem, LVIR_LABEL, &rc));
+		return rc;
+	}
+
+	void CTableEditHelperV2_ListView::TableEdit_GetField(t_size item, t_size subItem, pfc::string_base & out, t_size & lineCount) {
+		listview_helper::get_item_text(TableEdit_GetParentWnd(), (int)item, (int)subItem, out);
+		lineCount = pfc::is_multiline(out) ? 5 : 1;
+	}
+	void CTableEditHelperV2_ListView::TableEdit_SetField(t_size item, t_size subItem, const char * value) {
+		WIN32_OP_D(listview_helper::set_item_text(TableEdit_GetParentWnd(), (int)item, (int)subItem, value));
+
+#if PFC_DEBUG
+		pfc::string8 meh;
+		listview_helper::get_item_text(TableEdit_GetParentWnd(), (int)item, (int)subItem, meh);
+		PFC_ASSERT(meh == value);
+#endif
+	}
+	t_size CTableEditHelperV2_ListView::TableEdit_GetItemCount() const {
+		LRESULT temp;
+		WIN32_OP_D((temp = ListView_GetItemCount(TableEdit_GetParentWnd())) >= 0);
+		return (t_size)temp;
+	}
+	void CTableEditHelperV2_ListView::TableEdit_SetItemFocus(t_size item, t_size) {
+		WIN32_OP_D(listview_helper::select_single_item(TableEdit_GetParentWnd(), (int) item));
+	}
+
+	t_size CTableEditHelperV2_ListView::TableEdit_GetColumnCount() const { 
+		return (t_size)ListView_GetColumnCount(TableEdit_GetParentWnd()); 
+	}
+
+}