Skip to content

Commit

Permalink
Merge pull request #195 from rexim/copy-layout-to-clipboard
Browse files Browse the repository at this point in the history
Implement "Copy Layout to Clipboard" functionality
  • Loading branch information
nakst authored Feb 28, 2025
2 parents 9c16864 + 8c4c997 commit e34738b
Showing 1 changed file with 58 additions and 1 deletion.
59 changes: 58 additions & 1 deletion gf2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct Array {
T *array;
size_t length, allocated;

void InsertMany(T *newItems, uintptr_t index, size_t newCount) {
void InsertMany(const T *newItems, uintptr_t index, size_t newCount) {
if (length + newCount > allocated) {
allocated *= 2;
if (length + newCount > allocated) allocated = length + newCount;
Expand Down Expand Up @@ -74,6 +74,7 @@ struct Array {

void Insert(T item, uintptr_t index) { InsertMany(&item, index, 1); }
void Add(T item) { Insert(item, length); }
void AddMany(const T *newItems, size_t newCount) { InsertMany(newItems, length, newCount); }
void Free() { free(array); array = nullptr; length = allocated = 0; }
int Length() { return length; }
T &First() { return array[0]; }
Expand Down Expand Up @@ -344,6 +345,7 @@ UIElement *InterfaceWindowSwitchToAndFocus(const char *name);
void WatchAddExpression2(char *string);
int WatchWindowMessage(UIElement *element, UIMessage message, int di, void *dp);
void CommandInspectLine(void *);
void CopyLayoutToClipboard(void *cp);

//////////////////////////////////////////////////////
// Utilities:
Expand Down Expand Up @@ -1542,6 +1544,7 @@ void InterfaceAddBuiltinWindowsAndCommands() {
{ .invoke = CommandAddWatch } });
interfaceCommands.Add({ .label = "Inspect line",
{ .code = UI_KEYCODE_BACKTICK, .invoke = CommandInspectLine } });
interfaceCommands.Add({ .label = "Copy Layout to Clipboard", { .invoke = CopyLayoutToClipboard } });
interfaceCommands.Add({ .label = nullptr,
{ .code = UI_KEYCODE_LETTER('E'), .ctrl = true, .invoke = CommandWatchAddEntryForAddress } });
interfaceCommands.Add({ .label = nullptr,
Expand Down Expand Up @@ -1747,6 +1750,60 @@ void InterfaceLayoutCreate(UIElement *parent) {
}
}

void GenerateLayoutString(UIElement *e, Array<char> *sb)
{
char buf[32];

if (strcmp(e->cClassName, "Split Pane") == 0) {
assert(e->childCount == 3);
if (e->flags & UI_SPLIT_PANE_VERTICAL) {
sb->Add('v');
} else {
sb->Add('h');
}
sb->Add('(');
int n = snprintf(buf, sizeof(buf), "%d", (int)(((UISplitPane*)e)->weight*100));
sb->AddMany(buf, n);
sb->Add(',');
GenerateLayoutString(e->children[1], sb);
sb->Add(',');
GenerateLayoutString(e->children[2], sb);
sb->Add(')');
} else if (strcmp(e->cClassName, "Tab Pane") == 0) {
sb->AddMany("t(", 2);
for (size_t i = 0; i < e->childCount; ++i) {
if (i > 0) sb->Add(',');
GenerateLayoutString(e->children[i], sb);
}
sb->Add(')');
} else {
for (int i = 0; i < interfaceWindows.Length(); ++i) {
InterfaceWindow *window = &interfaceWindows[i];
if (window->element != NULL && window->element->id == e->id) {
sb->AddMany(window->name, strlen(window->name));
return;
}
}
assert(0 && "unreachable");
}
}

void CopyLayoutToClipboard(void *cp)
{
static Array<char> sb; // String Builder

sb.length = 0;
GenerateLayoutString(switcherMain->e.children[0]->children[0], &sb);
sb.Add('\0');

// Copying the text into the memory allocated by the UI allocator, because on some platforms
// (like Windows) it is not malloc/free from libc and _UIClipboardWriteText performs UI_FREE
// on the text buffer later.
char *text = (char*) UI_CALLOC(sb.length);
memcpy(text, sb.array, sb.length);
_UIClipboardWriteText(windowMain, text);
}

int GfMain(int argc, char **argv) {
if (argc == 2 && (0 == strcmp(argv[1], "-?") || 0 == strcmp(argv[1], "-h") || 0 == strcmp(argv[1], "--help"))) {
fprintf(stderr, "Usage: %s [GDB args]\n\n"
Expand Down

0 comments on commit e34738b

Please sign in to comment.