From a82499551d62adc4602840e8100a3ebfe4465727 Mon Sep 17 00:00:00 2001
From: Rene Gollent <rene@gollent.com>
Date: Wed, 3 Jun 2015 19:10:56 -0400
Subject: [PATCH] Debugger: Add interface subclasses for table cell editors.

TableCellTextControlEditor:
- Serves as a base for editors that expose their functionality via a
  text control. Handles common functionality of watching for changes,
  validating input, and notifying listeners appropriately.
TableCellOptionPopUpEditor:
- Serves as a base class for editors where the set of possible values
  is fixed and known up front. Handles reacting to selection changes
  and notifying listeners.
---
 src/apps/debugger/Jamfile                     |   4 +
 .../value/TableCellFormattedValueEditor.cpp   |  25 +++++
 .../gui/value/TableCellFormattedValueEditor.h |  30 ++++++
 .../gui/value/TableCellOptionPopUpEditor.cpp  |  75 +++++++++++++
 .../gui/value/TableCellOptionPopUpEditor.h    |  34 ++++++
 .../gui/value/TableCellTextControlEditor.cpp  | 102 ++++++++++++++++++
 .../gui/value/TableCellTextControlEditor.h    |  35 ++++++
 7 files changed, 305 insertions(+)
 create mode 100644 src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.cpp
 create mode 100644 src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.h
 create mode 100644 src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.cpp
 create mode 100644 src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.h
 create mode 100644 src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.cpp
 create mode 100644 src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.h

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index d1a2859b2f..3f1e595af3 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -300,7 +300,11 @@ Application Debugger :
 	WatchPromptWindow.cpp
 
 	# user_interface/gui/value
+	TableCellFormattedValueEditor.cpp
 	TableCellFormattedValueRenderer.cpp
+	TableCellOptionPopUpEditor.cpp
+	TableCellTextControlEditor.cpp
+	TableCellValueEditor.cpp
 	TableCellValueRenderer.cpp
 	TableCellValueRendererUtils.cpp
 
diff --git a/src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.cpp b/src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.cpp
new file mode 100644
index 0000000000..4ab92ebf98
--- /dev/null
+++ b/src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@gollent.com.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "TableCellFormattedValueEditor.h"
+
+#include "ValueFormatter.h"
+
+
+TableCellFormattedValueEditor::TableCellFormattedValueEditor(
+	Value* initialValue, ValueFormatter* formatter)
+	:
+	TableCellValueEditor(),
+	fValueFormatter(formatter)
+{
+	SetInitialValue(initialValue);
+	fValueFormatter->AcquireReference();
+}
+
+
+TableCellFormattedValueEditor::~TableCellFormattedValueEditor()
+{
+	fValueFormatter->ReleaseReference();
+}
diff --git a/src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.h b/src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.h
new file mode 100644
index 0000000000..c38c289a0a
--- /dev/null
+++ b/src/apps/debugger/user_interface/gui/value/TableCellFormattedValueEditor.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@gollent.com.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef TABLE_CELL_FORMATTED_VALUE_EDITOR_H
+#define TABLE_CELL_FORMATTED_VALUE_EDITOR_H
+
+#include "TableCellValueEditor.h"
+
+
+class ValueFormatter;
+
+
+class TableCellFormattedValueEditor : public TableCellValueEditor {
+public:
+								TableCellFormattedValueEditor(
+									Value* initialValue,
+									ValueFormatter* formatter);
+	virtual						~TableCellFormattedValueEditor();
+
+protected:
+			ValueFormatter*		GetValueFormatter() const
+									{ return fValueFormatter; }
+
+private:
+			ValueFormatter*		fValueFormatter;
+};
+
+
+#endif	// TABLE_CELL_FORMATTED_VALUE_EDITOR_H
diff --git a/src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.cpp b/src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.cpp
new file mode 100644
index 0000000000..4fa432dec4
--- /dev/null
+++ b/src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@gollent.com.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "TableCellOptionPopUpEditor.h"
+
+#include "Value.h"
+
+
+enum {
+	MSG_SELECTED_OPTION_CHANGED 	= 'msoc'
+};
+
+
+TableCellOptionPopUpEditor::TableCellOptionPopUpEditor(::Value* initialValue,
+	ValueFormatter* formatter)
+	:
+	TableCellFormattedValueEditor(initialValue, formatter),
+	BOptionPopUp("optionEditor", NULL, NULL)
+{
+}
+
+
+TableCellOptionPopUpEditor::~TableCellOptionPopUpEditor()
+{
+}
+
+
+status_t
+TableCellOptionPopUpEditor::Init()
+{
+	BMessage* message = new(std::nothrow) BMessage(
+		MSG_SELECTED_OPTION_CHANGED);
+	if (message == NULL)
+		return B_NO_MEMORY;
+
+	SetMessage(message);
+
+	return ConfigureOptions();
+}
+
+
+BView*
+TableCellOptionPopUpEditor::GetView()
+{
+	return this;
+}
+
+
+void
+TableCellOptionPopUpEditor::AttachedToWindow()
+{
+	BOptionPopUp::AttachedToWindow();
+
+	SetTarget(this);
+
+	NotifyEditBeginning();
+}
+
+
+void
+TableCellOptionPopUpEditor::MessageReceived(BMessage* message)
+{
+	switch (message->what) {
+		case MSG_SELECTED_OPTION_CHANGED:
+		{
+			// TODO: implement
+			break;
+		}
+		default:
+			BOptionPopUp::MessageReceived(message);
+			break;
+	}
+}
diff --git a/src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.h b/src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.h
new file mode 100644
index 0000000000..e9f3d9ee0c
--- /dev/null
+++ b/src/apps/debugger/user_interface/gui/value/TableCellOptionPopUpEditor.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@gollent.com.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef TABLE_CELL_OPTION_POPUP_EDITOR_H
+#define TABLE_CELL_OPTION_POPUP_EDITOR_H
+
+#include <OptionPopUp.h>
+
+#include "TableCellFormattedValueEditor.h"
+
+
+// common base class for editors that have a fixed set of chooseable
+// values known up front
+class TableCellOptionPopUpEditor : public TableCellFormattedValueEditor,
+	protected BOptionPopUp {
+public:
+								TableCellOptionPopUpEditor(
+									::Value* initialValue,
+									ValueFormatter* formatter);
+	virtual						~TableCellOptionPopUpEditor();
+
+	status_t					Init();
+
+	virtual	BView*				GetView();
+
+	virtual	status_t			ConfigureOptions() = 0;
+
+protected:
+	virtual	void				AttachedToWindow();
+	virtual	void				MessageReceived(BMessage* message);
+};
+
+#endif	// TABLE_CELL_TEXT_CONTROL_EDITOR_H
diff --git a/src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.cpp b/src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.cpp
new file mode 100644
index 0000000000..2c9a999257
--- /dev/null
+++ b/src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@gollent.com.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "TableCellTextControlEditor.h"
+
+#include "Value.h"
+#include "ValueFormatter.h"
+
+
+enum {
+	MSG_INPUT_VALIDATION_NEEDED 	= 'ivne',
+	MSG_TEXT_VALUE_CHANGED 			= 'tevc'
+};
+
+
+TableCellTextControlEditor::TableCellTextControlEditor(::Value* initialValue,
+	ValueFormatter* formatter)
+	:
+	TableCellFormattedValueEditor(initialValue, formatter),
+	BTextControl("", "", NULL)
+{
+}
+
+
+TableCellTextControlEditor::~TableCellTextControlEditor()
+{
+}
+
+
+status_t
+TableCellTextControlEditor::Init()
+{
+	BMessage* message = new(std::nothrow) BMessage(
+		MSG_INPUT_VALIDATION_NEEDED);
+	if (message == NULL)
+		return B_NO_MEMORY;
+
+	SetMessage(message);
+
+	message = new(std::nothrow) BMessage(MSG_TEXT_VALUE_CHANGED);
+	if (message == NULL)
+		return B_NO_MEMORY;
+
+	SetModificationMessage(message);
+
+	return B_OK;
+}
+
+
+BView*
+TableCellTextControlEditor::GetView()
+{
+	return this;
+}
+
+
+void
+TableCellTextControlEditor::AttachedToWindow()
+{
+	BTextControl::AttachedToWindow();
+
+	SetTarget(this);
+
+	BString output;
+
+	if (GetValueFormatter()->FormatValue(InitialValue(), output) == B_OK)
+		SetText(output);
+
+	NotifyEditBeginning();
+}
+
+
+void
+TableCellTextControlEditor::MessageReceived(BMessage* message)
+{
+	switch (message->what) {
+		case MSG_TEXT_VALUE_CHANGED:
+		{
+			// TODO: highlight the input view in some way to show
+			// invalid inputs
+			break;
+		}
+		case MSG_INPUT_VALIDATION_NEEDED:
+		{
+			if (ValidateInput()) {
+				::Value* value = NULL;
+				status_t error = GetValueForInput(value);
+				if (error != B_OK)
+					break;
+
+				BReference< ::Value> valueReference(value, true);
+				NotifyEditCompleted(value);
+			}
+			break;
+		}
+		default:
+			BTextControl::MessageReceived(message);
+			break;
+	}
+}
diff --git a/src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.h b/src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.h
new file mode 100644
index 0000000000..7dfe962428
--- /dev/null
+++ b/src/apps/debugger/user_interface/gui/value/TableCellTextControlEditor.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015, Rene Gollent, rene@gollent.com.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef TABLE_CELL_TEXT_CONTROL_EDITOR_H
+#define TABLE_CELL_TEXT_CONTROL_EDITOR_H
+
+#include <TextControl.h>
+
+#include "TableCellFormattedValueEditor.h"
+
+
+// common base class for editors that input a value via a text field
+class TableCellTextControlEditor : public TableCellFormattedValueEditor,
+	protected BTextControl {
+public:
+								TableCellTextControlEditor(
+									::Value* initialValue,
+									ValueFormatter* formatter);
+	virtual						~TableCellTextControlEditor();
+
+	status_t					Init();
+
+	virtual	BView*				GetView();
+
+	virtual	bool				ValidateInput() const = 0;
+
+	virtual status_t			GetValueForInput(::Value*& _output) const = 0;
+									// returns reference
+
+	virtual	void				AttachedToWindow();
+	virtual	void				MessageReceived(BMessage* message);
+};
+
+#endif	// TABLE_CELL_TEXT_CONTROL_EDITOR_H