Beispiel #1
0
static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
{
    glfwSetClipboardString((GLFWwindow*)user_data, text);
}
void TextFieldWidget::ProcessEvent(InputEvent & InputEvent)
{
	// DECISION
	//if (CheckHover())
	// HACK
	//if (HasTypingFocus())
	/*{
		// TEST
		if (   InputEvent.m_EventTypes.end() != InputEvent.m_EventTypes.find(InputEvent::EventType::POINTER_ACTIVATION)
			&& (   InputEvent.m_EventTypes.end() != InputEvent.m_EventTypes.find(InputEvent::EventType::BUTTON_EVENT)
				&& 0 == InputEvent.m_InputId
				&& true == InputEvent.m_Buttons[0]))
		{
			InputEvent.m_Pointer->ModifyPointerMapping().RequestPointerCapture(&ModifyGestureRecognizer());
		}
	}

	// DECISION
	// TEST
	// If captured by something else, ignore this event
	if (   nullptr != InputEvent.m_Pointer->GetPointerMapping().GetCapturer()
		&& &GetGestureRecognizer() != InputEvent.m_Pointer->GetPointerMapping().GetCapturer())
	{
		return;
	}*/

	auto SelectionLength = std::max(m_CaretPosition, m_SelectionPosition) - std::min(m_CaretPosition, m_SelectionPosition);

	if (InputEvent.m_EventTypes.end() != InputEvent.m_EventTypes.find(InputEvent::EventType::BUTTON_EVENT))
	{
		auto ButtonId = InputEvent.m_InputId;
		bool Pressed = InputEvent.m_Buttons[0];		// TODO: Check if there are >1 buttons

		if (Pointer::VirtualCategory::TYPING == InputEvent.m_Pointer->GetVirtualCategory())
		{
			if (Pressed)
			{
				auto ShiftActive = (   InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_LSHIFT)
									|| InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_RSHIFT));
				auto SuperActive = (   InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_LSUPER)
									|| InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_RSUPER));
				auto AltActive = (   InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_LALT)
								  || InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_RALT));

				bool HandledEvent = true;		// Assume true at first

				switch (ButtonId)
				{
				case GLFW_KEY_BACKSPACE:
					{
						auto SelectionExisted = EraseSelectionIfAny();

						if (false == SelectionExisted)
						{
							if (m_CaretPosition > 0)
							{
								m_Content.erase(m_CaretPosition - 1, 1);
								UpdateContentLines();
								MoveCaret(-1, true);
							}
						}
					}
					break;
				case GLFW_KEY_DEL:
					{
						auto SelectionExisted = EraseSelectionIfAny();

						if (false == SelectionExisted)
						{
							if (m_CaretPosition < m_Content.length())
							{
								m_Content.erase(m_CaretPosition, 1);
								UpdateContentLines();
							}
						}
					}
					break;
				case GLFW_KEY_ENTER:
				case GLFW_KEY_KP_ENTER:
					{
						EraseSelectionIfAny();

						m_Content.insert(m_CaretPosition, 1, '\n');
						UpdateContentLines();
						MoveCaret(+1, true);
					}
					break;
				case GLFW_KEY_TAB:
					{
						EraseSelectionIfAny();

						m_Content.insert(m_CaretPosition, 1, '\t');
						UpdateContentLines();
						MoveCaret(+1, true);
					}
					break;
				case GLFW_KEY_LEFT:
					{
						if (0 != SelectionLength && !ShiftActive)
						{
							SetCaretPosition(std::min(m_CaretPosition, m_SelectionPosition), true);
						}
						else
						{
							if (SuperActive && !AltActive)
							{
								std::vector<class ContentLine>::size_type LineNumber = 0;
								std::vector<class ContentLine>::size_type ColumnNumber = 0;

								for (auto & ContentLine : m_ContentLines)
								{
									if (ContentLine.m_StartPosition + ContentLine.m_Length >= m_CaretPosition)
									{
										ColumnNumber = m_CaretPosition - ContentLine.m_StartPosition;
										break;
									}

									++LineNumber;
								}

								SetCaretPosition(m_ContentLines[LineNumber].m_StartPosition, !ShiftActive);
							}
							else if (AltActive && !SuperActive)
							{
								{
									// Skip spaces to the left
									auto LookAt = m_CaretPosition - 1;
									while (   LookAt != -1
										   && !IsCoreCharacter(m_Content[LookAt]))
									{
										--LookAt;
									}

									// Skip non-spaces to the left
									while (   LookAt != -1
										   && IsCoreCharacter(m_Content[LookAt]))
									{
										--LookAt;
									}

									SetCaretPosition(LookAt + 1, !ShiftActive);
								}
							}
							else
							{
								MoveCaretTry(-1, !ShiftActive);
							}
						}
					}
					break;
				case GLFW_KEY_RIGHT:
					{
						if (0 != SelectionLength && !ShiftActive)
						{
							SetCaretPosition(std::max(m_CaretPosition, m_SelectionPosition), true);
						}
						else
						{
							if (SuperActive && !AltActive)
							{
								std::vector<class ContentLine>::size_type LineNumber = 0;
								std::vector<class ContentLine>::size_type ColumnNumber = 0;

								for (auto & ContentLine : m_ContentLines)
								{
									if (ContentLine.m_StartPosition + ContentLine.m_Length >= m_CaretPosition)
									{
										ColumnNumber = m_CaretPosition - ContentLine.m_StartPosition;
										break;
									}

									++LineNumber;
								}

								SetCaretPosition(m_ContentLines[LineNumber].m_StartPosition + m_ContentLines[LineNumber].m_Length, !ShiftActive);
							}
							else if (AltActive && !SuperActive)
							{
								{
									// Skip spaces to the right
									auto LookAt = m_CaretPosition;
									while (   LookAt < m_Content.length()
										   && !IsCoreCharacter(m_Content[LookAt]))
									{
										++LookAt;
									}

									// Skip non-spaces to the right
									while (   LookAt < m_Content.length()
										   && IsCoreCharacter(m_Content[LookAt]))
									{
										++LookAt;
									}

									SetCaretPosition(LookAt, !ShiftActive);
								}
							}
							else
							{
								MoveCaretTry(+1, !ShiftActive);
							}
						}
					}
					break;
				case GLFW_KEY_UP:
					{
						if (0 != SelectionLength && !ShiftActive)
						{
							SetCaretPosition(std::min(m_CaretPosition, m_SelectionPosition), true);
						}

						if (SuperActive)
						{
							SetCaretPosition(0, !ShiftActive);		// Go to home
						}
						else
						{
							MoveCaretVerticallyTry(-1, !ShiftActive);
						}
					}
					break;
				case GLFW_KEY_DOWN:
					{
						if (0 != SelectionLength && !ShiftActive)
						{
							SetCaretPosition(std::max(m_CaretPosition, m_SelectionPosition), true);
						}

						if (SuperActive)
						{
							SetCaretPosition(m_Content.length(), !ShiftActive);		// Go to end
						}
						else
						{
							MoveCaretVerticallyTry(+1, !ShiftActive);
						}
					}
					break;
				case 'A':
					{
						if (SuperActive)
						{
							// Select all
							SetCaretPosition(0, true);
							SetCaretPosition(m_Content.length(), false);
						}
					}
					break;
				case 'X':
					{
						if (SuperActive)
						{
							if (!GetSelectionContent().empty())
							{
#if DECISION_USE_CLIPBOARD_INSTEAD_OF_TypingModule
								glfwSetClipboardString(GetSelectionContent());
#else
								m_TypingModule.SetString(GetSelectionContent());
#endif

								EraseSelectionIfAny();
							}
						}
					}
					break;
				case 'C':
					{
						if (SuperActive)
						{
							if (!GetSelectionContent().empty())
							{
#if DECISION_USE_CLIPBOARD_INSTEAD_OF_TypingModule
								glfwSetClipboardString(GetSelectionContent());
#else
								m_TypingModule.SetString(GetSelectionContent());
#endif
							}
						}
					}
					break;
				case 'V':
					{
						if (SuperActive)
						{
							if (!glfwGetClipboardString().empty())
							{
								EraseSelectionIfAny();

#if DECISION_USE_CLIPBOARD_INSTEAD_OF_TypingModule
								m_Content.insert(m_CaretPosition, glfwGetClipboardString());
								UpdateContentLines();
								MoveCaret(static_cast<sint32>(glfwGetClipboardString().length()), true);
#else
								auto Entry = m_TypingModule.TakeString();

								m_Content.insert(m_CaretPosition, Entry);
								UpdateContentLines();
								MoveCaret(static_cast<sint32>(Entry.length()), true);
#endif
							}
						}
					}
					break;
				default:
					HandledEvent = false;
					break;
				}

				if (HandledEvent)
				{
					InputEvent.m_Handled = true;
				}
			}
		}
		else if (Pointer::VirtualCategory::POINTING == InputEvent.m_Pointer->GetVirtualCategory())
		{
			if (Pressed)
			{
				switch (ButtonId)
				{
				case 0:
					{
						Vector2n GlobalPosition(InputEvent.m_Pointer->GetPointerState().GetAxisState(0).GetPosition(), InputEvent.m_Pointer->GetPointerState().GetAxisState(1).GetPosition());
						Vector2n LocalPosition = GlobalToLocal(GlobalPosition);
						LocalPosition = m_TypingModule.GetInsertionPosition(LocalPosition);

						auto CaretPosition = GetNearestCaretPosition(LocalPosition);

						auto ShiftActive = g_InputManager->m_TypingPointer->GetPointerState().GetButtonState(GLFW_KEY_LSHIFT) || g_InputManager->m_TypingPointer->GetPointerState().GetButtonState(GLFW_KEY_RSHIFT);
						SetCaretPosition(CaretPosition, !ShiftActive);

						{
							auto Entry = m_TypingModule.TakeString();

							if (!Entry.empty())
							{
								m_Content.insert(m_CaretPosition, Entry);
								UpdateContentLines();
								SetCaretPosition(GetNearestCaretPosition(LocalPosition), true);
							}
						}
					}
					break;
				default:
					break;
				}
			}
		}
	}

	if (   InputEvent.m_EventTypes.end() != InputEvent.m_EventTypes.find(InputEvent::EventType::AXIS_EVENT)
		|| InputEvent.m_EventTypes.end() != InputEvent.m_EventTypes.find(InputEvent::EventType::CANVAS_MOVED_TEST))
	{
		if (Pointer::VirtualCategory::POINTING == InputEvent.m_Pointer->GetVirtualCategory())
		{
			if (true == InputEvent.m_Pointer->GetPointerState().GetButtonState(0))
			{
				Vector2n GlobalPosition(InputEvent.m_Pointer->GetPointerState().GetAxisState(0).GetPosition(), InputEvent.m_Pointer->GetPointerState().GetAxisState(1).GetPosition());
				Vector2n LocalPosition = GlobalToLocal(GlobalPosition);

				auto CaretPosition = GetNearestCaretPosition(LocalPosition);

				SetCaretPosition(CaretPosition, false);
			}
		}
	}
}
static void ImGui_ImplGlfwVulkan_SetClipboardText(const char* text)
{
    glfwSetClipboardString(g_Window, text);
}
TextFileWidget::TextFileWidget(Vector2n Position, std::string Path, TypingModule & TypingModule)
	: FlowLayoutWidget(Position, {
		std::shared_ptr<Widget>(new FlowLayoutWidget(Vector2n::ZERO, {
			std::shared_ptr<Widget>(m_FileMinimizeToggle = new ToggleWidget(Vector2n::ZERO, Vector2n(12, 12), [](bool State) { if (!State) g_InputManager->RequestTypingPointer(*static_cast<GestureRecognizer *>(nullptr)); }, true)),
			std::shared_ptr<Widget>(new LabelWidget(Vector2n(0, -lineHeight - 2), Path, LabelWidget::Background::Normal))
		}, {})),
		std::shared_ptr<Widget>(m_TextFieldWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule))
	}, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }, FlowLayoutWidget::LayoutType::Vertical),
	  m_Path(Path)
{
	m_TextFieldWidget->SetContent(FromFileToString(Path));
	m_OnChange = [=]()		// Saving takes place in TextFileWidget when it gets its NotifyChange() from the contained TextFieldWidget
	{
		//PlayBeep();
		//printf("Saving '%s'.\n", Path.c_str());

		// Write to file
		WriteToFile(Path, m_TextFieldWidget->GetContent());
	};

	const std::string Folder = ParsePath(Path, 0);
	const std::string Filename = ParsePath(Path, 1);

	auto CopyPath = [this, &TypingModule]() {
#if DECISION_USE_CLIPBOARD_INSTEAD_OF_TypingModule
		glfwSetClipboardString(this->m_Path);
#else
		TypingModule.SetString(this->m_Path);
#endif
	};
	ModifyGestureRecognizer().AddShortcut(GestureRecognizer::ShortcutEntry('I', PointerState::Modifiers::Super, CopyPath, "Copy Path"));

	// TEST: Line Gutters
#if 0
	//if ("./Gen/5086673/gistfile1.go" == Path)
	m_TextFieldWidget->m_GetLineGutters = [=](uint32 LineNumber) -> std::string
	{
#if 0
		std::string x = "."; Ls(x);
		return std::to_string(LineNumber + 1);
#endif
		// HACK: Pass file folder and name info
		if (0 == LineNumber)
			return Folder;
		else if (1 == LineNumber)
			return Filename;
		else
			throw 0;
	};
#endif

	if (IsFileTrackedByGit(Path)) {
		auto GitDiff = new GitDiffWidget(Vector2n::ZERO, TypingModule, this);
		GitDiff->RemoveAllBehaviors();
		AddWidget(GitDiff);

		auto GitCommit = new ButtonWidget(Vector2n(-160, -350), [=, &TypingModule]() {
				auto Shell = std::unique_ptr<ShellWidget>(new ShellWidget(Vector2n::ZERO, TypingModule));
				std::string Command = "cd \'" + Folder + "\'\ngit commit --allow-empty-message -m '' -- \'" + Filename + "\'";
				Command += "\ngit push origin master";
				Shell->m_CommandWidget->SetContent(Command);
				Shell->m_ExecuteWidget->GetAction()();
				this->NotifyExternalChange();		// Do this to triger potential GitDiffWidget, GitStatusWidget, etc.

				//std::cerr << "Commit & Push: '" << Folder << "' folder and '" << Filename << "' file.\n";
				std::cerr << Shell->m_OutputWidget->GetContent() << endl;
			},
			"Commit & Push");
		AddWidget(GitCommit);
	}

	m_TextFieldWidget->m_MinimizeToggle = m_FileMinimizeToggle;
}