Skip to content

Commit ac11ea6

Browse files
committed
added basic editor for multiline selection
1 parent 1268538 commit ac11ea6

File tree

2 files changed

+126
-88
lines changed

2 files changed

+126
-88
lines changed

YALCT/ShaderEditor.cs

+125-87
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class ShaderEditor : IImGuiComponent
2121
private bool autoApply = true;
2222
private float autoApplyCurrentInterval = 0;
2323

24+
private bool basicMode = false;
2425
private int editorSelectedLineIndex = -1;
2526
private string editorSelectedLineContent = null;
2627
private int editorSelectedLineCursorPosition = -1;
@@ -165,101 +166,32 @@ private unsafe void SubmitEditorWindow()
165166
if (ImGui.Begin("Shader Editor"))
166167
{
167168
ImGui.PushFont(Controller.EditorFont);
168-
Vector2 editorWindowSize = ImGui.GetWindowSize();
169-
if (ImGui.BeginChild("editor", Vector2.Zero, true))
169+
if (ImGui.BeginTabBar("editor mode"))
170170
{
171-
// handle basic input
172-
if (editorSelectedLineIndex != -1)
171+
if (ImGui.BeginTabItem("Advanced"))
173172
{
174-
if ((editorSelectedLineCursorPosition == 0 && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.LeftArrow), false))
175-
|| ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.UpArrow), true))
176-
{
177-
SetSelectedLine(editorSelectedLineIndex - 1);
178-
}
179-
if ((editorSelectedLineCursorPosition == editorSelectedLineContent.Length && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.RightArrow), false))
180-
|| ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.DownArrow), true))
181-
{
182-
SetSelectedLine(editorSelectedLineIndex + 1);
183-
}
184-
if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Enter), true))
185-
{
186-
string newLineContent = "";
187-
if (editorSelectedLineCursorPosition != editorSelectedLineContent.Length)
188-
{
189-
fragmentCodeLines[editorSelectedLineIndex] = editorSelectedLineContent.Take(editorSelectedLineCursorPosition).ToSystemString();
190-
newLineContent = editorSelectedLineContent.Skip(editorSelectedLineCursorPosition).ToSystemString();
191-
}
192-
fragmentCodeLines.Insert(editorSelectedLineIndex + 1, newLineContent);
193-
SetSelectedLine(editorSelectedLineIndex + 1);
194-
}
195-
if (editorSelectedLineIndex > 0)
196-
{
197-
if (editorSelectedLineCursorPosition == 0 && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Backspace), true))
198-
{
199-
if (!string.IsNullOrEmpty(editorSelectedLineContent))
200-
{
201-
fragmentCodeLines[editorSelectedLineIndex - 1] += editorSelectedLineContent;
202-
}
203-
fragmentCodeLines.RemoveAt(editorSelectedLineIndex);
204-
SetSelectedLine(editorSelectedLineIndex - 1);
205-
}
206-
}
173+
basicMode = false;
174+
SubmitAdvancedEditor();
175+
ImGui.EndTabItem();
207176
}
208-
209-
// draw lines
210-
for (int i = 0; i < fragmentCodeLines.Count; i++)
177+
if (ImGui.BeginTabItem("Basic"))
211178
{
212-
string line = fragmentCodeLines[i];
213-
string lineNumber = $"{i + Controller.Context.FragmentHeaderLineCount}";
214-
bool isError = errorMessages.Any(msg => msg.StartsWith($"{lineNumber}:"));
215-
bool isEdited = i == editorSelectedLineIndex;
216-
ImGui.TextColored(
217-
isEdited ? RgbaFloat.Green.ToVector4() : isError ? RgbaFloat.Red.ToVector4() : RgbaFloat.LightGrey.ToVector4(),
218-
lineNumber);
219-
ImGui.SameLine(50);
220-
if (isError)
221-
{
222-
ImGui.PushStyleColor(ImGuiCol.Text, RgbaFloat.Red.ToVector4());
223-
}
224-
if (isEdited)
179+
basicMode = true;
180+
if (ImGui.BeginChild("editor basic", Vector2.Zero, true))
225181
{
226-
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero);
182+
Vector2 editorWindowSize = ImGui.GetWindowSize();
183+
float textSize = ImGui.CalcTextSize(fragmentCode).Y + 32;
227184
ImGui.PushItemWidth(-1);
228-
// taken from https://github.com/mellinoe/ImGui.NET/blob/0b9c9ea07d720ac0c4e382deb8f08de30703a9a3/src/ImGui.NET.SampleProgram/MemoryEditor.cs#L128
229-
// which is not ideal
230-
ImGuiInputTextCallback callback = (data) =>
231-
{
232-
int* p_cursor_pos = (int*)data->UserData;
233-
234-
if (ImGuiNative.ImGuiInputTextCallbackData_HasSelection(data) == 0)
235-
*p_cursor_pos = data->CursorPos;
236-
return 0;
237-
};
238-
int cursorPos = -1;
239-
const ImGuiInputTextFlags flags = ImGuiInputTextFlags.AllowTabInput | ImGuiInputTextFlags.CallbackAlways;
240-
if (ImGui.InputText(lineNumber,
241-
ref editorSelectedLineContent,
242-
1000,
243-
flags,
244-
callback,
245-
(IntPtr)(&cursorPos)))
246-
{
247-
fragmentCodeLines[editorSelectedLineIndex] = editorSelectedLineContent;
248-
}
185+
ImGui.InputTextMultiline("",
186+
ref fragmentCode,
187+
MAXEDITORSTRINGLENGTH,
188+
new Vector2(editorWindowSize.X - 16, textSize > editorWindowSize.Y ? textSize : editorWindowSize.Y - 16),
189+
ImGuiInputTextFlags.AllowTabInput);
249190
ImGui.PopItemWidth();
250-
ImGui.PopStyleVar(1);
251-
editorSelectedLineCursorPosition = cursorPos;
252-
}
253-
else if (ImGui.Selectable(line))
254-
{
255-
SetSelectedLine(i);
256-
}
257-
if (isError)
258-
{
259-
ImGui.PopStyleColor(1);
260191
}
192+
ImGui.EndTabItem();
261193
}
262-
ImGui.EndChild();
194+
ImGui.EndTabBar();
263195
}
264196
ImGui.PopFont();
265197
ImGui.End();
@@ -281,6 +213,105 @@ private unsafe void SubmitEditorWindow()
281213
ImGui.PopStyleVar();
282214
}
283215

216+
private unsafe void SubmitAdvancedEditor()
217+
{
218+
if (ImGui.BeginChild("editor", Vector2.Zero, true))
219+
{
220+
// handle basic input
221+
if (editorSelectedLineIndex != -1)
222+
{
223+
if ((editorSelectedLineCursorPosition == 0 && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.LeftArrow), false))
224+
|| ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.UpArrow), true))
225+
{
226+
SetSelectedLine(editorSelectedLineIndex - 1);
227+
}
228+
if ((editorSelectedLineCursorPosition == editorSelectedLineContent.Length && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.RightArrow), false))
229+
|| ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.DownArrow), true))
230+
{
231+
SetSelectedLine(editorSelectedLineIndex + 1);
232+
}
233+
if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Enter), true))
234+
{
235+
string newLineContent = "";
236+
if (editorSelectedLineCursorPosition != editorSelectedLineContent.Length)
237+
{
238+
fragmentCodeLines[editorSelectedLineIndex] = editorSelectedLineContent.Take(editorSelectedLineCursorPosition).ToSystemString();
239+
newLineContent = editorSelectedLineContent.Skip(editorSelectedLineCursorPosition).ToSystemString();
240+
}
241+
fragmentCodeLines.Insert(editorSelectedLineIndex + 1, newLineContent);
242+
SetSelectedLine(editorSelectedLineIndex + 1);
243+
}
244+
if (editorSelectedLineIndex > 0)
245+
{
246+
if (editorSelectedLineCursorPosition == 0 && ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Backspace), true))
247+
{
248+
if (!string.IsNullOrEmpty(editorSelectedLineContent))
249+
{
250+
fragmentCodeLines[editorSelectedLineIndex - 1] += editorSelectedLineContent;
251+
}
252+
fragmentCodeLines.RemoveAt(editorSelectedLineIndex);
253+
SetSelectedLine(editorSelectedLineIndex - 1);
254+
}
255+
}
256+
}
257+
258+
// draw lines
259+
for (int i = 0; i < fragmentCodeLines.Count; i++)
260+
{
261+
string line = fragmentCodeLines[i];
262+
string lineNumber = $"{i + Controller.Context.FragmentHeaderLineCount}";
263+
bool isError = errorMessages.Any(msg => msg.StartsWith($"{lineNumber}:"));
264+
bool isEdited = i == editorSelectedLineIndex;
265+
ImGui.TextColored(
266+
isEdited ? RgbaFloat.Green.ToVector4() : isError ? RgbaFloat.Red.ToVector4() : RgbaFloat.LightGrey.ToVector4(),
267+
lineNumber);
268+
ImGui.SameLine(50);
269+
if (isError)
270+
{
271+
ImGui.PushStyleColor(ImGuiCol.Text, RgbaFloat.Red.ToVector4());
272+
}
273+
if (isEdited)
274+
{
275+
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero);
276+
ImGui.PushItemWidth(-1);
277+
// taken from https://github.com/mellinoe/ImGui.NET/blob/0b9c9ea07d720ac0c4e382deb8f08de30703a9a3/src/ImGui.NET.SampleProgram/MemoryEditor.cs#L128
278+
// which is not ideal
279+
ImGuiInputTextCallback callback = (data) =>
280+
{
281+
int* p_cursor_pos = (int*)data->UserData;
282+
283+
if (ImGuiNative.ImGuiInputTextCallbackData_HasSelection(data) == 0)
284+
*p_cursor_pos = data->CursorPos;
285+
return 0;
286+
};
287+
int cursorPos = -1;
288+
const ImGuiInputTextFlags flags = ImGuiInputTextFlags.AllowTabInput | ImGuiInputTextFlags.CallbackAlways;
289+
if (ImGui.InputText(lineNumber,
290+
ref editorSelectedLineContent,
291+
1000,
292+
flags,
293+
callback,
294+
(IntPtr)(&cursorPos)))
295+
{
296+
fragmentCodeLines[editorSelectedLineIndex] = editorSelectedLineContent;
297+
}
298+
ImGui.PopItemWidth();
299+
ImGui.PopStyleVar(1);
300+
editorSelectedLineCursorPosition = cursorPos;
301+
}
302+
else if (ImGui.Selectable(line))
303+
{
304+
SetSelectedLine(i);
305+
}
306+
if (isError)
307+
{
308+
ImGui.PopStyleColor(1);
309+
}
310+
}
311+
ImGui.EndChild();
312+
}
313+
}
314+
284315
private void SetSelectedLine(int i)
285316
{
286317
if (i >= 0 && i < fragmentCodeLines.Count)
@@ -333,7 +364,14 @@ public void SetError(string error)
333364

334365
public void Apply()
335366
{
336-
MergeLines();
367+
if (basicMode)
368+
{
369+
SplitLines();
370+
}
371+
else
372+
{
373+
MergeLines();
374+
}
337375
Controller.Context.CreateDynamicResources(fragmentCode);
338376
}
339377

YALCT/StartMenu.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public void SubmitUI(float deltaTime, InputSnapshot inputSnapshot)
3232
Controller.Context.Height / 2 - MENUHEIGHT / 2));
3333
if (ImGui.Begin("Yet Another Live Coding Tool", ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse))
3434
{
35-
Vector2 buttonSize = new Vector2(MENUWIDTH - 15, 40);
35+
Vector2 buttonSize = new Vector2(MENUWIDTH - 16, 40);
3636
if (ImGui.Button("Create", buttonSize))
3737
{
3838
Controller.SetState(UIState.Editor);

0 commit comments

Comments
 (0)