2 Commits

Author SHA1 Message Date
ed 3d3c4e80ae word wrapping yum 2026-02-21 23:55:38 -05:00
ed bdd0fbc1c4 wip better word wrap ux 2026-02-21 23:52:18 -05:00
3 changed files with 45 additions and 30 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[ai]
provider = "gemini"
model = "gemini-2.5-pro"
model = "gemini-3-flash-preview"
system_prompt = "DO NOT EVER make a shell script unless told to. DO NOT EVER make a readme or a file describing your changes unless your are told to. If you have commands I should be entering into the command line or if you have something to explain to me, please just use code blocks or normal text output. DO NOT DO ANYTHING OTHER THAN WHAT YOU WERE TOLD TODO. DO NOT EVER, EVER DO ANYTHING OTHER THAN WHAT YOU WERE TOLD TO DO. IF YOU WANT TO DO OTHER THINGS, SIMPLY SUGGEST THEM, AND THEN I WILL REVIEW YOUR CHANGES, AND MAKE THE DECISION ON HOW TO PROCEED. WHEN WRITING SCRIPTS USE A 120-160 character limit per line. I don't want to see scrunched code.\n"
[theme]
+42 -28
View File
@@ -67,9 +67,9 @@ _SUBHDR_COLOR = (220, 200, 120) # sub-section header
def _show_text_viewer(title: str, text: str, app_instance=None):
def _show_text_viewer(title: str, text: str):
if dpg.does_item_exist("win_text_viewer"):
wrap = app_instance.project.get("project", {}).get("word_wrap", False) if app_instance else False
wrap = dpg.get_value("project_word_wrap") if dpg.does_item_exist("project_word_wrap") else False
dpg.configure_item("win_text_viewer", label=f"Text Viewer - {title}", show=True)
if dpg.does_item_exist("text_viewer_content"):
dpg.set_value("text_viewer_content", text if text is not None else "")
@@ -86,7 +86,7 @@ def _add_text_field(parent: str, label: str, value: str):
with dpg.group(horizontal=False, parent=parent):
with dpg.group(horizontal=True):
dpg.add_text(f"{label}:", color=_LABEL_COLOR)
dpg.add_button(label="[+]", callback=lambda s, a, u: _show_text_viewer(label, u, app_instance=self), user_data=value)
dpg.add_button(label="[+]", callback=lambda s, a, u: _show_text_viewer(label, u), user_data=value)
if len(value) > COMMS_CLAMP_CHARS:
if wrap:
with dpg.child_window(height=80, border=True):
@@ -294,7 +294,7 @@ class ConfirmDialog:
dpg.add_button(
label="[+ Maximize]",
user_data=f"{self._tag}_script",
callback=lambda s, a, u: _show_text_viewer("Confirm Script", dpg.get_value(u, app_instance=self))
callback=lambda s, a, u: _show_text_viewer("Confirm Script", dpg.get_value(u))
)
dpg.add_input_text(
tag=f"{self._tag}_script",
@@ -745,12 +745,12 @@ class App:
dpg.add_button(
label="[+ Script]",
user_data=script,
callback=lambda s, a, u: _show_text_viewer(f"Call Script", u, app_instance=self)
callback=lambda s, a, u: _show_text_viewer("Call Script", u)
)
dpg.add_button(
label="[+ Output]",
user_data=result,
callback=lambda s, a, u: _show_text_viewer(f"Call Output", u, app_instance=self)
callback=lambda s, a, u: _show_text_viewer("Call Output", u)
)
if wrap:
with dpg.child_window(height=72, border=True):
@@ -988,7 +988,7 @@ class App:
# ---------------------------------------------------------------- callbacks
def cb_word_wrap_toggled(self, sender=None, app_data=None):
def cb_word_wrap_toggled(self, sender=None, app_data=None):
# This function is now also called by _refresh_project_widgets to set initial state
if app_data is None:
wrap = dpg.get_value("project_word_wrap") if dpg.does_item_exist("project_word_wrap") else False
@@ -1349,13 +1349,24 @@ class App:
def _rebuild_disc_list(self):
if not dpg.does_item_exist("disc_scroll"):
return
def _toggle_read(s, a, idx):
# Save edit box content before switching to read mode
tag = f"disc_content_{idx}"
if dpg.does_item_exist(tag) and not self.disc_entries[idx].get("read_mode", False):
self.disc_entries[idx]["content"] = dpg.get_value(tag)
self.disc_entries[idx]["read_mode"] = not self.disc_entries[idx].get("read_mode", False)
self._rebuild_disc_list()
dpg.delete_item("disc_scroll", children_only=True)
for i, entry in enumerate(self.disc_entries):
collapsed = entry.get("collapsed", False)
read_mode = entry.get("read_mode", False)
ts_str = entry.get("ts", "")
preview = entry["content"].replace("\n", " ")[:60]
if len(entry["content"]) > 60:
preview += "..."
ts_str = entry.get("ts", "")
with dpg.group(parent="disc_scroll"):
with dpg.group(horizontal=True):
@@ -1372,6 +1383,12 @@ class App:
width=120,
callback=self._make_disc_role_cb(i),
)
if not collapsed:
dpg.add_button(
label="[Edit]" if read_mode else "[Read]",
user_data=i,
callback=_toggle_read
)
if ts_str:
dpg.add_text(ts_str, color=(120, 120, 100))
if collapsed:
@@ -1382,13 +1399,7 @@ class App:
)
dpg.add_button(
label="[+ Max]",
user_data=f"disc_content_{{i}}",
callback=lambda s, a, u, idx=i: _show_text_viewer(f"Entry #{{idx+1}}", dpg.get_value(u, app_instance=self) if dpg.does_item_exist(u) else "", app_instance=self)
)
dpg.add_button(
label="Del",
width=36,
callback=self._make_disc_insert_cb(i),
callback=lambda s, a, u, idx=i: _show_text_viewer(f"Entry #{idx+1}", self.disc_entries[idx]["content"])
)
dpg.add_button(
label="Del",
@@ -1396,17 +1407,21 @@ class App:
callback=self._make_disc_remove_cb(i),
)
dpg.add_text(preview, color=(160, 160, 150))
else:
with dpg.group(tag=f"disc_body_{i}", show=not collapsed):
dpg.add_input_text(
tag=f"disc_content_{i}",
default_value=entry["content"],
multiline=True,
width=-1,
height=100,
callback=self._make_disc_content_cb(i),
on_enter=False,
)
if read_mode:
with dpg.child_window(height=150, border=True):
dpg.add_text(entry["content"], wrap=0, color=(200, 200, 200))
else:
dpg.add_input_text(
tag=f"disc_content_{i}",
default_value=entry["content"],
multiline=True,
width=-1,
height=150,
callback=self._make_disc_content_cb(i),
on_enter=False,
)
dpg.add_separator()
def _make_disc_role_cb(self, idx: int):
@@ -1850,7 +1865,7 @@ class App:
dpg.add_button(
label="[+ Maximize]",
user_data="last_script_text",
callback=lambda s, a, u: _show_text_viewer("Last Script", dpg.get_value(u, app_instance=self))
callback=lambda s, a, u: _show_text_viewer("Last Script", dpg.get_value(u))
)
dpg.add_input_text(
tag="last_script_text",
@@ -1867,7 +1882,7 @@ class App:
dpg.add_button(
label="[+ Maximize]",
user_data="last_script_output",
callback=lambda s, a, u: _show_text_viewer("Last Output", dpg.get_value(u, app_instance=self))
callback=lambda s, a, u: _show_text_viewer("Last Output", dpg.get_value(u))
)
dpg.add_input_text(
tag="last_script_output",
@@ -2051,4 +2066,3 @@ def main():
if __name__ == "__main__":
main()
+2 -1
View File
@@ -3,6 +3,7 @@ name = "manual_slop"
git_dir = "C:/projects/manual_slop"
system_prompt = "Make sure to update MainContext.md every time.\nMake destructive modifications to the project, ITS OK, I HAVE GIT HISTORY TO MANAGE THE PROJECTS."
main_context = "C:/projects/manual_slop/MainContext.md"
word_wrap = true
[output]
namespace = "manual_slop"
@@ -112,7 +113,7 @@ history = [
[discussion.discussions."Misc UX improvements"]
git_commit = "5f9b270841fa1b3e34af1c56cbc75041c95b265a"
last_updated = "2026-02-21T23:38:30"
last_updated = "2026-02-21T23:46:45"
history = [
"@2026-02-21T23:03:51\nUser:\nMake the namespace for the generated markdown file the projet name instead of that specific namespace in the config panel.\nThe ouptut dir can be in the project panel spec (that way we can just remove config panel entirely).",
"@2026-02-21T23:04:55\nAI:\nI have applied the changes to streamline the project settings and remove the old Config panel completely:\n\n1. **GUI Layout Changes (`gui.py`)**:\n - The `Config` panel has been completely removed.\n - The **Output Dir** field has been moved into the **Projects** panel (right above the Project Files list).\n - The **Auto-add history** checkbox has been moved to the top of the **Discussion History** panel (directly under the entry toolbar buttons).\n - The **Files** panel was shifted upward to reclaim the space left behind by the old Config panel.\n\n2. **Namespace Management (`aggregate.py` & `project_manager.py`)**:\n - The explicitly defined `namespace` field is gone.\n - Instead, `aggregate.py` now directly infers the output markdown file namespace from the active project's `name` property. (e.g., saving under the `manual_slop` project will just prefix the markdown with `manual_slop_001.md`).\n - `project_manager.py` was updated to no longer scaffold out `namespace` strings into new `.toml` files, and `flat_config` now injects the core `project` dictionary segment so the generators can access the internal name.\n\n3. **`MainContext.md` Updated**:\n - I have updated the markdown file with the latest layout structures and explained that `namespace` is no longer a configurable setting but dynamically determined by the project profile.\n\nYou'll need to restart the application for the GUI layout and DearPyGUI state changes to take effect! Let me know how it looks.",