Coverage for aipyapp/gui/config.py: 0%
120 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-11 12:02 +0200
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-11 12:02 +0200
1#!/usr/bin/env python
2#coding: utf-8
4import os
6import wx
7import wx.adv
8from wx import DirDialog, FD_SAVE, FD_OVERWRITE_PROMPT
9from wx.lib.agw.floatspin import FloatSpin, EVT_FLOATSPIN, FS_LEFT, FS_RIGHT, FS_CENTRE, FS_READONLY
11from .. import T, set_lang
13class ConfigDialog(wx.Dialog):
14 def __init__(self, parent, settings):
15 super().__init__(parent, title=T('Configuration'))
17 self.settings = settings
19 vbox = wx.BoxSizer(wx.VERTICAL)
21 # Main panel with content
22 main_panel = wx.Panel(self)
23 main_vbox = wx.BoxSizer(wx.VERTICAL)
25 # Work directory group
26 work_dir_box = wx.StaticBox(main_panel, -1, T('Work Directory'))
27 work_dir_sizer = wx.StaticBoxSizer(work_dir_box, wx.VERTICAL)
29 work_dir_panel = wx.Panel(main_panel)
30 work_dir_inner_sizer = wx.BoxSizer(wx.HORIZONTAL)
32 self.work_dir_text = wx.TextCtrl(work_dir_panel, -1, settings.workdir, style=wx.TE_READONLY)
33 work_dir_inner_sizer.Add(self.work_dir_text, 1, wx.ALL | wx.EXPAND, 5)
35 browse_button = wx.Button(work_dir_panel, -1, T('Browse...'))
36 browse_button.Bind(wx.EVT_BUTTON, self.on_browse_work_dir)
37 work_dir_inner_sizer.Add(browse_button, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
39 work_dir_panel.SetSizer(work_dir_inner_sizer)
40 work_dir_sizer.Add(work_dir_panel, 0, wx.ALL | wx.EXPAND, 5)
42 # Add hint about creating new directory
43 hint_text = wx.StaticText(main_panel, -1, T('You can create a new directory in the file dialog'))
44 work_dir_sizer.Add(hint_text, 0, wx.LEFT | wx.BOTTOM, 5)
46 main_vbox.Add(work_dir_sizer, 0, wx.ALL | wx.EXPAND, 10)
48 # Settings group
49 settings_box = wx.StaticBox(main_panel, -1, T('Settings'))
50 settings_sizer = wx.StaticBoxSizer(settings_box, wx.VERTICAL)
52 # Max tokens slider
53 tokens_panel = wx.Panel(main_panel)
54 tokens_sizer = wx.BoxSizer(wx.HORIZONTAL)
56 tokens_label = wx.StaticText(tokens_panel, -1, T('Max Tokens') + ":")
57 tokens_sizer.Add(tokens_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
59 self.tokens_slider = wx.Slider(tokens_panel, -1,
60 settings.get('max_tokens', 8192),
61 minValue=64,
62 maxValue=128*1024,
63 style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS)
64 self.tokens_slider.SetTickFreq(100)
65 tokens_sizer.Add(self.tokens_slider, 1, wx.ALL | wx.EXPAND, 5)
67 self.tokens_text = wx.StaticText(tokens_panel, -1, str(self.tokens_slider.GetValue()))
68 self.tokens_text.SetMinSize((50, -1))
69 tokens_sizer.Add(self.tokens_text, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
71 tokens_panel.SetSizer(tokens_sizer)
72 settings_sizer.Add(tokens_panel, 0, wx.ALL | wx.EXPAND, 5)
74 # Timeout slider
75 timeout_panel = wx.Panel(main_panel)
76 timeout_sizer = wx.BoxSizer(wx.HORIZONTAL)
78 timeout_label = wx.StaticText(timeout_panel, -1, T('Timeout (seconds)') + ":")
79 timeout_sizer.Add(timeout_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
81 self.timeout_slider = wx.Slider(timeout_panel, -1,
82 int(settings.get('timeout', 0)),
83 minValue=0,
84 maxValue=120,
85 style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS)
86 self.timeout_slider.SetTickFreq(30)
87 timeout_sizer.Add(self.timeout_slider, 1, wx.ALL | wx.EXPAND, 5)
89 self.timeout_text = wx.StaticText(timeout_panel, -1, str(self.timeout_slider.GetValue()))
90 self.timeout_text.SetMinSize((50, -1))
91 timeout_sizer.Add(self.timeout_text, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
93 timeout_panel.SetSizer(timeout_sizer)
94 settings_sizer.Add(timeout_panel, 0, wx.ALL | wx.EXPAND, 5)
96 # Max rounds slider
97 rounds_panel = wx.Panel(main_panel)
98 rounds_sizer = wx.BoxSizer(wx.HORIZONTAL)
100 rounds_label = wx.StaticText(rounds_panel, -1, T('Max Rounds') + ":")
101 rounds_sizer.Add(rounds_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
103 self.rounds_slider = wx.Slider(rounds_panel, -1,
104 settings.get('max_rounds', 16),
105 minValue=1,
106 maxValue=64,
107 style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS)
108 self.rounds_slider.SetTickFreq(8)
109 rounds_sizer.Add(self.rounds_slider, 1, wx.ALL | wx.EXPAND, 5)
111 self.rounds_text = wx.StaticText(rounds_panel, -1, str(self.rounds_slider.GetValue()))
112 rounds_sizer.Add(self.rounds_text, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
114 rounds_panel.SetSizer(rounds_sizer)
115 settings_sizer.Add(rounds_panel, 0, wx.ALL | wx.EXPAND, 5)
117 main_vbox.Add(settings_sizer, 0, wx.ALL | wx.EXPAND, 10)
119 self.url_ctrl = wx.adv.HyperlinkCtrl(main_panel, label=T('Click here for more information'), url="https://d.aipyaipy.com/d/162", style=wx.adv.HL_ALIGN_LEFT | wx.adv.HL_CONTEXTMENU)
120 main_vbox.Add(self.url_ctrl, 0, wx.ALL, 10)
122 main_panel.SetSizer(main_vbox)
123 vbox.Add(main_panel, 1, wx.EXPAND)
125 # Buttons panel at bottom
126 button_panel = wx.Panel(self)
127 button_sizer = wx.BoxSizer(wx.HORIZONTAL)
129 ok_button = wx.Button(button_panel, wx.ID_OK, T('OK'))
130 ok_button.SetMinSize((100, 30))
131 cancel_button = wx.Button(button_panel, wx.ID_CANCEL, T('Cancel'))
132 cancel_button.SetMinSize((100, 30))
134 button_sizer.Add(ok_button, 0, wx.ALL, 5)
135 button_sizer.Add(cancel_button, 0, wx.ALL, 5)
137 button_panel.SetSizer(button_sizer)
138 vbox.Add(button_panel, 0, wx.ALL | wx.ALIGN_CENTER | wx.BOTTOM, 20)
140 # Bind events
141 self.tokens_slider.Bind(wx.EVT_SLIDER, self.on_tokens_slider)
142 self.timeout_slider.Bind(wx.EVT_SLIDER, self.on_timeout_slider)
143 self.rounds_slider.Bind(wx.EVT_SLIDER, self.on_rounds_slider)
145 self.SetSizer(vbox)
146 self.SetMinSize((500, 450))
147 self.Fit()
148 self.Centre()
150 def on_browse_work_dir(self, event):
151 with DirDialog(self, T('Select work directory'),
152 defaultPath=self.work_dir_text.GetValue(),
153 style=wx.DD_DEFAULT_STYLE) as dlg:
154 if dlg.ShowModal() == wx.ID_OK:
155 self.work_dir_text.SetValue(dlg.GetPath())
157 def on_tokens_slider(self, event):
158 value = self.tokens_slider.GetValue()
159 self.tokens_text.SetLabel(str(value))
161 def on_timeout_slider(self, event):
162 value = self.timeout_slider.GetValue()
163 self.timeout_text.SetLabel(str(value))
165 def on_rounds_slider(self, event):
166 value = self.rounds_slider.GetValue()
167 self.rounds_text.SetLabel(str(value))
169 def get_values(self):
170 return {
171 'workdir': self.work_dir_text.GetValue(),
172 'max_tokens': int(self.tokens_slider.GetValue()),
173 'timeout': float(self.timeout_slider.GetValue()),
174 'max_rounds': int(self.rounds_slider.GetValue())
175 }
177if __name__ == '__main__':
178 class TestSettings:
179 def __init__(self):
180 self.workdir = os.getcwd()
181 self._settings = {
182 'max-tokens': 2000,
183 'timeout': 30.0,
184 'max-rounds': 10
185 }
187 def get(self, key, default=None):
188 return self._settings.get(key, default)
190 def __setitem__(self, key, value):
191 self._settings[key] = value
193 def save(self):
194 print("Settings saved:", self._settings)
196 app = wx.App(False)
197 settings = TestSettings()
198 dialog = ConfigDialog(None, settings)
199 if dialog.ShowModal() == wx.ID_OK:
200 values = dialog.get_values()
201 print("New settings:", values)
202 dialog.Destroy()
203 app.MainLoop()