Skip to content

Commit

Permalink
Feature/ux (#19)
Browse files Browse the repository at this point in the history
* fix: Remove enum which is not supported on kicad 6.0 for Ubuntu

* fix: Remove minmal max_width

* Revert "fix: Remove minmal max_width"

This reverts commit 5813cca8ea95337631fce5a1eb9a648d12d8bb49.

* feat: Enable resizing the summary panel

* feat: Record and restore the sash position

* fix: Remove post init window

* feat: Enable resizing the left & right panel of the main panel

* feat: Show progress bar while generating gerber files

* fix: Change the base class for workers

* fix: Fix the settings

* fix: Fix the size

* fix: Donot call pcbnew.refresh from working thread

* alpha release

* fool test

* feat: More detailed progress bar

* fix: Add others in order region

* fix: Ajust the default height

* fix: fix the code to name

* alpha release

* feat: Remove entry for setting the language

Follow the language setting in Kicad

* fix: Ajust the preference panel

* fix: Adjust  the style of progressbar

* feat: Add app icon

* fix: Remove  vertical line in the summary panel

* fix: Restore the workflows

* feat: Update doc

* fix: Restore the workflows

* fix: Remove dist files

---------

Co-authored-by: liangtie.qian <yihuo0420@gmail.com>
  • Loading branch information
2 people authored and SYSUeric66 committed Nov 10, 2023
1 parent 538e3f1 commit 4a6057e
Show file tree
Hide file tree
Showing 21 changed files with 750 additions and 436 deletions.
20 changes: 18 additions & 2 deletions __main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
from wx import App, Locale


class StandAloneApp(App):
def __init__(
self, redirect=False, filename=None, useBestVisual=False, clearSigInt=True
):
super().__init__(redirect, filename, useBestVisual, clearSigInt)

def OnInit(self):
from kicad_amf_plugin.settings.setting_manager import SETTING_MANAGER

self.locale = Locale(SETTING_MANAGER.get_language())
return True


if __name__ == "__main__":
from kicad_amf_plugin.plugin._main import _main
from wx import App
app = App()

app = StandAloneApp()
_main()
app.MainLoop()
Binary file added docs/place_order_new.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 6 additions & 40 deletions kicad_amf_plugin/gui/app_base.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from kicad_amf_plugin.language.lang_const import get_supported_language
from kicad_amf_plugin.language.lang_const import LANG_DOMAIN
from kicad_amf_plugin.settings.supported_layer_count import AVAILABLE_LAYER_COUNTS
import builtins
import sys
import os
from kicad_amf_plugin import PLUGIN_ROOT
from kicad_amf_plugin.gui.event.pcb_fabrication_evt_list import EVT_LOCALE_CHANGE
from kicad_amf_plugin.kicad.board_manager import load_board_manager
from kicad_amf_plugin.utils.combo_box_ignore_wheel import ComboBoxIgnoreWheel
from kicad_amf_plugin.icon import GetImagePath
import wx

# add translation macro to builtin similar to what gettext does
Expand All @@ -23,63 +22,30 @@ def _displayHook(obj):
class BaseApp(wx.EvtHandler):
def __init__(self):
super().__init__()
self.Bind(EVT_LOCALE_CHANGE, self.on_locale_changed)
# work around for Python stealing "_"
sys.displayhook = _displayHook
self.locale = None
wx.Locale.AddCatalogLookupPathPrefix(
os.path.join(PLUGIN_ROOT, "language", "locale")
)
existing_locale = wx.GetLocale()
if existing_locale is not None:
existing_locale.AddCatalog(LANG_DOMAIN)

def load_success(self):
from kicad_amf_plugin.settings.setting_manager import SETTING_MANAGER
self.update_language(SETTING_MANAGER.language)

SETTING_MANAGER.register_app(self)
self.board_manager = load_board_manager()
if self.board_manager.board.GetCopperLayerCount() not in AVAILABLE_LAYER_COUNTS:
wx.MessageBox(_("Unsupported layer count!"))
return False
return True

def on_locale_changed(self, evt):
self.update_language(evt.GetInt())
info = wx.MessageDialog(
self.main_wind,
_(
"Restart the plugin to apply the new locale ?\nFor full translation(including the options), restarting KiCad is required"
),
_("Tip"),
wx.YES | wx.ICON_QUESTION | wx.NO,
)
res = info.ShowModal()
info.Destroy()
if res == wx.ID_YES:
if self.main_wind:
self.main_wind.Destroy()
self.startup_dialog()

def update_language(self, lang: int):
if lang in get_supported_language():
selLang = lang
else:
wx.MessageBox(f"Unexpected language id {lang}")
selLang = wx.LANGUAGE_ENGLISH
if self.locale:
assert sys.getrefcount(self.locale) <= 2
del self.locale

self.locale = wx.Locale(selLang)
if self.locale.IsOk():
self.locale.AddCatalog(LANG_DOMAIN)
else:
wx.MessageBox(self.locale.GetLocale() + _(" is not supported"))
self.locale = None

def startup_dialog(self):
from kicad_amf_plugin.gui.main_frame import MainFrame
from kicad_amf_plugin.settings.setting_manager import SETTING_MANAGER

self.main_wind = MainFrame(
self.board_manager, SETTING_MANAGER.get_window_size()
)
self.main_wind.SetIcon(wx.Icon(GetImagePath("Huaqiu.ico")))
self.main_wind.Show()
107 changes: 79 additions & 28 deletions kicad_amf_plugin/gui/main_frame.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
from kicad_amf_plugin.gui.summary.price_summary_model import PriceCategory
from kicad_amf_plugin.kicad.board_manager import BoardManager
from kicad_amf_plugin.kicad.fabrication_data_generator_evt import (
EVT_BUTTON_FABRICATION_DATA_GEN_RES,
FabricationDataGenEvent,
GenerateStatus,
)
from kicad_amf_plugin.order.supported_region import SupportedRegion
from kicad_amf_plugin.pcb_fabrication.base.base_info_view import BaseInfoView
from kicad_amf_plugin.pcb_fabrication.process.process_info_view import ProcessInfoView
Expand Down Expand Up @@ -37,6 +42,7 @@
import webbrowser
import json
from kicad_amf_plugin.order.order_region import OrderRegion, URL_KIND
from kicad_amf_plugin.kicad.fabrication_data_generator_thread import DataGenThread
from enum import Enum


Expand Down Expand Up @@ -79,16 +85,33 @@ def __init__(self, board_manager: BoardManager, size, parent=None):
)
self._board_manager = board_manager
self._fabrication_data_gen = None
self._fabrication_data_gen_thread = None
self._pcb_form_parts: "dict[PCBFormPart, FormPanelBase]" = {}
self._data_gen_progress: wx.ProgressDialog = None
self._dataGenThread: DataGenThread = None
SINGLE_PLUGIN.register_main_wind(self)
self.init_ui()

def show_data_gen_progress_dialog(self):
if self._data_gen_progress is not None:
self._data_gen_progress.Destroy()
self._data_gen_progress = None
self._data_gen_progress = wx.ProgressDialog(
_("Preparing for your order"),
_("The browser will be launched automatically while ready"),
maximum=GenerateStatus.MAX_PROGRESS,
parent=self,
style=0 | wx.PD_APP_MODAL,
)

def init_ui(self):
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
left_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.main_splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
self.left_panel_container = wx.Panel(self.main_splitter)

pcb_fab_scroll_wind = wx.ScrolledWindow(
self,
self.left_panel_container,
wx.ID_ANY,
wx.DefaultPosition,
wx.Size(-1, -1),
Expand All @@ -104,9 +127,14 @@ def init_ui(self):
pcb_fab_scroll_wind.SetSizer(lay_pcb_fab_panel)
pcb_fab_scroll_wind.Layout()

self.summary_view = SummaryPanel(self)
main_sizer.Add(pcb_fab_scroll_wind, 1, wx.EXPAND, 8)
main_sizer.Add(self.summary_view, 0, wx.EXPAND, 8)
self.summary_view = SummaryPanel(self.main_splitter)
left_sizer.Add(pcb_fab_scroll_wind, 1, wx.EXPAND, 8)
self.left_panel_container.SetSizer(left_sizer)
self.left_panel_container.Layout()
left_sizer.Fit(self.left_panel_container)
self.main_splitter.SplitVertically(
self.left_panel_container, self.summary_view, 400
)

self.Bind(
EVT_LAYER_COUNT_CHANGE,
Expand All @@ -121,15 +149,49 @@ def init_ui(self):
self.Bind(EVT_ORDER_REGION_CHANGED, self.on_order_region_changed)
self.Bind(wx.EVT_SIZE, self.OnSize, self)
self.Bind(wx.EVT_CLOSE, self.OnClose, self)
self.Bind(
wx.EVT_SPLITTER_SASH_POS_CHANGED,
self.on_sash_pos_changed,
self.main_splitter,
)

self.main_splitter.Bind(wx.EVT_IDLE, self.main_splitter_on_idle)

self.Bind(
EVT_BUTTON_FABRICATION_DATA_GEN_RES, self.on_fabrication_data_gen_progress
)

for i in self._pcb_form_parts.values():
i.init()
i.on_region_changed()

main_sizer = wx.BoxSizer(wx.HORIZONTAL)
main_sizer.Add(self.main_splitter, 1, wx.EXPAND, 5)
self.SetSizer(main_sizer)
self.Layout()
self.Centre(wx.BOTH)

def on_fabrication_data_gen_progress(self, evt: FabricationDataGenEvent):
if self._data_gen_progress is not None:
res = evt.get_status()
if GenerateStatus.RUNNING == res.get_status():
self._data_gen_progress.Update(res.get_progress(), res.get_message())
else:
self._data_gen_progress.Destroy()
self._data_gen_progress = None
if GenerateStatus.FAILED == res.get_status():
wx.MessageBox(f"{res.get_message()}")

def on_sash_pos_changed(self, evt):
sash_pos = evt.GetSashPosition()
SETTING_MANAGER.set_mainwindow_sash_pos(sash_pos)

def main_splitter_on_idle(self, evt):
self.main_splitter.SetSashPosition(
SETTING_MANAGER.get_mainwindow_sash_position()
)
self.main_splitter.Unbind(wx.EVT_IDLE)

@property
def fabrication_data_generator(self):
if self._fabrication_data_gen is None:
Expand Down Expand Up @@ -242,35 +304,24 @@ def on_update_price(self, evt):
raise e # TODO remove me

def on_place_order(self, evt):
self.show_data_gen_progress_dialog()
if not self.form_is_valid():
return
try:
url = OrderRegion.get_url(
SETTING_MANAGER.order_region, URL_KIND.PLACE_ORDER
)
if url is None:
wx.MessageBox(_("No available url for placing order in current region"))
return
with self.fabrication_data_generator.create_kicad_pcb_file() as zipfile:
rsp = requests.post(
url,
files={"file": open(zipfile, "rb")},
data=self.get_place_order_form(),
)
urls = json.loads(rsp.content)
for key in "url", "redirect":
if key in urls:
uat_url = str(urls[key])
webbrowser.open(uat_url)
return
raise Exception("No available order url in the response")
except Exception as e:
wx.MessageBox(str(e))
raise e # TODO remove me
url = OrderRegion.get_url(SETTING_MANAGER.order_region, URL_KIND.PLACE_ORDER)
if url is None:
wx.MessageBox(_("No available url for placing order in current region"))
return
if self._dataGenThread is not None:
self._dataGenThread.join()
self._dataGenThread = None
self._dataGenThread = DataGenThread(
self, self.fabrication_data_generator, self.get_place_order_form(), url
)

def adjust_size(self):
for i in self._pcb_form_parts.values():
i.Layout()
self.left_panel_container.Layout()
self.Layout()

def on_order_region_changed(self, ev):
Expand Down
3 changes: 1 addition & 2 deletions kicad_amf_plugin/gui/summary/price_model_base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from dataclasses import dataclass
from enum import Enum
import abc
import json


class PriceModelCol(Enum):
class PriceModelCol:
DESC = 0
VALUE = DESC + 1
COL_COUNT = VALUE + 1
Expand Down
30 changes: 19 additions & 11 deletions kicad_amf_plugin/gui/summary/summary_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
from kicad_amf_plugin.utils.roles import EditDisplayRole
from .ui_summary_panel import UiSummaryPanel
from kicad_amf_plugin.icon import GetImagePath
from kicad_amf_plugin.language.lang_setting_pop_menu import LangSettingPopMenu
import wx
from .order_summary_model import OrderSummary, OrderSummaryModel
from .order_summary_model import OrderSummaryModel
from .price_summary_model import PriceSummaryModel


Expand All @@ -18,9 +17,9 @@


OrderRegionSettings = (
EditDisplayRole(SupportedRegion.CHINA_MAINLAND, _("CN")),
EditDisplayRole(SupportedRegion.JAPAN, _("JP")),
EditDisplayRole(SupportedRegion.EUROPE_USA, _("EU/USA")),
EditDisplayRole(SupportedRegion.CHINA_MAINLAND, _("Mainland China")),
EditDisplayRole(SupportedRegion.EUROPE_USA, _("Worldwide (English)")),
EditDisplayRole(SupportedRegion.JAPAN, _("Worldwide (Japanese)")),
)


Expand All @@ -29,10 +28,14 @@ def __init__(self, *args, **kw):
super().__init__(*args, **kw)

self.init_ui()
self.btn_set_language.Bind(wx.EVT_BUTTON, self.on_set_lang_clicked)
self.btn_update_price.Bind(wx.EVT_BUTTON, self.on_update_price_clicked)
self.btn_place_order.Bind(wx.EVT_BUTTON, self.on_place_order_clicked)
self.choice_order_region.Bind(wx.EVT_CHOICE, self.on_region_changed)
self.Bind(
wx.EVT_SPLITTER_SASH_POS_CHANGED,
self.on_sash_changed,
self.splitter_detail_summary,
)

def init_ui(self):
self.list_order_summary.AppendTextColumn(
Expand Down Expand Up @@ -95,6 +98,12 @@ def init_ui(self):

self.SetMinSize(wx.Size(max_width + 30, -1))

def splitter_detail_summaryOnIdle(self, event):
self.splitter_detail_summary.SetSashPosition(
SETTING_MANAGER.get_summary_detail_sash_pos()
)
self.splitter_detail_summary.Unbind(wx.EVT_IDLE)

def update_price_detail(self, price: "dict"):
self.model_price_summary.update_price(price)

Expand All @@ -113,6 +122,10 @@ def on_place_order_clicked(self, ev):
evt = PlaceOrder(id=-1)
wx.PostEvent(self.Parent, evt)

def on_sash_changed(self, evt):
sash_pos = evt.GetSashPosition()
SETTING_MANAGER.set_summary_detail_sash_pos(sash_pos)

def GetImagePath(self, bitmap_path):
return GetImagePath(bitmap_path)

Expand All @@ -123,11 +136,6 @@ def GetLineHeight(parent):
line.Destroy()
return height

def on_set_lang_clicked(self, evt):
menu = LangSettingPopMenu(SETTING_MANAGER.language)
self.PopupMenu(menu)
menu.Destroy()

def clear_content(self):
for i in self.model_order_summary, self.model_price_summary:
i.clear_content()
Expand Down
Loading

0 comments on commit 4a6057e

Please sign in to comment.