Пример #1
0
Widget::~Widget()
{
	// DEBUG: Not sure if still need to do this now that widget is removed after event queue processing, but maybe still needed to rid of persistent pointers
	// For all connected pointers
	// DEBUG: Disabled because it caused intermittent crashing of FolderListingWidget...
	// DEBUG: Re-enabled because fixed root cause of crashing, it was this widget being deleted more than once because I wasn't resetting m_Child back to nullptr after deleting
	while (!ModifyGestureRecognizer().GetConnected().empty())
	{
		// Modify the pointer mapping of said pointer, and removed the widget which is being removed
		ModifyGestureRecognizer().GetConnected().begin().operator *()->ModifyPointerMapping().RemoveMapping(ModifyGestureRecognizer());
	}
}
void ConceptStringBoxWidget::UpdateGestureRecognizer()
{
	//ModifyGestureRecognizer().m_RecognizeTap = true;

	// HACK: Recognize only taps when unselected; but this needs to be automated
	ModifyGestureRecognizer().m_RecognizeTap = !HasTypingFocus();
}
void MultitouchTestBoxWidget::ProcessTap(const InputEvent & InputEvent, Vector2n Position)
{
	++m_Color;
	if (m_Color >= 6)
		m_Color = 0;

	g_InputManager->RequestTypingPointer(ModifyGestureRecognizer());
}
Пример #4
0
ButtonWidget::ButtonWidget(Vector2n Position, Vector2n Dimensions, std::function<void()> Action)
	: Widget(Position, Dimensions),
	  m_Action(Action)
{
	assert(nullptr != m_Action);

	ModifyGestureRecognizer().m_RecognizeTap = true;
}
Пример #5
0
void Widget::ProcessCanvasUpdated()
{
	/*if (nullptr != m_GestureRecognizerTEST)
	{
		m_GestureRecognizerTEST->ProcessCanvasUpdated();
	}*/
	ModifyGestureRecognizer().ProcessCanvasUpdated();
}
Пример #6
0
template <typename T> void ListWidget<T>::ProcessManipulationStarted(const PointerState & PointerState)
{
	if (!HasTypingFocus())
	{
		auto ParentLocalPosition = GlobalToParent(Vector2n(PointerState.GetAxisState(0).GetPosition(), PointerState.GetAxisState(1).GetPosition()));
		
		ModifyGestureRecognizer().m_ManipulationOffset = GetPosition() - ParentLocalPosition;
	}
}
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;
}
Пример #8
0
// 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
}
Пример #9
0
template <typename T> ListWidget<T>::ListWidget(Vector2n Position, std::vector<T> & List, TypingModule & TypingModule)
	: CompositeWidget(Position, {
		/*std::shared_ptr<Widget>(new ButtonWidget(Vector2n(-1, -18), Vector2n(lineHeight, lineHeight), [&]() {
			// TEST: This is specific stuff for quick testing
			if (!m_List.empty())
			{
				m_List.pop_back();
			}
		} ))*/ }),
	  m_TapAction(),
	  m_List(List),
	  m_TypingModule(TypingModule)
{
	ModifyGestureRecognizer().m_RecognizeTap = true;
	ModifyGestureRecognizer().m_RecognizeManipulationTranslate = true;

	UpdateDimensions();
}
Пример #10
0
template <typename T> MenuWidget<T>::MenuWidget(Vector2n Position, std::vector<T> & Entries, TypingModule * TypingModule)
    : Widget(Position, Vector2n::ZERO, {}),
m_Entries(Entries),
m_TypingModule(TypingModule)
{
    ModifyGestureRecognizer().m_RecognizeTap = true;

    UpdateDimensions();
}
void MultitouchTestBoxWidget::ProcessManipulationBegin(const InputEvent & InputEvent)
{
	const PointerState & PointerState = InputEvent.m_PostEventState;
	//printf("MultitouchTestBoxWidget::ProcessManipulationBegin()\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()));

	ModifyGestureRecognizer().m_ManipulationOffset = GetPosition() - ParentLocalPosition;
}
Пример #12
0
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();
}
Пример #13
0
GitDiffWidget::GitDiffWidget(Vector2n Position, TypingModule & TypingModule, TextFileWidget * Target)
	: FlowLayoutWidget(Position, { std::shared_ptr<Widget>(m_SourceWidget = new ConnectionWidget<TextFileWidget>(Vector2n::ZERO, Target)),
								   std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("git diff"), LabelWidget::Background::Normal)),
								   std::shared_ptr<Widget>(m_OutputWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule)) }, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) })
{
	m_OutputWidget->m_GetLineHighlighting = GetLineHighlighting();

	// TODO: Not quite sure if MinimizeToggle is applicable here, as the content is not really there
	// (By that, I mean that originally MinimizeToggle was meant to simply not render content which was actually valid, whereas here it's used to hide the output when the content is out of date)
	m_OutputWidget->m_MinimizeToggle = m_SourceWidget->m_LiveToggle;

	m_SourceWidget->m_OnChange = [&]()
	{
		std::string InOut = "";

		if (nullptr != m_SourceWidget->Target())
		{
			std::string Folder = ParsePath(m_SourceWidget->Target()->GetPath(), 0);
			std::string Filename = ParsePath(m_SourceWidget->Target()->GetPath(), 1);

			auto Shell = std::unique_ptr<ShellWidget>(new ShellWidget(Vector2n::ZERO, TypingModule));
			std::string Command = "cd \'" + Folder + "\'\ngit diff --no-ext-diff -- \'" + Filename + "\'";
			//Command += " | tail -n +5";		// Skip the first 4 lines (if any)
			Shell->m_CommandWidget->SetContent(Command);
			Shell->m_ExecuteWidget->GetAction()();
			InOut = Shell->m_OutputWidget->GetContent();

			SkipFirstLines(InOut, 4);

			TrimLastNewline(InOut);
		}

		m_OutputWidget->SetContent(InOut);
	};

	m_SourceWidget->m_OnChange();

	ModifyGestureRecognizer().AddShortcut(GestureRecognizer::ShortcutEntry('R', PointerState::Modifiers::Super, m_SourceWidget->m_OnChange, "Run/Refresh"));
}
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"));
}
Пример #15
0
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()));
}
Пример #16
0
void InputManager::RequestTypingPointer(GestureRecognizer & Target)
{
	// DECISION: Only allow pointer change when it's not captured
	if (nullptr == m_TypingPointer->GetPointerMapping().GetCapturer())
	//if (true)
	{
#if 0
		m_TypingPointer->ModifyPointerMapping().RemoveAllMappings();
		m_TypingPointer->ModifyPointerMapping().AddMapping(Target);
		m_TypingPointer->ModifyPointerMapping().DoneAdding();
#else
		m_TypingPointer->ModifyPointerMapping().RemoveAllMappings();
		if (nullptr != &Target)		// HACK: I should use pointer rather than reference (but too lazy to manually change all invokations...)
		{
			m_TypingPointer->ModifyPointerMapping().AddMapping(Target);
			for (auto Parent = static_cast<Widget *>(&Target.GetOwner())->ModifyParent(); nullptr != Parent; Parent = Parent->ModifyParent())
			{
				m_TypingPointer->ModifyPointerMapping().AddMapping(Parent->ModifyGestureRecognizer());
			}
		}
		m_TypingPointer->ModifyPointerMapping().DoneAdding();
#endif
	}
}
Пример #17
0
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;
}
Пример #18
0
ProgramWidget::ProgramWidget(Vector2n Position, TypingModule & TypingModule, Project & Project, TextFieldWidget * Target)
	: FlowLayoutWidget(Position, { std::shared_ptr<Widget>(m_SourceWidget = new ConnectionWidget<TextFieldWidget>(Vector2n::ZERO, Target)),
								   std::shared_ptr<Widget>(m_StdinWidget = new ConnectionWidget<TextFieldWidget>(Vector2n::ZERO)),
								   std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("go run"), LabelWidget::Background::Normal)),
								   std::shared_ptr<Widget>(m_OutputWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule)) }, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }),
	  m_Project(Project)
{
	// TODO: Not quite sure if MinimizeToggle is applicable here, as the content is not really there
	// (By that, I mean that originally MinimizeToggle was meant to simply not render content which was actually valid, whereas here it's used to hide the output when the content is out of date)
	m_OutputWidget->m_MinimizeToggle = m_SourceWidget->m_LiveToggle;

	{
		m_SourceWidget->m_OnChange = [=, &Project]()
		{
			//PlayBeep();

			Project.m_ProcessEndedTime = glfwGetTime();
			Project.m_BackgroundState = 0;

			// Kill child processes
			if (0 != Project.m_LastPid)
			{
				//std::cout << "Sending kill to last child pid " << Project.m_LastPid << ".\n";
				//auto Result = kill(0, SIGTERM);
				auto Result = killpg(Project.m_LastPid, SIGKILL);
				//waitpid(m_LastPid, NULL, 0);

				if (0 != Result) {
					std::cerr << "Error: kill() failed with return " << Result << ", errno " << errno << ".\n";
					//throw 0;
				}
			}

			//std::cout << "Closing " << Project.m_PipeFd[0] << " and " << Project.m_PipeFd[1] << "; ";
			close(Project.m_PipeFd[0]);		// Close the read end of the pipe in the parent
			Project.m_PipeFd[0] = Project.m_PipeFd[1] = -1;

			if (!m_SourceWidget->m_LiveToggle->GetState())
			{
				//OutputWidget.m_Visible = false;
				return;
			}
			else
			{
				//OutputWidget.m_Visible = true;
			}

			std::string Content = "";
			if (nullptr != m_SourceWidget->Target()) {
				Content = m_SourceWidget->Target()->GetContent();
			}
			Project.GenerateProgram(Content);
			Project.SetStdinContent(m_StdinWidget);

			g_OutputWidget = m_OutputWidget;		// HACK
			//m_OutputWidget->SetContent("");
			Project.m_ProcessStartedTime = glfwGetTime();
			Project.m_ExpiredOutput = true;
			Project.m_BackgroundState = 1;
		};

		m_StdinWidget->m_OnChange = m_SourceWidget->m_OnChange;

		// If there's already a Target for source, then refresh ourselves
		m_SourceWidget->m_OnChange();
	}

	ModifyGestureRecognizer().AddShortcut(GestureRecognizer::ShortcutEntry('R', PointerState::Modifiers::Super, m_SourceWidget->m_OnChange, "Run/Refresh"));

	m_GetLineAnnotations = [this](uint32 LineNumber) -> std::string
	{
		//return std::to_string(LineNumber + 1) + "-" + (m_ProgramWidget->m_OutputWidget->GetContent().length() >= 3 ? m_ProgramWidget->m_OutputWidget->GetContent().substr(0, 3) : "...");

		// HACK: Using hardcoded color, make this better
		// Don't do this if the result is not compile error, or if Live Toggle is off
		if (   Color(1.0, 0.9, 0.9) != this->m_OutputWidget->GetBackground()
			|| false == this->m_SourceWidget->m_LiveToggle->GetState())
			return "";

		// TODO: Clean up
		{
			std::stringstream ss;
			auto Input = this->m_OutputWidget->GetContent();
			TrimLastNewline(Input);
			ss << Input;
			std::string Line;

			// Skip first line if it starts with "#"
			if (Line.length() >= 1 && '#' == Line[0])
				std::getline(ss, Line);

			for (;;)
			{
				std::getline(ss, Line);

				// Parse one go error line
				try
				{
					auto FirstColon = Line.find(':');
					auto SecondColon = Line.find(':', FirstColon + 1);
					uint32 FoundLineNumber = std::stoi(Line.substr(FirstColon + 1, SecondColon - (FirstColon + 1)));

					if (FoundLineNumber == LineNumber + 1)
						return TrimFirstSpace(Line.substr(SecondColon + 1));
				}
				catch (...) {}

				if (ss.eof())
					break;
			}
		}
		return "";
	};
}
Пример #19
0
FunctionWidget::FunctionWidget(Vector2n Position, Function & Function)
    : Widget(Position, Vector2n(904, (3 + 2/*f.body_lines.size()*/) * lineHeight), {}),
m_Function(Function)
{
    ModifyGestureRecognizer().m_RecognizeTap = true;
}
Пример #20
0
void TextFieldWidget::ProcessTap(InputEvent & InputEvent, Vector2n Position)
{
	g_InputManager->RequestTypingPointer(ModifyGestureRecognizer());
}
void ConceptStringBoxWidget::ProcessTap(const InputEvent & InputEvent, Vector2n Position)
{
	g_InputManager->RequestTypingPointer(ModifyGestureRecognizer());
}