add copy, start on paste and text selections
This commit is contained in:
parent
70f51642cd
commit
342e342a50
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
||||
Subproject commit 2af4a293148aadac84d9fec3505d2adcdb747298
|
||||
Subproject commit 92c4f8eb665e9fc7a58dc9631bb6f26a0828a638
|
||||
@ -15,12 +15,26 @@ struct FlatBuffer
|
||||
LineStart[] line_starts;
|
||||
u64 length;
|
||||
u64 lf_count;
|
||||
|
||||
i64 buf_pos;
|
||||
i64 offset;
|
||||
i64 rows;
|
||||
|
||||
I64Vec2 sel;
|
||||
SelectMode sel_mode;
|
||||
|
||||
bool dirty;
|
||||
}
|
||||
|
||||
enum SelectMode
|
||||
{
|
||||
None,
|
||||
Normal,
|
||||
Line,
|
||||
}
|
||||
|
||||
alias SM = SelectMode;
|
||||
|
||||
struct LineStart
|
||||
{
|
||||
u64 pos;
|
||||
@ -98,6 +112,7 @@ CreateFlatBuffer(u8[] data)
|
||||
data: buf,
|
||||
length: cast(u64)data.length,
|
||||
lf_count: CountLF(data),
|
||||
sel: -1,
|
||||
};
|
||||
|
||||
fb.tk = CreateTokenizer(&fb);
|
||||
@ -277,7 +292,42 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
|
||||
|
||||
Reset(&fb.arena);
|
||||
|
||||
AdjustOffset(fb);
|
||||
UpdateOffset(fb);
|
||||
}
|
||||
|
||||
void
|
||||
ToggleSelection(FlatBuffer* fb, SelectMode mode)
|
||||
{
|
||||
if(fb.sel_mode == SM.None)
|
||||
{
|
||||
StartSelection(fb, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
EndSelection(fb);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StartSelection(FlatBuffer* fb, SelectMode mode)
|
||||
{
|
||||
fb.sel_mode = mode;
|
||||
|
||||
if(mode == SM.Normal)
|
||||
{
|
||||
fb.sel = fb.buf_pos;
|
||||
}
|
||||
else if(mode == SM.Line)
|
||||
{
|
||||
fb.sel = CurrentLine(fb);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EndSelection(FlatBuffer* fb)
|
||||
{
|
||||
fb.sel = -1;
|
||||
fb.sel_mode = SM.None;
|
||||
}
|
||||
|
||||
void
|
||||
@ -790,14 +840,30 @@ Move(FlatBuffer* fb, Input key, Modifier md)
|
||||
}
|
||||
}
|
||||
|
||||
AdjustOffset(fb);
|
||||
U64Vec2 p = VecPos(fb);
|
||||
UpdateOffset(fb);
|
||||
UpdateSelection(fb);
|
||||
|
||||
Logf("selection %s", fb.sel.v);
|
||||
|
||||
return taken;
|
||||
}
|
||||
|
||||
void
|
||||
AdjustOffset(FlatBuffer* fb)
|
||||
UpdateSelection(FlatBuffer* fb)
|
||||
{
|
||||
if(fb.sel_mode == SM.Normal)
|
||||
{
|
||||
fb.sel.y = fb.buf_pos;
|
||||
}
|
||||
|
||||
if(fb.sel_mode == SM.Line)
|
||||
{
|
||||
fb.sel.y = CurrentLine(fb);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UpdateOffset(FlatBuffer* fb)
|
||||
{
|
||||
if(fb.rows > 0) with(fb)
|
||||
{
|
||||
|
||||
@ -22,6 +22,7 @@ debug bool g_frame_continue = false;
|
||||
struct EditorCtx
|
||||
{
|
||||
Arena arena;
|
||||
PlatformWindow* window;
|
||||
UIPanel* base_panel;
|
||||
u64 panel_id;
|
||||
EditState state;
|
||||
@ -61,6 +62,23 @@ struct Editor
|
||||
u64 line_offset;
|
||||
}
|
||||
|
||||
struct ChangeStacks
|
||||
{
|
||||
Arena arena;
|
||||
u64 current_pos;
|
||||
u8[] current_str;
|
||||
u64 current_len;
|
||||
EditorChange* undos;
|
||||
EditorChange* redos;
|
||||
}
|
||||
|
||||
struct EditorChange
|
||||
{
|
||||
u8[] str;
|
||||
u64 pos;
|
||||
EditorChange* next;
|
||||
}
|
||||
|
||||
struct Command
|
||||
{
|
||||
u8[] name;
|
||||
@ -79,6 +97,8 @@ enum CmdType
|
||||
OpenFile,
|
||||
SaveFile,
|
||||
CreateFile,
|
||||
VSplit,
|
||||
HSplit,
|
||||
}
|
||||
|
||||
alias CT = CmdType;
|
||||
@ -148,6 +168,7 @@ InitEditorCtx(PlatformWindow* window)
|
||||
InitUICtx(window);
|
||||
|
||||
EditorCtx ctx = {
|
||||
window: window,
|
||||
arena: CreateArena(MB(2)),
|
||||
cmd: {
|
||||
arena: CreateArena(MB(1)),
|
||||
@ -473,6 +494,9 @@ Shift(Modifier md)
|
||||
void
|
||||
HandleInputs(EditorCtx* ctx, Inputs* inputs)
|
||||
{
|
||||
u8[] cb_text;
|
||||
FlatBuffer* fb = !Nil(GetFocusedPanel()) ? &(GetFocusedPanel()).ed.buf : null;
|
||||
|
||||
for(auto node = inputs.list.first; node != null; node = node.next)
|
||||
{
|
||||
bool taken = false;
|
||||
@ -480,7 +504,6 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs)
|
||||
Input key = node.value.key;
|
||||
Modifier md = node.value.md;
|
||||
bool pressed = node.value.pressed;
|
||||
FlatBuffer* fb = !Nil(GetFocusedPanel()) ? &(GetFocusedPanel()).ed.buf : null;
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
@ -529,8 +552,18 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs)
|
||||
} break;
|
||||
case v:
|
||||
{
|
||||
AddEditor(ctx, GetFocusedPanel(), A2D.X);
|
||||
taken = true;
|
||||
if(Ctrl(md))
|
||||
{
|
||||
cb_text = ClipboardText(ctx.window);
|
||||
}
|
||||
if(Shift(md))
|
||||
{
|
||||
ToggleSelection(fb, SM.Line);
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleSelection(fb, SM.Normal);
|
||||
}
|
||||
} break;
|
||||
case c:
|
||||
{
|
||||
@ -566,6 +599,11 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs)
|
||||
}
|
||||
|
||||
InsertInputToBuf(ctx);
|
||||
|
||||
if(cb_text.length > 0)
|
||||
{
|
||||
Insert(fb, cb_text, cb_text.length);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -721,6 +759,14 @@ GetCommands(CmdPalette* cmd)
|
||||
name: CastStr!(u8)("create"),
|
||||
type: CT.CreateFile,
|
||||
},
|
||||
{
|
||||
name: CastStr!(u8)("vsplit"),
|
||||
type: CT.VSplit,
|
||||
},
|
||||
{
|
||||
name: CastStr!(u8)("hsplit"),
|
||||
type: CT.HSplit,
|
||||
},
|
||||
];
|
||||
|
||||
Reset(&cmd.arena);
|
||||
@ -770,16 +816,24 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
{
|
||||
case Enter:
|
||||
{
|
||||
if(cmd.current.type == CT.None)
|
||||
if(cmd.current.type == CT.None && cmd.commands.length > 0)
|
||||
{
|
||||
if(cmd.commands[cmd.selected].type == CT.OpenFile)
|
||||
{
|
||||
goto case Tab;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.current = cmd.commands[cmd.selected];
|
||||
}
|
||||
}
|
||||
|
||||
UIPanel* p = GetFocusedPanel();
|
||||
|
||||
switch(cmd.current.type)
|
||||
{
|
||||
case CT.OpenFile:
|
||||
{
|
||||
UIPanel* p = GetFocusedPanel();
|
||||
if(!Nil(p) && cmd.selected >= 0 && cmd.selected < cmd.opt_strs.length)
|
||||
{
|
||||
OpenFile(p.ed, cmd.opt_strs[cmd.selected]);
|
||||
@ -787,12 +841,15 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
} break;
|
||||
case CT.SaveFile:
|
||||
{
|
||||
UIPanel* p = GetFocusedPanel();
|
||||
if(!Nil(p))
|
||||
{
|
||||
SaveFile(p.ed, GetParam(cmd));
|
||||
}
|
||||
} break;
|
||||
case CT.VSplit, CT.HSplit:
|
||||
{
|
||||
AddEditor(ctx, p, cmd.current.type == CT.VSplit ? A2D.X : A2D.Y);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -800,15 +857,10 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
} goto CmdInputEnd;
|
||||
case Backspace:
|
||||
{
|
||||
if(cmd.icount > 0)
|
||||
{
|
||||
cmd.icount -= 1;
|
||||
|
||||
if(cmd.buffer[cmd.icount] == ' ')
|
||||
if(CondIncr!(-1)(cmd.icount > 0, &cmd.icount) && cmd.buffer[cmd.icount] == ' ')
|
||||
{
|
||||
cmd.current = cast(Command)NO_CMD;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case Space:
|
||||
{
|
||||
@ -827,17 +879,11 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
} break;
|
||||
case Up:
|
||||
{
|
||||
if(cmd.selected > 0)
|
||||
{
|
||||
cmd.selected -= 1;
|
||||
}
|
||||
CondIncr!(-1)(cmd.selected > 0, &cmd.selected);
|
||||
} break;
|
||||
case Down:
|
||||
{
|
||||
if(cmd.selected < cmd.opt_strs.length-1)
|
||||
{
|
||||
cmd.selected += 1;
|
||||
}
|
||||
CondIncr!(+1)(cmd.selected < cmd.opt_strs.length-1, &cmd.selected);
|
||||
} break;
|
||||
mixin(TextLineCharCases());
|
||||
default: break;
|
||||
|
||||
@ -129,6 +129,7 @@ struct UICtx
|
||||
UIStack!(f32)* edge_softness;
|
||||
|
||||
i64 highlighted_char;
|
||||
I64Vec2 selected;
|
||||
u32 tab_width;
|
||||
f32 text_size;
|
||||
|
||||
@ -176,6 +177,7 @@ struct UIItem
|
||||
UISize[2] size_info;
|
||||
Vec2 adjustment;
|
||||
i64 highlighted_char;
|
||||
I64Vec2 selected;
|
||||
|
||||
// Calculated Parameters
|
||||
Vec4[4] color;
|
||||
|
||||
@ -378,7 +378,16 @@ EditorView(UIPanel* panel)
|
||||
|
||||
Container(ScratchName(panel.id, "lines"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.Y);
|
||||
{
|
||||
I64Vec2 sel = ed.buf.sel;
|
||||
if(sel.x > sel.y)
|
||||
{
|
||||
i64 t = sel.y;
|
||||
sel.y = sel.x;
|
||||
sel.x = t;
|
||||
}
|
||||
|
||||
U64Vec2 pos = VecPos(&ed.buf);
|
||||
SelectMode sm = ed.buf.sel_mode;
|
||||
u64 i = 0;
|
||||
for(LineBuffer* buf = ed.linebufs.first; buf != null; buf = buf.next, i += 1)
|
||||
{
|
||||
@ -395,6 +404,10 @@ EditorView(UIPanel* panel)
|
||||
Push!("highlighted_char")(pos.x);
|
||||
}
|
||||
|
||||
if(sm == SM.Line && line_no >= sel.x && line_no <= sel.y)
|
||||
{
|
||||
}
|
||||
|
||||
TextPart* tp = WrappedTextLine(buf.text, panel.id, text_size, line_no, buf.style);
|
||||
height += (text_size * tp.count);
|
||||
if(TextClicked(tp))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user