void ConceptionTestApp::UpdateWindowDimensions(Vector2n WindowDimensions) { // TODO: This is a hack, I should create a WindowResize listener type of thing and take care within Widget itself static_cast<Canvas *>(m_Widgets[0].get())->SetDimensions(WindowDimensions + Vector2n(-200, -200)); static_cast<Canvas *>(m_Widgets[1].get())->SetDimensions(Vector2n(300, 500)); static_cast<Canvas *>(m_Widgets[2].get())->SetDimensions(WindowDimensions); }
LiveFunctionWidget::LiveFunctionWidget(Vector2n Position, TypingModule & TypingModule, Project & Project) : CompositeWidget(Position, { std::shared_ptr<Widget>(m_ToggleWidget = new ToggleWidget(Vector2n(-1, -18), [=](bool State) { m_LiveProgramWidget->m_SourceWidget->m_Visible = State; }, true)), std::shared_ptr<Widget>(new FlowLayoutWidget(Vector2n::ZERO, { std::shared_ptr<Widget>(m_InputWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule)), std::shared_ptr<Widget>(m_SourceWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule)), std::shared_ptr<Widget>(m_LiveProgramWidget = new LiveProgramWidget(Vector2n::ZERO, TypingModule, Project)) }, { })) }, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }) { m_LiveProgramWidget->RemoveAllBehaviors(); // With live test execution and all m_SourceWidget->m_OnChange = [=, &Project]() { std::ostringstream GenProgram; Project.GenerateProgramForFunction(GenProgram, m_InputWidget->GetContent(), m_SourceWidget->GetContent()); m_LiveProgramWidget->m_SourceWidget->SetContent(GenProgram.str()); }; m_InputWidget->m_OnChange = m_SourceWidget->m_OnChange; { auto ImportList = new ListWidget<ConceptId>(Vector2n::ZERO, Project.GetStdIncludes(), TypingModule); auto pTypingModule = &TypingModule; ImportList->m_TapAction = [=](Vector2n LocalPosition, std::vector<ConceptId> & m_List) { auto Entry = pTypingModule->TakeString(); if (!Entry.empty()) { auto ConceptId = FindOrCreateConcept(Entry); //Insert(ConceptId); // TEST auto Spot = m_List.begin() + (LocalPosition.Y() / lineHeight); m_List.insert(Spot, ConceptId); } else { auto ListEntry = static_cast<decltype(m_List.size())>(LocalPosition.Y() / lineHeight); if (ListEntry < m_List.size()) { pTypingModule->SetString(GetConcept(m_List[ListEntry]).GetContent()); m_List.erase(m_List.begin() + ListEntry); } } }; auto LabelledImportList = new FlowLayoutWidget(Vector2n(-280, -100), { std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("import (\""), LabelWidget::Background::None)), std::shared_ptr<Widget>(ImportList), std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("\")"), LabelWidget::Background::None)) }, {}); static_cast<FlowLayoutWidget *>(GetWidgets()[1].get())->AddWidget(LabelledImportList); } }
MultitouchTestBoxWidget::MultitouchTestBoxWidget(Vector2n Position) : Widget(Position, Vector2n(200, 200), { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }), // m_GestureRecognizerTEST(), m_Color(rand() % 6) // HACK { // m_GestureRecognizerTEST.m_Widget = this; // m_GestureRecognizerTEST.m_OnTap = &MultitouchTestBoxWidget::ProcessTap; ModifyGestureRecognizer().m_RecognizeTap = true; }
void TextFieldWidget::ProcessManipulationStarted(const PointerState & PointerState) { if (!HasTypingFocus()) { auto ParentLocalPosition = GlobalToParent(Vector2n(PointerState.GetAxisState(0).GetPosition(), PointerState.GetAxisState(1).GetPosition())); ModifyGestureRecognizer().m_ManipulationOffset = GetPosition() - ParentLocalPosition; } }
void DraggablePositionBehavior::ProcessManipulationUpdate(const PointerState & PointerState) { if (!m_Widget.HasTypingFocus()) { auto ParentLocalPosition = m_Widget.GlobalToParent(Vector2n(PointerState.GetAxisState(0).GetPosition(), PointerState.GetAxisState(1).GetPosition())); m_Widget.ModifyPosition() = m_Widget.GetGestureRecognizer().m_ManipulationOffset + ParentLocalPosition; } }
template <typename T> void ListWidget<T>::ProcessManipulationUpdated(const PointerState & PointerState) { if (!HasTypingFocus()) { auto ParentLocalPosition = GlobalToParent(Vector2n(PointerState.GetAxisState(0).GetPosition(), PointerState.GetAxisState(1).GetPosition())); ModifyPosition() = GetGestureRecognizer().m_ManipulationOffset + ParentLocalPosition; } }
void MultitouchTestBoxWidget::ProcessManipulationUpdate(const InputEvent & InputEvent) { const PointerState & PointerState = InputEvent.m_PostEventState; //printf("MultitouchTestBoxWidget::ProcessManipulationUpdate()\n"); /*Vector2d PositionDouble = GetParent()->GlobalToCanvas(Vector2n(PointerState.GetAxisState(0).GetPosition(), PointerState.GetAxisState(1).GetPosition())); Vector2n PositionInt(std::lround(PositionDouble.X()), std::lround(PositionDouble.Y())); // TODO: Loss of accuracy? Fix it if needed.*/ auto ParentLocalPosition = GlobalToParent(Vector2n(PointerState.GetAxisState(0).GetPosition(), PointerState.GetAxisState(1).GetPosition())); ModifyPosition() = GetGestureRecognizer().m_ManipulationOffset + ParentLocalPosition; }
template <typename T> ListWidget<T>::ListWidget(Vector2n Position, std::vector<T> & List, TypingModule & TypingModule) #if DECISION_LIST_WIDGET_IS_COMPOSITE : CompositeWidget(Position, { std::shared_ptr<Widget>(new ButtonWidget(Vector2n(-1, -17), Vector2n(lineHeight, lineHeight), [&]() { // TEST: This is specific stuff for quick testing if (!m_Entries.empty()) { m_Entries.pop_back(); } } )) }, {}), #else : Widget(Position, Vector2n::ZERO, {}), #endif m_Entries(List), m_TypingModule(TypingModule) { ModifyGestureRecognizer().m_RecognizeTap = true; UpdateDimensions(); }
void OpenGLStream::NewLine() { if (Color(1.0, 1.0, 1.0) != m_BackgroundColor) { glPushAttrib(GL_ALL_ATTRIB_BITS); DrawBox(m_CaretPosition, Vector2n(charWidth, lineHeight), m_BackgroundColor, m_BackgroundColor); glPopAttrib(); } m_CaretPosition.X() = m_LineStartX; m_CaretPosition.Y() += lineHeight; }
// Prints a segment that doesn't contain line breaks, tabs void OpenGLStream::PrintSegment(const std::string & Segment) { if (Color(1.0, 1.0, 1.0) != m_BackgroundColor) { glPushAttrib(GL_ALL_ATTRIB_BITS); DrawBox(m_CaretPosition, Vector2n(static_cast<sint32>(Segment.length()) * charWidth, lineHeight), m_BackgroundColor, m_BackgroundColor); glPopAttrib(); } OglUtilsPrint(m_CaretPosition.X(), m_CaretPosition.Y(), 0, LEFT, Segment.c_str()); m_CaretPosition.X() += Segment.length() * charWidth; }
void OpenGLStream::Tab() { auto NewCaretPositionX = m_LineStartX + (((m_CaretPosition.X() - m_LineStartX) / charWidth / 4) + 1) * 4 * charWidth; if (Color(1.0, 1.0, 1.0) != m_BackgroundColor) { glPushAttrib(GL_ALL_ATTRIB_BITS); DrawBox(m_CaretPosition, Vector2n(NewCaretPositionX - m_CaretPosition.X(), lineHeight), m_BackgroundColor, m_BackgroundColor); glPopAttrib(); } m_CaretPosition.X() = NewCaretPositionX; }
// TODO: I've made this into a multi-line edit box, so change class name from Field (i.e. 1 line) to Box TextFieldWidget::TextFieldWidget(Vector2n Position, TypingModule & TypingModule) : Widget(Position, Vector2n(904, (3 + 2/*f.body_lines.size()*/) * lineHeight)), m_OnChange(), m_Content(), m_ContentLines(), m_MaxLineLength(0), m_CaretPosition(0), m_TargetCaretColumnX(0), m_SelectionPosition(0), m_TypingModule(TypingModule), m_BackgroundColor(static_cast<uint8>(255), 255, 255) { ModifyGestureRecognizer().m_RecognizeTap = true; ModifyGestureRecognizer().m_RecognizeDoubleTap = true; ModifyGestureRecognizer().m_RecognizeManipulationTranslate = true; UpdateContentLines(); // This is here at least for resize }
void FlowLayoutWidget::Render() { // HACK: This doesn't belong in Render, etc. // TODO: Support for invisible widgets (i.e. they shouldn't add 2 points of space) for (auto WidgetToLayout = 0; WidgetToLayout < GetWidgets().size(); ++WidgetToLayout) { if (0 == WidgetToLayout) { GetWidgets()[WidgetToLayout]->SetPosition(Vector2n::ZERO); } else { GetWidgets()[WidgetToLayout]->SetPosition(Vector2n(GetWidgets()[WidgetToLayout - 1]->GetPosition().X() + GetWidgets()[WidgetToLayout - 1]->GetDimensions().X() + 2, 0)); } } CompositeWidget::Render(); }
// Process a window resize event void GLFWCALL InputManager::ProcessWindowSize(int WindowWidth, int WindowHeight) { // Set the viewport size glViewport(0, 0, WindowWidth, WindowHeight); // Update the projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, WindowWidth, WindowHeight, 0); glMatrixMode(GL_MODELVIEW); m_pInstance->m_WindowDimensions = Vector2n(WindowWidth, WindowHeight); printf("Window Dimensions: %dx%d\n", m_pInstance->m_WindowDimensions.X(), m_pInstance->m_WindowDimensions.Y()); if (nullptr != m_pInstance->m_InputHandler) { InputEvent InputEvent; InputEvent.m_EventTypes.insert(InputEvent::EventType::PARENT_SIZE); // TODO: Maybe put the event details inside? m_pInstance->m_InputHandler->ProcessEvent(InputEvent); } }
LiveProgramFileWidget::LiveProgramFileWidget(Vector2n Position, std::string Path, TypingModule & TypingModule, Project & Project) : FlowLayoutWidget(Position, { std::shared_ptr<Widget>(m_SourceFileWidget = new TextFileWidget(Vector2n::ZERO, Path, TypingModule)), std::shared_ptr<Widget>(m_ProgramWidget = new ProgramWidget(Vector2n::ZERO, TypingModule, Project, m_SourceFileWidget->m_TextFieldWidget)) }, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }), m_SourceWidget(m_SourceFileWidget->m_TextFieldWidget) { m_SourceFileWidget->RemoveAllBehaviors(); m_ProgramWidget->RemoveAllBehaviors(); m_SourceWidget->m_GetAutocompletions = GetAutocompletions(m_SourceFileWidget->GetPath()); // Add Dependee connector to the source widget (for connecting text fields that the source widget depends on) for (int i = 0; i < 3; ++i) { auto Dependee = new ConnectionWidget<TextFieldWidget>(Vector2n(-16 - 2, (16 + 2) * i)); // TODO: Should do NotifyExternalChange() as long as I don't expect the contents of this thing to actually depend on the dependee... Dependee->m_OnChange = [=]() { m_SourceWidget->NotifyChange(); }; m_SourceWidget->AddWidget(Dependee); } ModifyGestureRecognizer().AddShortcut(GestureRecognizer::ShortcutEntry('R', PointerState::Modifiers::Super, [=]() { m_SourceWidget->NotifyChange(true); }, "Run/Refresh")); }
SayWidget::SayWidget(Vector2n Position, TypingModule & TypingModule) : FlowLayoutWidget(Position, { std::shared_ptr<Widget>(m_InputWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule)), std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("say"), LabelWidget::Background::Normal))/*, std::shared_ptr<Widget>(m_ExecuteWidget = new ButtonWidget(Vector2n::ZERO, Vector2n(16, 16), [&](){} ))*/ }, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }) { // TEST m_InputWidget->SetContent("Shall we play a game?"); { m_ExecuteWidget = new ButtonWidget(Vector2n::ZERO, Vector2n(16, 16), [](){}); m_ExecuteWidget->SetAction([&]() { { auto Pid = fork(); if (0 == Pid) { execl("/usr/bin/say", "/usr/bin/say", m_InputWidget->GetContent().c_str(), (char *)0); // TODO: Add error checking on above execl(), and do exit() in case execution reaches here //exit(1); // Not needed, just in case I comment out the above } else if (-1 == Pid) { std::cerr << "Error forking.\n"; throw 0; } else { } } }); } ModifyGestureRecognizer().AddShortcut(GestureRecognizer::ShortcutEntry('R', PointerState::Modifiers::Super, m_ExecuteWidget->GetAction())); }
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; } } }
DebugOverlayWidget::DebugOverlayWidget(CanvasWidget * MainCanvas) : CanvasWidget(Vector2n::ZERO, false, false) { { auto Content = []() -> std::string { std::ostringstream out; out << "Mouse.PntrMppng.m_Entries.size(): " << g_InputManager->m_MousePointer->ModifyPointerMapping().m_Entries.size(); for (auto & i : g_InputManager->m_MousePointer->ModifyPointerMapping().m_Entries) { PrintName(out, i); auto LocalPosition = dynamic_cast<Widget *>(&i->GetOwner())->GlobalToLocal(Vector2n(g_InputManager->m_MousePointer->GetPointerState().GetAxisState(0).GetPosition(), g_InputManager->m_MousePointer->GetPointerState().GetAxisState(1).GetPosition())); out << " [" << static_cast<Widget *>(&i->GetOwner())->GetDimensions().X() << ", " << static_cast<Widget *>(&i->GetOwner())->GetDimensions().Y() << "]"; out << " (" << LocalPosition.X() << ", " << LocalPosition.Y() << ")"; out << " <" << static_cast<Widget *>(&i->GetOwner())->m_DebugDescription << ">"; } out << "\nKB.PntrMppng.m_Entries.size(): " << g_InputManager->m_TypingPointer->ModifyPointerMapping().m_Entries.size(); for (auto & i : g_InputManager->m_TypingPointer->ModifyPointerMapping().m_Entries) { PrintName(out, i); } return out.str(); }; AddWidget(new LabelWidget(Vector2n(0, 18), Content)); } { auto Content = []() -> std::string { std::ostringstream out; out << "InputManager.m_IEQueue.m_Queue" << std::endl; for (auto & i : g_InputManager->m_InputEventQueue.m_Queue) { out << i.ToString() << std::endl; } return out.str(); }; AddWidget(new LabelWidget(Vector2n(0, 240), Content)); } // Visualizer of currently available shortcuts { auto Content = []() -> std::string { std::ostringstream out; std::map<GestureRecognizer::ShortcutEntry::Key, GestureRecognizer::ShortcutEntry &> AvailShortcuts; // Find all non-overlapping available shortcuts for (auto & i : g_InputManager->m_TypingPointer->ModifyPointerMapping().m_Entries) { for (auto & S : i->m_Shortcuts) { // TODO: Highlight shortcuts that can be activated in current state (e.g. Cmd+O does nothing when a folder is selected, etc.) // Only add this shortcut if there isn't any other overlapping one (i.e., with the same signature <Modifier, InputId>) auto Key = decltype(AvailShortcuts)::key_type(S.InputId, S.Modifiers); if (AvailShortcuts.end() == AvailShortcuts.find(Key)) AvailShortcuts.insert(decltype(AvailShortcuts)::value_type(Key, S)); } } // Print out all available shortcuts (in some sorted order) for (auto & aS : AvailShortcuts) { auto & S = aS.second; if (PointerState::Modifiers::Super == S.Modifiers) // TODO: Make this more general (Modifier -> string) out << "Cmd+"; switch (S.InputId) { case GLFW_KEY_F3: out << "F3"; break; default: out << static_cast<char>(S.InputId); break; } out << " - " << S.Description; out << endl; } return out.str(); }; // TODO: Make it right aligned to edge of screen AddWidget(new LabelWidget(Vector2n(1536 - 19 * charWidth, lineHeight + 2), Content)); } // Time in top right corner // TODO: Add support for reference frames other than top left corner as origin auto TimeWidget = new class TimeWidget(Vector2n(1536 - 13 * charWidth - 1, 1)); //TimeWidget->SetPosition(TimeWidget->GetPosition() - Vector2n(TimeWidget->GetDimensions().X(), 0)); // This doesn't work because its dimensions are updated after render... AddWidget(TimeWidget); // Visibility toggle { auto ToggleWidget = new class ToggleWidget(Vector2n(1, 1), [=](bool State) { // Toggle visibility of all widgets but the last one (i.e. this toggle) // TODO: Fix problem where upon initialize, OnChange is called before this widget has been added, so 2nd last widget is not hidden for (auto Widget = GetWidgets().begin(); GetWidgets().end() != Widget && GetWidgets().end() - 3 != Widget; ++Widget) { (*Widget)->m_Visible = State; } }, false); AddWidget(ToggleWidget); ProcessTimePassed(0); // HACK: Get all the widgets actually added ToggleWidget->UpdateHACK(); } }
void GestureRecognizer::ProcessEvent(InputEvent & InputEvent) { // DEBUG: This check is probably not needed anymore... it should always pass, due to new architecture if (true == InputEvent.m_Handled) { printf("Exception in void GestureRecognizer::ProcessEvent(InputEvent & InputEvent), InputEvent.m_Handled is not false!"); throw 0; return; } // DECISION /*#if 1 // TEST: Capture the pointer if the pointer is activated (via primary button) if ( InputEvent.HasType(InputEvent::EventType::POINTER_ACTIVATION) && ( InputEvent.HasType(InputEvent::EventType::BUTTON_EVENT) && 0 == InputEvent.m_InputId && true == InputEvent.m_Buttons[0])) { InputEvent.m_Pointer->ModifyPointerMapping().RequestPointerCapture(this); } // Release the pointer capture if the pointer is deactivated if (InputEvent.HasType(InputEvent::EventType::POINTER_DEACTIVATION)) { InputEvent.m_Pointer->ModifyPointerMapping().RequestPointerRelease(this); } #endif*/ // EXPERIMENTAL /*if ( m_RecognizeDoubleTap && !InputEvent.m_Handled) { if ( InputEvent.HasType(InputEvent::EventType::BUTTON_EVENT) && 0 == InputEvent.m_InputId && false == InputEvent.m_Buttons[0] && std::fabs(InputEvent.m_Pointer->GetPointerState().GetTimestamp() - m_LastTapCompletedStateTEST.GetTimestamp()) <= 0.400 && (Vector2n(InputEvent.m_Pointer->GetPointerState().GetAxisState(0).GetPosition(), InputEvent.m_Pointer->GetPointerState().GetAxisState(1).GetPosition()) - Vector2n(m_LastTapStateTEST.GetAxisState(0).GetPosition(), m_LastTapStateTEST.GetAxisState(1).GetPosition())).LengthSquared() <= (3 * 3)) { printf("Recognized a double tap of %f ms.\n", std::fabs(InputEvent.m_Pointer->GetPointerState().GetTimestamp() - m_LastTapCompletedStateTEST.GetTimestamp()) * 1000); InputEvent.m_Handled = true; m_Owner.ProcessDoubleTap(InputEvent, Vector2n(m_LastTapStateTEST.GetAxisState(0).GetPosition(), m_LastTapStateTEST.GetAxisState(1).GetPosition())); m_LastTapCompletedStateTEST.InvalidateTEST(); } }*/ // TODO: Fix bug where dragging the object out of down-event range and then bringing it back still activates the tap (it shouldn't) /*if ( m_RecognizeTap && !InputEvent.m_Handled) { if ( InputEvent.HasType(InputEvent::EventType::BUTTON_EVENT) && 0 == InputEvent.m_InputId && true == InputEvent.m_Buttons[0]) { m_LastTapStateTEST = InputEvent.m_Pointer->GetPointerState(); } else if ( InputEvent.HasType(InputEvent::EventType::BUTTON_EVENT) && 0 == InputEvent.m_InputId && false == InputEvent.m_Buttons[0] //&& std::fabs(InputEvent.m_Timestamp - m_LastTapEventTEST.m_Timestamp) <= 1.0) && (Vector2n(InputEvent.m_Pointer->GetPointerState().GetAxisState(0).GetPosition(), InputEvent.m_Pointer->GetPointerState().GetAxisState(1).GetPosition()) - Vector2n(m_LastTapStateTEST.GetAxisState(0).GetPosition(), m_LastTapStateTEST.GetAxisState(1).GetPosition())).LengthSquared() <= (3 * 3)) { printf("Recognized a tap.\n"); InputEvent.m_Handled = true; m_Owner.ProcessTap(InputEvent, Vector2n(m_LastTapStateTEST.GetAxisState(0).GetPosition(), m_LastTapStateTEST.GetAxisState(1).GetPosition())); m_LastTapCompletedStateTEST = m_LastTapStateTEST; } }*/ //if (m_RecognizeDrag) /*{ if ( InputEvent.HasType(InputEvent::EventType::AXIS_EVENT) && 0 == InputEvent.m_InputId && true == InputEvent.GetPointerState().GetButtonState(0)) { //printf("Recognized a drag by (%d, %d).\n", InputEvent.m_Sliders[0], InputEvent.m_Sliders[1]); //double Scaler = GetAttached().size(); //printf("GetAttached().size() %d\n", GetAttached().size()); //m_Owner.ProcessDrag(Vector2d(InputEvent.m_Sliders[0] / Scaler, InputEvent.m_Sliders[1] / Scaler)); m_Owner.ProcessDrag(Vector2d(InputEvent.m_Sliders[0], InputEvent.m_Sliders[1])); // TODO: Figure out this GetAttached() stuff } }*/ if ( m_RecognizeScroll && !InputEvent.m_Handled) { if ( InputEvent.HasType(InputEvent::EventType::AXIS_EVENT) && 2 == InputEvent.m_InputId) { //printf("Recognized a wheel move by %d.\n", InputEvent.m_Sliders[0]); m_Owner.ProcessScroll(InputEvent, Vector2n(InputEvent.m_Sliders[0], InputEvent.m_Sliders[1])); InputEvent.m_Handled = true; } } // TODO: Support for manipulation with >1 pointer simultaneously (including translation, as well as rotation/scale) /*if ( m_RecognizeManipulationTranslate && !InputEvent.m_Handled) { if ( InputEvent.HasType(InputEvent::EventType::BUTTON_EVENT) && 0 == InputEvent.m_InputId && true == InputEvent.m_Buttons[0]) { m_InManipulation = true; m_Owner.ProcessManipulationBegin(InputEvent.m_Pointer->GetPointerState()); // DECISION //InputEvent.m_Pointer->ModifyPointerMapping().RequestPointerCapture(this); // TEST InputEvent.m_Handled = true; } if ( InputEvent.HasType(InputEvent::EventType::AXIS_EVENT) && 0 == InputEvent.m_InputId && true == InputEvent.m_Pointer->GetPointerState().GetButtonState(0)) { //double Scaler = GetAttached().size(); m_Owner.ProcessManipulationUpdate(InputEvent.m_Pointer->GetPointerState()); // DECISION //InputEvent.m_Pointer->ModifyPointerMapping().RequestPointerCapture(this); // TEST InputEvent.m_Handled = true; } if ( InputEvent.HasType(InputEvent::EventType::BUTTON_EVENT) && 0 == InputEvent.m_InputId && false == InputEvent.m_Buttons[0]) { m_InManipulation = false; m_Owner.ProcessManipulationEnd(InputEvent.m_Pointer->GetPointerState()); // DECISION //InputEvent.m_Pointer->ModifyPointerMapping().RequestPointerRelease(this); // TEST InputEvent.m_Handled = true; } }*/ //if ( m_RecognizeCharacters if ( true && !InputEvent.m_Handled) { if (InputEvent.HasType(InputEvent::EventType::CHARACTER_EVENT)) { m_Owner.ProcessCharacter(InputEvent, InputEvent.m_InputId); //InputEvent.m_Handled = true; } } // TODO: There might be duplication here this way, I think I should eliminate it (by providing a complete alternative gesture-level api for all events // Low-level event passthrough if (!InputEvent.m_Handled) { m_Owner.ProcessEvent(InputEvent); } }
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; }
MultitouchTestApp::MultitouchTestApp(InputManager & InputManager) : App(InputManager) { { #if 0 auto MainCanvas = new Canvas(Vector2n(300, 0), true, true); MainCanvas->m_BlackBackgroundTEST = true; MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(-200 - 5, -200 - 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(0 + 5, -200 - 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(-200 - 5, 0 + 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(0 + 5, 0 + 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(100 + 5, 100 + 5))); m_Widgets.push_back(std::unique_ptr<Widget>(MainCanvas)); // MainCanvas #else /// Canvas inside Canvas test auto OuterCanvasTEST = new Canvas(Vector2n(0, 0), true, true); auto MainCanvas = new Canvas(Vector2n(-100, -340), true, true); MainCanvas->m_BlackBackgroundTEST = true; OuterCanvasTEST->AddWidget(MainCanvas); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(-200 - 5, -200 - 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(0 + 5, -200 - 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(-200 - 5, 0 + 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(0 + 5, 0 + 5))); MainCanvas->AddWidget(new MultitouchTestBoxWidget(Vector2n(100 + 5, 100 + 5))); OuterCanvasTEST->AddWidget(new MultitouchTestBoxWidget(Vector2n(-300, 250))); MainCanvas->SetDimensions(Vector2n(500, 500)); m_Widgets.push_back(std::unique_ptr<Widget>(OuterCanvasTEST)); m_Widgets.push_back(std::unique_ptr<Widget>(new DebugOverlayWidget())); // DEBUG: Print debug info #endif } }
ConceptStringBoxWidget::ConceptStringBoxWidget(Vector2n Position, TypingModule & TypingModule) : Widget(Position, Vector2n(80 * charWidth, 24 * lineHeight), { /*std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this))*/ }), m_Content(), m_CaretPosition(0), m_TypingModule(TypingModule) { UpdateGestureRecognizer(); // DEBUG: Irregular starting state, for testing { /*m_Content.push_back(FindConcept("int")); m_Content.push_back(FindConcept("main")); m_Content.push_back(FindConcept("(")); m_Content.push_back(FindConcept("int")); m_Content.push_back(FindConcept("argc")); m_Content.push_back(FindConcept(",")); m_Content.push_back(FindConcept("char")); m_Content.push_back(FindConcept("*")); m_Content.push_back(FindConcept("argv")); m_Content.push_back(FindConcept(")")); m_Content.push_back(FindConcept("{")); m_Content.push_back(17); m_Content.push_back(FindConcept("(")); m_Content.push_back(FindConcept(")")); m_Content.push_back(FindConcept(";")); m_Content.push_back(FindConcept("return")); m_Content.push_back(FindConcept("0")); m_Content.push_back(FindConcept(";")); m_Content.push_back(FindConcept("}"));*/ /* // Skip non-spaces to the right auto LookAt = m_CaretPosition; while ( LookAt < m_Content.length() && IsCoreCharacter(m_Content[LookAt])) { ++LookAt; } SetCaretPosition(LookAt, false); */ /*m_Content.push_back(FindOrCreateConcept("// Skip non-spaces to the right")); m_Content.push_back(FindOrCreateConcept("auto LookAt = m_CaretPosition;")); m_Content.push_back(FindOrCreateConcept("while (")); m_Content.push_back(FindOrCreateConcept(" LookAt < m_Content.length()\n&& IsCoreCharacter(m_Content[LookAt])")); m_Content.push_back(FindOrCreateConcept(")")); m_Content.push_back(FindOrCreateConcept("{")); m_Content.push_back(FindOrCreateConcept("++LookAt;")); m_Content.push_back(FindOrCreateConcept("}")); m_Content.push_back(FindOrCreateConcept("")); m_Content.push_back(FindOrCreateConcept("SetCaretPosition(LookAt, false);"));*/ //m_Content.push_back(37); /*m_Content.push_back(38); m_Content.push_back(ConceptInstance(38, {33})); m_Content.push_back(ConceptInstance(39, {33}));*/ //m_Content.push_back(ConceptInstance(40, {36, 28})); m_Content.push_back(LastConceptId() - 2); } }
ConceptionApp::ConceptionApp(InputManager & InputManager) : App(InputManager), m_CurrentProject(), m_TypingModule(new TypingModule()) // Gets cleaned up via unique_ptr when pushed back to m_Widgets { PopulateConcepts(); { auto MainCanvas = new Canvas(Vector2n(0, 0), true, true); //MainCanvas->MoveView(0, 336); MainCanvas->MoveView(1, -64); #if 1 { auto StdIncludesList = new ListWidget<ConceptId>(Vector2n::ZERO, m_CurrentProject.GetStdIncludes(), *m_TypingModule); StdIncludesList->m_TapAction = [=](Vector2n LocalPosition, std::vector<ConceptId> & m_List) { auto Entry = m_TypingModule->TakeString(); if (!Entry.empty()) { auto ConceptId = FindOrCreateConcept(Entry); //Insert(ConceptId); // TEST auto Spot = m_List.begin() + (LocalPosition.Y() / lineHeight); m_List.insert(Spot, ConceptId); } else { auto ListEntry = static_cast<decltype(m_List.size())>(LocalPosition.Y() / lineHeight); if (ListEntry < m_List.size()) { m_TypingModule->SetString(GetConcept(m_List[ListEntry]).GetContent()); m_List.erase(m_List.begin() + ListEntry); } } }; auto LabelledStdIncludesList = new FlowLayoutWidget(Vector2n(-280, -250), { std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("#include <"), LabelWidget::Background::None)), std::shared_ptr<Widget>(StdIncludesList), std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string(">"), LabelWidget::Background::None)) }, {}); LabelledStdIncludesList->AddBehavior(std::shared_ptr<Behavior>(new DraggablePositionBehavior(*LabelledStdIncludesList))); MainCanvas->AddWidget(LabelledStdIncludesList); } #endif MainCanvas->AddWidget(new ButtonWidget(Vector2n(-100, -350), []() { std::cout << "Hi from anon func.\n"; } )); MainCanvas->AddWidget(new ButtonWidget(Vector2n(-60, -350), []() { std::cout << "Second button.\n"; } )); MainCanvas->AddWidget(new ToggleWidget(Vector2n(-20, -350), [](bool State) { std::cout << "Testing this toggle widget! It's now set to " << State << ".\n"; }, true)); MainCanvas->AddWidget(new LiveFunctionWidget(Vector2n(-100, 100), *m_TypingModule, m_CurrentProject)); MainCanvas->AddWidget(new LiveProgramWidget(Vector2n(-100, -300), *m_TypingModule, m_CurrentProject)); MainCanvas->AddWidget(new LiveProgramWidget(Vector2n(-100, -100), *m_TypingModule, m_CurrentProject)); MainCanvas->AddWidget(new LiveGofmtWidget(Vector2n(-460, 200), *m_TypingModule, m_CurrentProject)); MainCanvas->AddWidget(new TextFieldWidget(Vector2n(-460, 160), *m_TypingModule)); MainCanvas->AddWidget(new ShellWidget(Vector2n(-460, 60), *m_TypingModule)); MainCanvas->AddWidget(new SayWidget(Vector2n(-460, -100), *m_TypingModule)); MainCanvas->AddWidget(new ConceptStringBoxWidget(Vector2n(-400, 100 + 400), *m_TypingModule)); // TEST: Modify some Concept { auto Widget = new TextFieldWidget(Vector2n(-320, 470), *m_TypingModule); Widget->SetContent(GetConcept(47).GetContent()); Widget->m_OnChange = [=]() { static_cast<ConceptBasic &>(ModifyConcept(47)).SetContentTEST(Widget->GetContent()); }; Widget->AddBehavior(std::shared_ptr<Behavior>(new DraggablePositionBehavior(*Widget))); MainCanvas->AddWidget(Widget); } // Label resizing test { auto SourceWidget = new TextFieldWidget(Vector2n::ZERO, *m_TypingModule); auto Content = [=]() -> std::string { return SourceWidget->GetContent(); }; auto LabelWidget = new class LabelWidget(Vector2n::ZERO, Content, LabelWidget::Background::Normal); MainCanvas->AddWidget(new FlowLayoutWidget(Vector2n(-100, -450), { std::shared_ptr<Widget>(SourceWidget), std::shared_ptr<Widget>(LabelWidget) }, {})); } // Time widget { auto Content = []() -> std::string { auto now = std::chrono::system_clock::now(); auto duration = now.time_since_epoch(); auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration).count(); return std::to_string(seconds); }; auto LabelWidget = new class LabelWidget(Vector2n(360, -340), Content, LabelWidget::Background::Normal); LabelWidget->AddBehavior(std::shared_ptr<Behavior>(new DraggablePositionBehavior(*LabelWidget))); MainCanvas->AddWidget(LabelWidget); } MainCanvas->AddWidget(new TimeWidget(Vector2n(360, -360))); // Time widget #if 0 // "./GenProgram.go" file contents displayed (in real-time) in this Label Widget { auto Content = []() -> std::string { //return FromFileToString("./GenProgram.go"); return FromFileToString("/Users/Dmitri/Desktop/goproj_play/src/gist.github.com/4670289.git/gistfile1.go"); }; auto LabelWidget = new class LabelWidget(Vector2n(-546, -186), Content, LabelWidget::Background::Normal); LabelWidget->AddBehavior(std::shared_ptr<Behavior>(new DraggablePositionBehavior(*LabelWidget))); MainCanvas->AddWidget(LabelWidget); } #endif #if 1 { MainCanvas->AddWidget(new ListWidget<Concept *>(Vector2n(-730 - 450, -250), Concepts, *m_TypingModule)); } #endif m_Widgets.push_back(std::unique_ptr<Widget>(m_TypingModule)); m_Widgets.push_back(std::unique_ptr<Widget>(MainCanvas)); m_Widgets.push_back(std::unique_ptr<Widget>(new DebugOverlayWidget())); // DEBUG: Print debug info } // Prepare and start the thread { m_CurrentProject.StartBackgroundThread(); } { // Load program m_CurrentProject.LoadSampleGenProgram(*static_cast<Canvas *>(m_Widgets[0].get())); } }
// TODO: Make a more direct implementation void DrawInnerRoundedBox(Vector2n Position, Vector2n Size, uint32 Radius, Color BackgroundColor, Color BorderColor) { DrawCircle(Position + Vector2n(Radius, Radius), Vector2n(Radius * 2, Radius * 2), BackgroundColor, BorderColor); if ( Size.X() < Radius * 2 || Size.Y() < Radius * 2) { return; } DrawCircle(Position + Vector2n(Size.X(), 0) + Vector2n(-Radius, Radius), Vector2n(Radius * 2, Radius * 2), BackgroundColor, BorderColor); DrawCircle(Position + Vector2n(0, Size.Y()) + Vector2n(Radius, -Radius), Vector2n(Radius * 2, Radius * 2), BackgroundColor, BorderColor); DrawCircle(Position + Size - Vector2n(Radius, Radius), Vector2n(Radius * 2, Radius * 2), BackgroundColor, BorderColor); { Position += Vector2n(Radius, 0); Size -= Vector2n(Radius * 2, 0); // DUPLICATION: A tweaked copy of DrawBox() { glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); glColor3dv(BorderColor.GetComponents()); glVertex2i(Position.X(), Position.Y()); glVertex2i(Position.X(), Position.Y() + Size.Y()); glVertex2i(Position.X() + Size.X(), Position.Y() + Size.Y()); glVertex2i(Position.X() + Size.X(), Position.Y()); glEnd(); glBegin(GL_QUADS); glColor3dv(BackgroundColor.GetComponents()); glVertex2i(Position.X(), +1 + Position.Y()); glVertex2i(Position.X(), -1 + Position.Y() + Size.Y()); glVertex2i(Position.X() + Size.X(), -1 + Position.Y() + Size.Y()); glVertex2i(Position.X() + Size.X(), +1 + Position.Y()); glEnd(); glEnable(GL_TEXTURE_2D); } } { Position += Vector2n(-Radius, Radius); Size += Vector2n(Radius * 2, -Radius * 2); // DUPLICATION: A tweaked copy of DrawBox() { glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); glColor3dv(BorderColor.GetComponents()); glVertex2i(Position.X(), Position.Y()); glVertex2i(Position.X(), Position.Y() + Size.Y()); glVertex2i(Position.X() + Size.X(), Position.Y() + Size.Y()); glVertex2i(Position.X() + Size.X(), Position.Y()); glEnd(); glBegin(GL_QUADS); glColor3dv(BackgroundColor.GetComponents()); glVertex2i(+1 + Position.X(), Position.Y()); glVertex2i(+1 + Position.X(), Position.Y() + Size.Y()); glVertex2i(-1 + Position.X() + Size.X(), Position.Y() + Size.Y()); glVertex2i(-1 + Position.X() + Size.X(), Position.Y()); glEnd(); glEnable(GL_TEXTURE_2D); } } }
ConceptionTestApp::ConceptionTestApp(InputManager & InputManager) : App(InputManager), m_CurrentProject(), m_TypingModule() /*OverlayCanvas(Vector2n(0, 0), false), SystemInputListener(), ControlModuleMapping0(), ControlModuleMapping1(), WidgetManager(), WidgetModule(WidgetManager), UnrealCameraModule(MainCanvas), UnrealCameraModule2TEST(MainCanvas2TEST), TypingModule(),*/ { /*{ { auto Widget = new ButtonWidget(Vector2n(10, 10)); WidgetManager.Add(Widget); Widget->SetOwnerCanvas(OverlayCanvas); } { auto Widget = new ButtonWidget(Vector2n(50, 10)); WidgetManager.Add(Widget); Widget->SetOwnerCanvas(OverlayCanvas); } { auto Widget = new TextFieldWidget(Vector2n(10, 50)); WidgetManager.Add(Widget); Widget->SetOwnerCanvas(OverlayCanvas); } { auto Widget = new ListWidget(Vector2n(-200, -292), CurrentProject.GetStdIncludes()); WidgetManager.Add(Widget); Widget->SetOwnerCanvas(MainCanvas); } } { std::vector<InputManager::InputId> ButtonMappings; ButtonMappings.push_back(InputManager::InputId(1000, GLFW_MOUSE_BUTTON_LEFT)); std::vector<InputManager::InputId> SliderMappings; std::vector<InputManager::InputId> AxisMappings; AxisMappings.push_back(InputManager::InputId(1000, 0)); AxisMappings.push_back(InputManager::InputId(1000, 1)); std::vector<InputManager::InputId> PositiveConstraints; std::vector<InputManager::InputId> NegativeConstraints; ControlModuleMapping0.AddMapping(&WidgetModule, 0, ButtonMappings, SliderMappings, AxisMappings, PositiveConstraints, NegativeConstraints); WidgetModule.SetOwnerCanvas(OverlayCanvas); } { std::vector<InputManager::InputId> ButtonMappings; ButtonMappings.push_back(InputManager::InputId(1000, GLFW_MOUSE_BUTTON_LEFT)); std::vector<InputManager::InputId> SliderMappings; SliderMappings.push_back(InputManager::InputId(1000, 0)); SliderMappings.push_back(InputManager::InputId(1000, 1)); SliderMappings.push_back(InputManager::InputId(1000, 2)); std::vector<InputManager::InputId> AxisMappings; AxisMappings.push_back(InputManager::InputId(1000, 0)); AxisMappings.push_back(InputManager::InputId(1000, 1)); std::vector<InputManager::InputId> PositiveConstraints; std::vector<InputManager::InputId> NegativeConstraints; ControlModuleMapping0.AddMapping(&UnrealCameraModule2TEST, 0, ButtonMappings, SliderMappings, AxisMappings, PositiveConstraints, NegativeConstraints); UnrealCameraModule2TEST.SetOwnerCanvas(MainCanvas2TEST); } { std::vector<InputManager::InputId> ButtonMappings; ButtonMappings.push_back(InputManager::InputId(1000, GLFW_MOUSE_BUTTON_LEFT)); std::vector<InputManager::InputId> SliderMappings; SliderMappings.push_back(InputManager::InputId(1000, 0)); SliderMappings.push_back(InputManager::InputId(1000, 1)); SliderMappings.push_back(InputManager::InputId(1000, 2)); std::vector<InputManager::InputId> AxisMappings; AxisMappings.push_back(InputManager::InputId(1000, 0)); AxisMappings.push_back(InputManager::InputId(1000, 1)); std::vector<InputManager::InputId> PositiveConstraints; std::vector<InputManager::InputId> NegativeConstraints; ControlModuleMapping0.AddMapping(&UnrealCameraModule, 0, ButtonMappings, SliderMappings, AxisMappings, PositiveConstraints, NegativeConstraints); UnrealCameraModule.SetOwnerCanvas(MainCanvas); } ControlModuleMapping0.DoneAdding(); g_TypingModuleTEST = &TypingModule; { std::vector<InputManager::InputId> ButtonMappings; ButtonMappings.push_back(InputManager::InputId(0, GLFW_KEY_BACKSPACE)); std::vector<InputManager::InputId> SliderMappings; std::vector<InputManager::InputId> AxisMappings; AxisMappings.push_back(InputManager::InputId(1000, 0)); AxisMappings.push_back(InputManager::InputId(1000, 1)); std::vector<InputManager::InputId> PositiveConstraints; std::vector<InputManager::InputId> NegativeConstraints; ControlModuleMapping1.AddMapping(&TypingModule, 0, ButtonMappings, SliderMappings, AxisMappings, PositiveConstraints, NegativeConstraints); TypingModule.SetOwnerCanvas(OverlayCanvas); } ControlModuleMapping1.DoneAdding(); m_InputManager.RegisterListener(&SystemInputListener); m_InputManager.RegisterListener(&ControlModuleMapping0); m_InputManager.RegisterListener(&ControlModuleMapping1);*/ /*{ MainCanvas.RenderBackground(); MainCanvas.SetupTransform(); { CurrentProject.Render(); WidgetManager.Render(MainCanvas); } MainCanvas.EndTransform(); } { MainCanvas2TEST.RenderBackground(); MainCanvas2TEST.SetupTransform(); { CurrentProject.Render(); WidgetManager.Render(MainCanvas2TEST); } MainCanvas2TEST.EndTransform(); } { OverlayCanvas.SetupTransform(); { WidgetManager.Render(OverlayCanvas); g_TypingModuleTEST->Render(); } OverlayCanvas.EndTransform(); }*/ { auto MainCanvas = new Canvas(Vector2n(50, 50), true, true); MainCanvas->AddWidget(new ButtonWidget(Vector2n(0, 0), []() {} )); MainCanvas->AddWidget(new ButtonWidget(Vector2n(10, 10), []() {} )); //MainCanvas->AddWidget(new ListWidget<ConceptId>(Vector2n(-200, -292), m_CurrentProject.GetStdIncludes())); MainCanvas->AddWidget(new TextFieldWidget(Vector2n(-400, -100), m_TypingModule)); m_Widgets.push_back(std::unique_ptr<Widget>(MainCanvas)); } { auto MainCanvas2TEST = new Canvas(Vector2n(800, 100), true, true); m_Widgets.push_back(std::unique_ptr<Widget>(MainCanvas2TEST)); } { auto OverlayCanvas = new Canvas(Vector2n(0, 0), false, false); OverlayCanvas->AddWidget(new ButtonWidget(Vector2n(10, 10), []() {} )); OverlayCanvas->AddWidget(new ButtonWidget(Vector2n(50, 10), []() {} )); //OverlayCanvas->AddWidget(new TextFieldWidget(Vector2n(10, 50))); //OverlayCanvas->AddWidget(new TextFieldWidget(Vector2n(10, 100))); //OverlayCanvas->AddWidget(new TextFieldWidget(Vector2n(10, 150))); m_Widgets.push_back(std::unique_ptr<Widget>(OverlayCanvas)); } { PopulateConcepts(); // Load program m_CurrentProject.LoadSampleGenProgram(*static_cast<Canvas *>(m_Widgets[0].get())); // HACK, TEST: Should use MainCanvas or something } }
FunctionWidget::FunctionWidget(Vector2n Position, Function & Function) : Widget(Position, Vector2n(904, (3 + 2/*f.body_lines.size()*/) * lineHeight), {}), m_Function(Function) { ModifyGestureRecognizer().m_RecognizeTap = true; }
const Vector2n DimensionsStream::GetDimensions() const { return Vector2n(std::max<sint32>(m_CaretPosition.X(), m_MaxLineLengthX), m_CaretPosition.Y() + lineHeight); }
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; }