void RegRichTextCtrl::OnLeftClick( wxMouseEvent& event ) { SetFocus(); wxClientDC dc(this); PrepareDC(dc); dc.SetFont(GetFont()); long position = 0; int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position); if (hit != wxRICHTEXT_HITTEST_NONE) { bool caretAtLineStart = false; if (hit & wxRICHTEXT_HITTEST_BEFORE) { // If we're at the start of a line (but not first in para) // then we should keep the caret showing at the start of the line // by showing the m_caretAtLineStart flag. wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(position); wxRichTextLine* line = GetBuffer().GetLineAtPosition(position); if (line && para && line->GetAbsoluteRange().GetStart() == position && para->GetRange().GetStart() != position) caretAtLineStart = true; position--; } MoveCaret(position, caretAtLineStart); SelectWord(GetCaretPosition()); } }
bool ezConsole::ProcessInputCharacter(ezUInt32 uiChar) { switch (uiChar) { case 27: // Escape ClearInputLine(); return false; case '\b': // backspace { if (!m_sInputLine.IsEmpty() && m_iCaretPosition > 0) { RemoveCharacter(m_iCaretPosition - 1); MoveCaret(-1); } } return false; case '\t': AutoCompleteInputLine(); return false; case 13: // Enter AddToInputHistory(m_sInputLine.GetData()); ProcessCommand(m_sInputLine.GetData()); ClearInputLine(); return false; } return true; }
void TextBox::KeydownRight() { if (m_position < m_text.size()) { auto charWidth = GetWindow()->GetFont()->GetCharSize(m_text[m_position]); ++m_position; MoveCaret(charWidth); } }
void TextBox::KeydownLeft() { if (m_position > 0) { --m_position; auto charWidth = static_cast<int>(GetWindow()->GetFont()->GetCharSize(m_text[m_position])); assert(charWidth > 0); MoveCaret(-charWidth); } }
void TextFieldWidget::ProcessCharacter(InputEvent & InputEvent, const uint32 Character) { if (Character < 128u) { EraseSelectionIfAny(); m_Content.insert(m_CaretPosition, 1, static_cast<uint8>(Character)); UpdateContentLines(); MoveCaret(+1, true); InputEvent.m_Handled = true; } }
void TextBox::OnTextInput(const SDL_TextInputEvent& textEvent) { GetWindow()->SetCursorHidden(true); if (m_position == m_text.size()) m_text.append(textEvent.text); else m_text.insert(m_position, textEvent.text); auto charWidth = GetWindow()->GetFont()->GetTextSize(textEvent.text); MoveCaret(charWidth); ++m_position; m_texture = GetWindow()->CreateTextureForText(m_text, GetWindow()->GetFont(), GetForegroundColor(), GetBackgroundColor()); }
void TextBox::KeydownBackspace() { if (m_position == 0) return; auto charWidth = static_cast<int>(GetWindow()->GetFont()->GetCharSize(m_text[m_position - 1])); assert(charWidth > 0); if (m_position == m_text.size()) m_text.pop_back(); else m_text.erase(m_position - 1, 1); m_texture = GetWindow()->CreateTextureForText(m_text, GetWindow()->GetFont(), GetForegroundColor(), GetBackgroundColor()); --m_position; // don't move the caret if the string is bigger than the text box if (m_texture.GetWidth() < GetLocation().w - (TextOffsetX * 2) + CaretWidth) { MoveCaret(-charWidth); } else if (m_clipOffset > 0) { if (m_clipOffset < charWidth) { // if there is a single character being clipped // move the caret by the number of visible pixels. MoveCaret(-(charWidth - m_clipOffset)); m_clipOffset = 0; } else { m_clipOffset -= charWidth; } } }
/************************************************************************ * * MouseHandler - WM_BUTTONDOWN handler * ************************************************************************/ void MouseHandler( HWND hWnd, LONG lParam ) { if ( ( gImeUIData.ImeState & IME_IN_CHOSECAND ) || ( gImeUIData.ImeState & IME_IN_COMPOSITION && !MoveCaret( hWnd ) ) ) return; HideCaret( hWnd ); // // Calculate caret position based on fixed pitched font // yPos = MAKEPOINTS(lParam).y / cyMetrics; xPos = MAKEPOINTS(lParam).x / cxMetrics; // // Adjust caret position if click landed on a trail byte // if ( IsDBCSTrailByte( (LPSTR)textbuf[yPos], (LPSTR)&(textbuf[yPos][xPos]) ) ) { // // If click landed on the last quarter of the DBCS character, // assume the user was aiming at the next character. // if ( (MAKEPOINTS(lParam).x - xPos * cxMetrics) > (cxMetrics / 2) ) xPos++; else xPos--; } DestroyCaret(); CreateCaret(hWnd, NULL, (fInsertMode && IsDBCSLeadByte( textbuf[yPos][xPos] )) ? CaretWidth*2 : CaretWidth, cyMetrics ); SetCaretPos( xPos * cxMetrics, yPos * cyMetrics ); ShowCaret( hWnd ); }
void ezConsole::AddInputCharacter(ezUInt32 uiChar) { if (uiChar == '\0') return; if (!ProcessInputCharacter(uiChar)) return; if (!FilterInputCharacter(uiChar)) return; ClampCaretPosition(); auto it = m_sInputLine.GetIteratorFront(); it += m_iCaretPosition; ezUInt32 uiString[2] = { uiChar, 0 }; m_sInputLine.Insert(it.GetData(), ezStringUtf8(uiString).GetData()); MoveCaret(1); }
void VirtualKeyHandler( HWND hWnd, UINT wParam ) { int i; HDC hdc; static int delta = 1; if ( ( gImeUIData.ImeState & IME_IN_CHOSECAND ) || ( gImeUIData.ImeState & IME_IN_COMPOSITION && !MoveCaret( hWnd ) ) ) return; switch( wParam ) { case VK_HOME: // beginning of line xPos = FIRSTCOL; break; case VK_END: // end of line xPos = LASTCOL; goto check_for_trailbyte; case VK_RIGHT: if ( IsDBCSLeadByte( textbuf[yPos][xPos] ) ) { if (xPos==LASTCOL - 1) break; //last character don't move xPos += 2; //skip 2 for DB Character } else { xPos = min( xPos + 1, LASTCOL ); } break; case VK_LEFT: xPos = max( xPos - 1, FIRSTCOL ); check_for_trailbyte: if ( IsDBCSTrailByte( (LPSTR)textbuf[yPos], (LPSTR)&(textbuf[yPos][xPos]) ) ) xPos--; break; case VK_UP: yPos = max( yPos - 1, FIRSTROW ); goto Virtical_Check_Trail; case VK_DOWN: yPos = min( yPos + 1, LASTROW ); Virtical_Check_Trail: if ( IsDBCSTrailByte( (LPSTR)textbuf[yPos], (LPSTR)&(textbuf[yPos][xPos]) ) ) { if (xPos<LASTCOL) { xPos+=delta; delta *= -1; } else { xPos--; } } break; case VK_INSERT: // // Change caret shape to indicate insert/overtype mode // fInsertMode = !fInsertMode; CaretWidth = fInsertMode ? cxMetrics : cxOverTypeCaret; break; case VK_BACK: // backspace if ( xPos > FIRSTCOL ) { xPos--; // // DB Character so backup one more to allign on boundary // if ( IsDBCSTrailByte( (LPSTR)textbuf[yPos], (LPSTR)&(textbuf[yPos][xPos]) ) ) xPos--; // // Fall Through to VK_DELETE to adjust row // } else //FIRST COLUMN don't backup -- this would change for wrapping { break; } case VK_DELETE: if ( !IsDBCSLeadByte( textbuf[yPos][xPos] ) ) { // // Move rest of line left by one, then blank out last character // for ( i = xPos; i < LASTCOL; i++ ) { textbuf[yPos][i] = textbuf[yPos][i+1]; } textbuf[yPos][LASTCOL] = ' '; } else { // // Move line left by two bytes, blank out last two bytes // for ( i = xPos; i < LASTCOL-1; i++ ) { textbuf[yPos][i] = textbuf[yPos][i+2]; } textbuf[yPos][LASTCOL-1] = ' '; textbuf[yPos][LASTCOL] = ' '; } // // Repaint the entire line // hdc = GetDC( hWnd ); HideCaret( hWnd ); TextOut( hdc, 0, yPos*cyMetrics, (LPSTR)textbuf[yPos], MAXCOL ); ReleaseDC( hWnd, hdc ); break; case VK_TAB: // tab -- tabs are column allignment not character { int xTabMax = xPos + TABSTOP; int xPosPrev; do { xPosPrev = xPos; SendMessage( hWnd, WM_KEYDOWN, VK_RIGHT, 1L ); } while ( (xPos % TABSTOP) && (xPos < xTabMax) && (xPos != xPosPrev)); } break; case VK_RETURN: // linefeed yPos = min( yPos+1, LASTROW ); xPos = FIRSTCOL; break; } ResetCaret( hWnd ); }
void ezConsole::DoDefaultInputHandling(bool bConsoleOpen) { if (!m_bDefaultInputHandlingInitialized) { m_bDefaultInputHandlingInitialized = true; ezInputActionConfig cfg; cfg.m_bApplyTimeScaling = true; cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyLeft; ezInputManager::SetInputActionConfig("Console", "MoveCaretLeft", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyRight; ezInputManager::SetInputActionConfig("Console", "MoveCaretRight", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyHome; ezInputManager::SetInputActionConfig("Console", "MoveCaretStart", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyEnd; ezInputManager::SetInputActionConfig("Console", "MoveCaretEnd", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyDelete; ezInputManager::SetInputActionConfig("Console", "DeleteCharacter", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyPageUp; ezInputManager::SetInputActionConfig("Console", "ScrollUp", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyPageDown; ezInputManager::SetInputActionConfig("Console", "ScrollDown", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyUp; ezInputManager::SetInputActionConfig("Console", "HistoryUp", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyDown; ezInputManager::SetInputActionConfig("Console", "HistoryDown", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyF2; ezInputManager::SetInputActionConfig("Console", "RepeatLast", cfg, true); cfg.m_sInputSlotTrigger[0] = ezInputSlot_KeyF3; ezInputManager::SetInputActionConfig("Console", "RepeatSecondLast", cfg, true); return; } if (bConsoleOpen) { if (ezInputManager::GetInputActionState("Console", "MoveCaretLeft") == ezKeyState::Pressed) MoveCaret(-1); if (ezInputManager::GetInputActionState("Console", "MoveCaretRight") == ezKeyState::Pressed) MoveCaret(1); if (ezInputManager::GetInputActionState("Console", "MoveCaretStart") == ezKeyState::Pressed) MoveCaret(-1000); if (ezInputManager::GetInputActionState("Console", "MoveCaretEnd") == ezKeyState::Pressed) MoveCaret(1000); if (ezInputManager::GetInputActionState("Console", "DeleteCharacter") == ezKeyState::Pressed) DeleteNextCharacter(); if (ezInputManager::GetInputActionState("Console", "ScrollUp") == ezKeyState::Pressed) Scroll(10); if (ezInputManager::GetInputActionState("Console", "ScrollDown") == ezKeyState::Pressed) Scroll(-10); if (ezInputManager::GetInputActionState("Console", "HistoryUp") == ezKeyState::Pressed) SearchInputHistory(1); if (ezInputManager::GetInputActionState("Console", "HistoryDown") == ezKeyState::Pressed) SearchInputHistory(-1); const ezUInt32 uiChar = ezInputManager::RetrieveLastCharacter(); if (uiChar != '\0') AddInputCharacter(uiChar); } else { const ezUInt32 uiChar = ezInputManager::RetrieveLastCharacter(false); char szCmd[16] = ""; char* szIterator = szCmd; ezUnicodeUtils::EncodeUtf32ToUtf8(uiChar, szIterator); *szIterator = '\0'; ExecuteBoundKey(szCmd); } if (ezInputManager::GetInputActionState("Console", "RepeatLast") == ezKeyState::Pressed) { if (GetInputHistory().GetCount() >= 1) ProcessCommand(GetInputHistory()[0].GetData()); } if (ezInputManager::GetInputActionState("Console", "RepeatSecondLast") == ezKeyState::Pressed) { if (GetInputHistory().GetCount() >= 2) ProcessCommand(GetInputHistory()[1].GetData()); } }
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); } } } }