コード例 #1
0
ファイル: ListWidget.hpp プロジェクト: prinsmike/Conception
template <typename T> void ListWidget<T>::Render()
{
	Color BackgroundColor(1.0, 1.0, 1.0);
	Color BorderColor(0.3, 0.3, 0.3);

	/*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
	{
	}
	else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}
	else
	{
	}*/

	// TODO: Think if I should outsource the entire rendering code for more generality
	// Draw list
	{
		UpdateDimensions();		// LATER: Optimize by not repeating this calculation each time, only when something changes?

		if (m_List.empty())
		{
			BackgroundColor[0] = 234 / 255.0;
			BackgroundColor[1] = 233 / 255.0;
			BackgroundColor[2] = 190 / 255.0;
		}

		DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

		// TODO: This part is not general
		std::string Description[2] = { "#include <", ">" };
		glColor3d(0, 0, 0); OglUtilsPrint(GetPosition().X(), GetPosition().Y(), 0, RIGHT, Description[0].c_str());
		glColor3d(0, 0, 0); OglUtilsPrint(GetPosition().X() + GetDimensions().X(), GetPosition().Y(), 0, LEFT, Description[1].c_str());

		// TEST
		auto Spot = m_List.end();
		if (!m_TypingModule.GetString().empty())
		{
			for (auto & Pointer : GetGestureRecognizer().GetConnected())
			{
				if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
				{
					Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
					Vector2n LocalPosition(GlobalToLocal(GlobalPosition));

					Spot = m_List.begin() + (LocalPosition.Y() / lineHeight);
				}
			}
		}

		OpenGLStream OpenGLStream(GetPosition());
		for (auto ListEntry = m_List.begin(); m_List.end() != ListEntry; ++ListEntry)
		{
			if (ListEntry == Spot)
				OpenGLStream << endl;

			OpenGLStream << *ListEntry << endl;
		}
	}

	CompositeWidget::Render();
}
コード例 #2
0
MatchResult GestureRecognizer::MatchEventQueue(InputEventQueue::FilteredQueue & UnreservedEvents)
{
	auto InputEventIterator = UnreservedEvents.begin();
	auto & InputEvent = **InputEventIterator;

#if 1
	// If the pointer is not connected to this GR (meaning a failed HitTest), return failed match
	// DEBUG: Is this the right way to go about it? Or a temporary hack? Figure it out.
	if (   nullptr != InputEvent.m_Pointer
		&& GetConnected().end() == GetConnected().find(InputEvent.m_Pointer)
		&& nullptr == dynamic_cast<TypingModule *>(&m_Owner))		// HACK!! (To enable TypingModule to work, i.e. get input while not being pointed to)
	{
		m_InManipulation = false;		// HACK: Not sure if this is the best way of doing it

		return MatchResult();
	}
#else
	Vector2n GlobalPosition(InputEvent.m_PreEventState.GetAxisState(0).GetPosition(), InputEvent.m_PreEventState.GetAxisState(1).GetPosition());
	//printf("Global Pos %d, %d.\n", GlobalPosition.X(), GlobalPosition.Y());
	if (/*   !m_InManipulation
		&& */!static_cast<Widget &>(m_Owner).IsHit(static_cast<Widget &>(m_Owner).GlobalToParent(GlobalPosition))
		&& (   nullptr != InputEvent.m_Pointer
			&& GetConnected().end() == GetConnected().find(InputEvent.m_Pointer)))
	{
		return MatchResult();
	}
#endif

// DEBUG: I don't think the following is neccessary anymore, so I will try just setting Hit to true at all times and see if that breaks anything. If not, might as well remove this (unneccessary?) check
#if 0
	Vector2n GlobalPosition(InputEvent.m_PreEventState.GetAxisState(0).GetPosition(), InputEvent.m_PreEventState.GetAxisState(1).GetPosition());
	auto Hit = static_cast<Widget &>(m_Owner).IsHit(static_cast<Widget &>(m_Owner).GlobalToParent(GlobalPosition));
	/*if (!Hit) {
		std::cout << "OMGGG LOOK HERE!!!! Hit IS false\n";
	}*/
#else
	auto Hit = true;
#endif

	MatchResult Match;
	if (m_RecognizeDoubleTap && (Match = MatchDoubleTap2(UnreservedEvents, InputEventIterator)).AnySuccess())
	{
		if (2 == Match.Status)
		{
			m_Owner.ProcessDoubleTap(InputEvent, Vector2n((*InputEventIterator)->m_PostEventState.GetAxisState(0).GetPosition(), (*InputEventIterator)->m_PostEventState.GetAxisState(1).GetPosition()));
		}
	}
	else if (m_RecognizeTap && (Match = MatchTap2(UnreservedEvents, InputEventIterator)).AnySuccess())
	{
		if (2 == Match.Status)
		{
			m_Owner.ProcessTap(InputEvent, Vector2n((*InputEventIterator)->m_PostEventState.GetAxisState(0).GetPosition(), (*InputEventIterator)->m_PostEventState.GetAxisState(1).GetPosition()));
		}
	}
	else if (m_RecognizeManipulationTranslate && (Match = MatchManipulationBegin(UnreservedEvents, InputEventIterator, m_InManipulation, Hit, m_RecognizeManipulationTranslateButtonId)).AnySuccess())
	{
		if (2 == Match.Status)
		{
			m_InManipulation = true;
			m_Owner.ProcessManipulationBegin(InputEvent);
		}
	}
	else if (m_RecognizeManipulationTranslate && (Match = MatchManipulationUpdate(UnreservedEvents, InputEventIterator, m_InManipulation)).AnySuccess())
	{
		if (2 == Match.Status)
		{
			m_Owner.ProcessManipulationUpdate(InputEvent);
		}
	}
	else if (m_RecognizeManipulationTranslate && (Match = MatchManipulationEnd(UnreservedEvents, InputEventIterator, m_InManipulation, m_RecognizeManipulationTranslateButtonId)).AnySuccess())
	{
		if (2 == Match.Status)
		{
			m_Owner.ProcessManipulationEnd(InputEvent);
			m_InManipulation = false;
		}
	}
	else if (ProcessShortcuts(InputEvent))
	{
		Match.Status = 2;
		Match.Events.push_back(*InputEventIterator);
	}
	else if (ProcessEventHandledTEST(InputEvent))
	{
		Match.Status = 2;
		Match.Events.push_back(*InputEventIterator);
	}

	return Match;
}
コード例 #3
0
ファイル: MenuWidget.hpp プロジェクト: shurcooL/Conception
template <typename T> void MenuWidget<T>::Render()
{
    Color BackgroundColor(1.0, 1.0, 1.0);
    Color BorderColor(0.3, 0.3, 0.3);

    /*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
    {
    }
    else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
    {
    	BorderColor[0] = 0.898;
    	BorderColor[1] = 0.765;
    	BorderColor[2] = 0.396;
    }
    else
    {
    }*/
    // HACK, TODO: Make this a single DRY const
    if (HasTypingFocus())
    {
        BorderColor[0] = 0.898;
        BorderColor[1] = 0.765;
        BorderColor[2] = 0.396;
    }

    // TODO: Think if I should outsource the entire rendering code for more generality
    // Draw list
    {
        UpdateDimensions();		// LATER: Optimize by not repeating this calculation each time, only when something changes?

        if (m_Entries.empty())
        {
            BackgroundColor[0] = 234 / 255.0;
            BackgroundColor[1] = 233 / 255.0;
            BackgroundColor[2] = 190 / 255.0;
        }

        DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

        // TEST
        auto Spot = m_Entries.end();
        if (   nullptr != m_TypingModule
                && !m_TypingModule->GetString().empty())
        {
            for (auto & Pointer : GetGestureRecognizer().GetConnected())
            {
                if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
                {
                    Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
                    Vector2n LocalPosition(GlobalToLocal(GlobalPosition));

                    Spot = m_Entries.begin() + (LocalPosition.Y() / lineHeight);
                }
            }
        }

        OpenGLStream OpenGLStream(GetPosition());
        //for (auto & Entry : m_Entries)
        for (auto Entry = m_Entries.begin(); m_Entries.end() != Entry; ++Entry)
        {
            if (Entry == Spot)
                OpenGLStream << endl;

            if (Entry - m_Entries.begin() == m_SelectedEntryId)
            {
                if (HasTypingFocus())
                    DrawBox(GetPosition() + Vector2n(0, static_cast<sint32>((Entry - m_Entries.begin() + (Entry >= Spot)) * lineHeight)), Vector2n(GetDimensions().X(), lineHeight), m_SelectedColor, m_SelectedColor);
                else
                    DrawBox(GetPosition() + Vector2n(0, static_cast<sint32>((Entry - m_Entries.begin() + (Entry >= Spot)) * lineHeight)), Vector2n(GetDimensions().X(), lineHeight), m_UnfocusedSelectedColor, m_UnfocusedSelectedColor);
            }

            OpenGLStream << *Entry << endl;
        }
    }
}
コード例 #4
0
ファイル: MenuWidget.hpp プロジェクト: shurcooL/Conception
template <typename T> void MenuWidget<T>::ProcessEvent(InputEvent & InputEvent)
{
    if (InputEvent.HasType(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)
            {
                const auto ControlActive = (   InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_LCTRL)
                                               || InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_RCTRL));
                const auto ShiftActive = (   InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_LSHIFT)
                                             || InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_RSHIFT));
                const auto SuperActive = (   InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_LSUPER)
                                             || InputEvent.m_Pointer->GetPointerState().GetButtonState(GLFW_KEY_RSUPER));
                const 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_UP:
                {
                    if (!SuperActive) {
                        if (m_SelectedEntryId > 0)
                            SetSelectedEntryId(m_SelectedEntryId - 1);
                    } else {
                        SetSelectedEntryId(0);
                    }
                }
                break;
                case GLFW_KEY_DOWN:
                {
                    if (!SuperActive) {
                        if (m_SelectedEntryId < m_Entries.size() - 1)
                            SetSelectedEntryId(m_SelectedEntryId + 1);
                    } else {
                        SetSelectedEntryId(m_Entries.size() - 1);
                    }
                }
                break;
                default:
                    HandledEvent = false;
                    break;
                }

                if (HandledEvent)
                {
                    InputEvent.m_Handled = true;
                }
            }
        }
    }

    if (HasTypingFocus())
    {
        if (   InputEvent.HasType(InputEvent::EventType::AXIS_EVENT)
                || InputEvent.HasType(InputEvent::EventType::CANVAS_MOVED_TEST))
        {
            if (Pointer::VirtualCategory::POINTING == InputEvent.m_Pointer->GetVirtualCategory())
            {
                if (true == InputEvent.m_Pointer->GetPointerState().GetButtonState(0))
                {
                    if (!(   nullptr != m_TypingModule
                             && !m_TypingModule->GetString().empty()))
                    {
                        Vector2n GlobalPosition(InputEvent.m_Pointer->GetPointerState().GetAxisState(0).GetPosition(), InputEvent.m_Pointer->GetPointerState().GetAxisState(1).GetPosition());
                        Vector2n LocalPosition = GlobalToLocal(GlobalPosition);

                        SetSelectedEntryId(LocalPosition);
                    }
                }
            }
        }
    }
}
コード例 #5
0
template <typename T> void ListWidget<T>::Render()
{
	Color BackgroundColor(1.0, 1.0, 1.0);
	Color BorderColor(0.3, 0.3, 0.3);

	/*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
	{
	}
	else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}
	else
	{
	}*/

	// TODO: Think if I should outsource the entire rendering code for more generality
	// Draw list
	{
		UpdateDimensions();		// LATER: Optimize by not repeating this calculation each time, only when something changes?

		if (m_Entries.empty())
		{
			BackgroundColor[0] = 234 / 255.0;
			BackgroundColor[1] = 233 / 255.0;
			BackgroundColor[2] = 190 / 255.0;
		}

		DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

		// TEST
		auto Spot = m_Entries.end();
		if (!m_TypingModule.GetString().empty())
		{
			for (auto & Pointer : GetGestureRecognizer().GetConnected())
			{
				if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
				{
					Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
					Vector2n LocalPosition(GlobalToLocal(GlobalPosition));

					Spot = m_Entries.begin() + (LocalPosition.Y() / lineHeight);
				}
			}
		}

		OpenGLStream OpenGLStream(GetPosition());
		for (auto Entry = m_Entries.begin(); m_Entries.end() != Entry; ++Entry)
		{
			if (Entry == Spot)
				OpenGLStream << endl;

			OpenGLStream << *Entry << endl;
		}
	}

#if DECISION_LIST_WIDGET_IS_COMPOSITE
	CompositeWidget::Render();
#endif
}
コード例 #6
0
void TextFieldWidget::Render()
{
	//Color BackgroundColor(1.0, 1.0, 1.0);
	Color BackgroundColor = m_BackgroundColor;
	Color BorderColor(0.3, 0.3, 0.3);

	/*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
	{
	}
	else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}
	else
	{
	}*/
	//if (CheckHover())
	// HACK
	if (HasTypingFocus())
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}

	/*glBegin(GL_QUADS);
		glVertex2d(m_Position.X(), m_Position.Y());
		glVertex2d(m_Position.X(), m_Position.Y() + 30);
		glVertex2d(m_Position.X() + 30, m_Position.Y() + 30);
		glVertex2d(m_Position.X() + 30, m_Position.Y());
	glEnd();*/
	DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

	// TEST
	auto ContentWithInsertion = m_Content;
	if (!m_TypingModule.GetString().empty())
	{
		for (auto & Pointer : GetGestureRecognizer().GetConnected())
		{
			if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
			{
				Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
				Vector2n LocalPosition(GlobalToLocal(GlobalPosition));
				LocalPosition = m_TypingModule.GetInsertionPosition(LocalPosition);

				auto InsertionPosition = GetNearestCaretPosition(LocalPosition);
				ContentWithInsertion.insert(InsertionPosition, m_TypingModule.GetString());
			}
		}
	}

	glColor3d(0, 0, 0);
	OpenGLStream OpenGLStream(GetPosition());
	OpenGLStream << ContentWithInsertion.substr(0, std::min(m_CaretPosition, m_SelectionPosition));

	Vector2n CaretPosition;

	// Remember caret position at selection front
	if (std::min(m_CaretPosition, m_SelectionPosition) == m_CaretPosition)
	{
		CaretPosition = OpenGLStream.GetCaretPosition();
	}

	// Draw selected text as highlighted
	if (HasTypingFocus())
	{
		OpenGLStream.SetBackgroundColor(Color(static_cast<uint8>(195), 212, 242));
	}
	else
	{
		OpenGLStream.SetBackgroundColor(Color(static_cast<uint8>(212), 212, 212));
	}
	auto SelectionLength = std::max(m_CaretPosition, m_SelectionPosition) - std::min(m_CaretPosition, m_SelectionPosition);
	OpenGLStream << ContentWithInsertion.substr(std::min(m_CaretPosition, m_SelectionPosition), SelectionLength);
	OpenGLStream.SetBackgroundColor(Color(1.0, 1.0, 1.0));

	// Remember caret position at selection back
	if (std::max(m_CaretPosition, m_SelectionPosition) == m_CaretPosition)
	{
		CaretPosition = OpenGLStream.GetCaretPosition();
	}

	OpenGLStream << ContentWithInsertion.substr(std::max(m_CaretPosition, m_SelectionPosition));

	//if (CheckHover())
	// HACK
	if (HasTypingFocus())
	{
		// Draw caret
		//if (static_cast<int>(glfwGetTime() * 2) % 2)
		{
			glPushMatrix();
			glTranslated(CaretPosition.X(), CaretPosition.Y(), 0);
			glColor3d(0, 0, 0);
			glBegin(GL_QUADS);
				glVertex2d(-1, 0);
				glVertex2d(-1, lineHeight);
				glVertex2d(+1, lineHeight);
				glVertex2d(+1, 0);
			glEnd();
			glPopMatrix();
		}
	}
}
コード例 #7
0
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);
			}
		}
	}
}