Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Yiannis128 committed Feb 11, 2024
1 parent fcf5168 commit 8d060b6
Show file tree
Hide file tree
Showing 17 changed files with 471 additions and 28 deletions.
5 changes: 4 additions & 1 deletion esbmc_ai_config/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from esbmc_ai_config.context_manager import ContextManager
from esbmc_ai_config.contexts.main_menu import MainMenu
from esbmc_ai_config.models.config_manager import ConfigManager


palette = [
Expand All @@ -18,8 +19,10 @@


def main() -> None:
# TODO Use argparse to take arguments for initial env and config location to start
# loading from.
ConfigManager.init()
top_ctx = MainMenu()

app: MainLoop = MainLoop(top_ctx.widget, palette=[("reversed", "standout", "")])
ContextManager.init(app, top_ctx)
app.run()
Expand Down
22 changes: 18 additions & 4 deletions esbmc_ai_config/context.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# Author: Yiannis Charalambous

from abc import abstractmethod
from typing import Optional
import urwid


class Context(object):
def __init__(self, widget: urwid.Widget) -> None:
super().__init__()
class Context(urwid.WidgetWrap):
def __init__(self, widget: Optional[urwid.Widget] = None) -> None:
super().__init__(widget if widget else self.build_ui())

self.widget: urwid.Widget = widget
@property
def widget(self) -> urwid.Widget:
assert isinstance(self._wrapped_widget, urwid.Widget)
return self._wrapped_widget

@widget.setter
def widget(self, value: urwid.Widget) -> None:
self._wrapped_widget = value

@abstractmethod
def build_ui(self) -> urwid.Widget:
"""Provides a method to build the interface, if not provided."""
raise NotImplementedError
6 changes: 3 additions & 3 deletions esbmc_ai_config/context_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ def __init__(self) -> None:
def init(cls, app: MainLoop, ctx: Context) -> None:
cls.app = app
cls.view_stack.append(ctx)
cls.app.widget = ctx.widget
cls.app.widget = ctx

@classmethod
def push_context(cls, ctx: Context) -> None:
cls.view_stack.append(ctx)
cls.app.widget = ctx.widget
cls.app.widget = ctx

@classmethod
def pop_context(cls) -> Context:
cls.app.widget = cls.view_stack[-2].widget
cls.app.widget = cls.view_stack[-2]
return cls.view_stack.pop()

@classmethod
Expand Down
Empty file.
23 changes: 16 additions & 7 deletions esbmc_ai_config/contexts/base_menu.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Author: Yiannis Charalambous

from typing_extensions import override
import urwid
from urwid import Button, Text, connect_signal, AttrMap

Expand All @@ -16,20 +17,28 @@ def __init__(
) -> None:
"""Creates a Menu context and displays it on the screen."""

_choices: list[str | urwid.Widget] = choices.copy()
if back_choice:
_choices.append(urwid.Divider())
_choices.append("Back")
self.choices: list[str | urwid.Widget] = choices.copy()
self.back_choice: bool = back_choice
self.title: str = title

menu: urwid.ListBox = self.create_menu(title=title, choices=_choices)
super().__init__()

menu_box: urwid.WidgetDecoration = urwid.Padding(
def create_padding(self, menu: urwid.Widget) -> urwid.Padding:
return urwid.Padding(
menu,
left=2,
right=2,
)

super().__init__(menu_box)
@override
def build_ui(self) -> urwid.Widget:
choices: list[str | urwid.Widget] = self.choices.copy()
if self.back_choice:
choices.append(urwid.Divider())
choices.append("Back")

menu: urwid.ListBox = self.create_menu(title=self.title, choices=choices)
return self.create_padding(menu)

def item_chosen(self, button, choice) -> None:
if choice == "Back":
Expand Down
44 changes: 44 additions & 0 deletions esbmc_ai_config/contexts/dialog_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Author: Yiannis Charalambous

from typing_extensions import override

import urwid
from esbmc_ai_config.context import Context
from esbmc_ai_config.context_manager import ContextManager


class DialogContext(Context):
def __init__(self, title: str = "", message: str = "") -> None:
self.title: str = title
self.message: str = message

super().__init__()

def _on_ok(self, button) -> None:
ContextManager.pop_context()

@override
def build_ui(self) -> urwid.Widget:
ok_button: urwid.Button = urwid.Button("OK", on_press=self._on_ok)

body: list[urwid.Widget] = [
urwid.Text(self.title),
urwid.Divider(),
urwid.Text(self.message),
urwid.Divider(),
urwid.Columns([urwid.AttrMap(ok_button, None, focus_map="reversed")]),
]

list_menu: urwid.ListBox = urwid.ListBox(body)
# Wrap in nice UI.
overlay: urwid.Widget = urwid.Overlay(
urwid.LineBox(urwid.Padding(list_menu, left=2, right=2)),
urwid.SolidFill("\N{MEDIUM SHADE}"),
align="center",
valign="middle",
width=("relative", 60),
height=("relative", 15),
min_width=20,
min_height=10,
)
return overlay
47 changes: 40 additions & 7 deletions esbmc_ai_config/contexts/env_menu.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
# Author: Yiannis Charalambous

from typing_extensions import override
import urwid
from esbmc_ai_config.models.config_manager import ConfigManager

from esbmc_ai_config.models.env_config_loader import EnvConfigLoader
from esbmc_ai_config.models.env_config_loader import EnvConfigField
from esbmc_ai_config.contexts.base_menu import BaseMenu
from esbmc_ai_config.widgets.text_input_button import TextInputButton


class EnvMenu(BaseMenu):
def __init__(self) -> None:
self.config: EnvConfigLoader = EnvConfigLoader(create_missing_fields=True)
choices: list = [field.name for field in self.config.fields]
super().__init__(title="Setup Environment", choices=choices)
super().__init__(title="Setup Environment", choices=self._get_menu_items())

top: urwid.Widget = urwid.Overlay(
urwid.LineBox(self.widget),
def _get_menu_items(self) -> list[str | urwid.Widget]:
choices: list[str | urwid.Widget] = [
TextInputButton(
field.name,
on_submit=self._on_value_submit,
initial_value=str(ConfigManager.env_config.values[field.name]),
)
for field in ConfigManager.env_config.fields
]
return choices

@override
def build_ui(self) -> urwid.Widget:
# Update value of choices to contain new objects of TextInputButton
# with initial values.
self.choices: list[str | urwid.Widget] = self._get_menu_items()
# Build the BaseMenu UI.
menu: urwid.Widget = super().build_ui()
# Wrap in nice UI.
overlay: urwid.Widget = urwid.Overlay(
urwid.LineBox(menu),
urwid.SolidFill("\N{MEDIUM SHADE}"),
align="center",
valign="middle",
Expand All @@ -23,4 +43,17 @@ def __init__(self) -> None:
min_height=10,
)

self.widget = top
return overlay

def _on_value_submit(self, title: str, value: str, ok_pressed: bool) -> None:
if ok_pressed:
field: EnvConfigField
for i in ConfigManager.env_config.fields:
if i.name == title:
field = i
break
else:
return

ConfigManager.env_config.values[title] = type(field.default_value)(value)
self.widget = self.build_ui()
41 changes: 41 additions & 0 deletions esbmc_ai_config/contexts/esbmc_menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Author: Yiannis Charalambous

from typing_extensions import override

import urwid
from esbmc_ai_config.contexts.base_menu import BaseMenu
from esbmc_ai_config.widgets.text_input_button import TextInputButton


class ESBMCMenu(BaseMenu):
def __init__(self) -> None:
super().__init__(title="ESBMC Options", choices=self._get_menu_choices())

def _on_esbmc_path(self, title: str, value: str, ok_pressed: bool) -> None:
return

def _get_menu_choices(self) -> list[str | urwid.Widget]:
return [
TextInputButton(
"ESBMC Path",
"",
on_submit=self._on_esbmc_path,
),
"ESBMC Parameters",
]

@override
def build_ui(self) -> urwid.Widget:
self.choices = self._get_menu_choices()
menu: urwid.Widget = super().build_ui()
overlay: urwid.Widget = urwid.Overlay(
urwid.LineBox(menu),
urwid.SolidFill("\N{MEDIUM SHADE}"),
align="center",
valign="middle",
width=("relative", 60),
height=("relative", 15),
min_width=20,
min_height=10,
)
return overlay
19 changes: 16 additions & 3 deletions esbmc_ai_config/contexts/main_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from esbmc_ai_config.contexts.base_menu import BaseMenu
from esbmc_ai_config.context_manager import ContextManager
from esbmc_ai_config.contexts.env_menu import EnvMenu
from esbmc_ai_config.contexts.esbmc_menu import ESBMCMenu
from esbmc_ai_config.contexts.save_menu import SaveMenu


class MainMenu(BaseMenu):
Expand All @@ -18,6 +20,8 @@ def __init__(self) -> None:
"Setup Environment",
"ESBMC Settings",
"AI Configuration",
"Custom LLM",
urwid.Divider(),
"Save",
"Save As",
urwid.Divider(),
Expand All @@ -26,6 +30,9 @@ def __init__(self) -> None:
back_choice=False,
)

@override
def build_ui(self) -> urwid.Widget:
list_menu: urwid.Widget = super().build_ui()
# Add additional content to widget.
text = urwid.ListBox(
[
Expand All @@ -45,17 +52,17 @@ def __init__(self) -> None:
)

top: Widget = urwid.Overlay(
urwid.LineBox(self.widget),
urwid.LineBox(list_menu),
text,
align="center",
valign="middle",
width=("relative", 60),
height=("relative", 15),
min_width=20,
min_height=12,
min_height=14,
)

self.widget = top
return top

@override
def item_chosen(self, button, choice) -> None:
Expand All @@ -67,6 +74,12 @@ def item_chosen(self, button, choice) -> None:
case "Setup Environment":
ContextManager.push_context(EnvMenu())
return
case "ESBMC Settings":
ContextManager.push_context(ESBMCMenu())
return
case "Save":
ContextManager.push_context(SaveMenu())
return

def exit_program(self, _):
raise urwid.ExitMainLoop()
68 changes: 68 additions & 0 deletions esbmc_ai_config/contexts/save_menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Author: Yiannis Charalambous

from typing_extensions import override

import urwid
from esbmc_ai_config.context import Context
from esbmc_ai_config.context_manager import ContextManager
from esbmc_ai_config.contexts.dialog_context import DialogContext
from esbmc_ai_config.models.config_manager import ConfigManager


class SaveMenu(Context):
def __init__(self) -> None:
super().__init__()

def _on_cancel(self, button) -> None:
ContextManager.pop_context()

def _on_ok(self, button) -> None:
ContextManager.pop_context()
ConfigManager.env_config.save()
# TODO
# ConfigManager.json_config.save()
ContextManager.push_context(
DialogContext(
"Success",
"ESBMC-AI Env and Config have been written successfully!",
)
)

@override
def build_ui(self) -> urwid.Widget:
cancel_button: urwid.Button = urwid.Button("Cancel", on_press=self._on_cancel)
ok_button: urwid.Button = urwid.Button("OK", on_press=self._on_ok)

body: list[urwid.Widget] = [
urwid.Text("Confirm"),
urwid.Divider(),
urwid.Text("Are you sure you want to save at location: "),
urwid.Divider(),
urwid.Columns(
[
("weight", 1, urwid.Divider()),
(
"weight",
2,
urwid.AttrMap(cancel_button, None, focus_map="reversed"),
),
("weight", 1, urwid.Divider()),
("weight", 2, urwid.AttrMap(ok_button, None, focus_map="reversed")),
("weight", 1, urwid.Divider()),
]
),
]

list_menu: urwid.ListBox = urwid.ListBox(body)
# Wrap in nice UI.
overlay: urwid.Widget = urwid.Overlay(
urwid.LineBox(urwid.Padding(list_menu, left=2, right=2)),
urwid.SolidFill("\N{MEDIUM SHADE}"),
align="center",
valign="middle",
width=("relative", 60),
height=("relative", 15),
min_width=20,
min_height=10,
)
return overlay
Empty file.
Loading

0 comments on commit 8d060b6

Please sign in to comment.