diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5596c82..deb6319 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -24,6 +24,9 @@ jobs: - name: Run tests run: pytest -v tests + - name: Run I18N conversion + run: python i18n.py + - name: Build run: | python3 setup.py sdist diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ffa2afe..4730c52 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -29,6 +29,9 @@ jobs: - name: Run tests run: pytest tests + - name: Run I18N conversion + run: python i18n.py + - name: Build run: | python3 setup.py sdist diff --git a/i18n.py b/i18n.py index b472d74..b83bd62 100644 --- a/i18n.py +++ b/i18n.py @@ -1,5 +1,6 @@ import os import polib +import sys from collections import defaultdict localedir = "katrain/i18n/locales" @@ -11,6 +12,8 @@ lang_to_strings = defaultdict(set) DEFAULT_LANG = "en" +errors = False + po = {} pofile = {} for lang in locales: @@ -28,13 +31,19 @@ for lang in locales: for msgid in strings_to_langs.keys() - lang_to_strings[lang]: if lang == DEFAULT_LANG: print("Message id", msgid, "found as ", strings_to_langs[msgid], "but missing in default", DEFAULT_LANG) + errors = True elif DEFAULT_LANG in strings_to_langs[msgid]: print("Message id", msgid, "missing in ", lang, "-> Adding it from", DEFAULT_LANG) entry = polib.POEntry(msgid=msgid, msgstr=strings_to_langs[msgid][DEFAULT_LANG], comment="TODO") po[lang].append(entry) + errors = True else: print(f"MISSING IN DEFAULT AND {lang}", strings_to_langs[msgid]) + errors = True po[lang].save(pofile[lang]) mofile = pofile[lang].replace(".po", ".mo") po[lang].save_as_mofile(mofile) print("Fixed", pofile[lang], "and converted ->", mofile) + + +sys.exit(int(errors)) diff --git a/katrain/__main__.py b/katrain/__main__.py index 3b3aa31..156b24e 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -132,6 +132,11 @@ class KaTrainGui(Screen): top, bot = [w.__self__ for w in self.board_controls.circles] # no weakref if self.game.next_player.player == "W": top, bot = bot, top + self.controls.players['W'].active = True + self.controls.players['B'].active = False + else: + self.controls.players['W'].active = False + self.controls.players['B'].active = True self.board_controls.mid_circles_container.clear_widgets() self.board_controls.mid_circles_container.add_widget(bot) self.board_controls.mid_circles_container.add_widget(top) @@ -140,11 +145,11 @@ class KaTrainGui(Screen): # update engine status dot if not self.engine or not self.engine.katago_process or self.engine.katago_process.poll() is not None: - self.controls.engine_status_col = ENGINE_DOWN_COL + self.board_controls.engine_status_col = ENGINE_DOWN_COL elif len(self.engine.queries) == 0: - self.controls.engine_status_col = ENGINE_READY_COL + self.board_controls.engine_status_col = ENGINE_READY_COL else: - self.controls.engine_status_col = ENGINE_BUSY_COL + self.board_controls.engine_status_col = ENGINE_BUSY_COL # redraw if redraw_board: @@ -174,6 +179,11 @@ class KaTrainGui(Screen): if self.game: self.message_queue.put([self.game.game_id, message, *args]) + def update_players(self): + for player in 'BW': + self.controls.players[player].player_type = self.game.players[player].player_type + self.game.players[player].player_subtype = self.game.players[player].player_subtype + def _do_new_game(self, move_tree=None, analyze_fast=False): self.board_gui.animating_pv = None self.engine.on_new_game() # clear queries @@ -181,6 +191,7 @@ class KaTrainGui(Screen): self.controls.graph.initialize_from_game(self.game.root) self.controls.periods_used = {"B": 0, "W": 0} self.update_state(redraw_board=True) + self.update_players() def _do_ai_move(self, node=None): if node is None or self.game.current_node == node: diff --git a/katrain/core/utils.py b/katrain/core/utils.py index 118dcb8..640f40e 100644 --- a/katrain/core/utils.py +++ b/katrain/core/utils.py @@ -94,7 +94,7 @@ class Lang(Observable): pass # proxy no longer exists -LANGUAGE = "nl" +LANGUAGE = "en" i18n = Lang(LANGUAGE) diff --git a/katrain/gui.kv b/katrain/gui.kv index 2fc4556..41b41cb 100644 --- a/katrain/gui.kv +++ b/katrain/gui.kv @@ -10,10 +10,11 @@ #-- NEW #:import RED __main__.RED +#:import WHITE __main__.WHITE +#:set LIGHTGREY [0.7,0.7,0.7,1] #:set BLACK [0.05,0.05,0.05,1] -#:set WHITE [0.95,0.95,0.95,1] #:set GREY [0.5,0.5,0.5,1] #:set GREEN [0.1,0.8,0.1,1] #:set LIGHTBLUE [0.3,0.7,0.9,1] @@ -24,7 +25,7 @@ #:set POINTLOSS_COLOR YELLOW #:set WINRATE_COLOR GREEN -#:set BUTTON_INACTIVE_COLOR GREY +#:set BUTTON_INACTIVE_COLOR LIGHTGREY #:set BACKGROUND_COLOR [36/255,48/255,62/255,1] #:set BOX_BACKGROUND_COLOR [46/255,65/255,88/255,1] #:set TEXT_COLOR WHITE @@ -33,6 +34,12 @@ : font_name: i18n._('Roboto') + canvas.before: + Color: + rgba: RED + Line: + rectangle: (*self.pos,*self.size) + width: 1 : font_name: i18n._('Roboto') @@ -75,42 +82,42 @@ # new widgets -: +: + ripple_duration_in_slow: 0.6 text_color: WHITE - md_bg_color: BOX_BACKGROUND_COLOR + background_color: BOX_BACKGROUND_COLOR label: label I18NLabel: id: label text: root.text + size: self.texture_size size_hint_x: None color: root.text_color font_size: root.font_size halign: root.halign -: - ripple_duration_in_slow: 0.6 + + inactive_background_color: BACKGROUND_COLOR + active_background_color: BOX_BACKGROUND_COLOR + background_color: self.active_background_color if self.state=='down' else self.inactive_background_color + outline_color: self.active_outline_color if self.state=='down' else self.inactive_outline_color -: - inactive_color: BACKGROUND_COLOR - active_color: BOX_BACKGROUND_COLOR - md_bg_color: self.active_color if self.state=='down' else self.inactive_color +: + outline_color: WHITE + text_color: self.outline_color -: - outline_color: root.color - text_color: root.color +: + inactive_outline_color: BUTTON_INACTIVE_COLOR + active_outline_color: WHITE + text_color: self.outline_color -: - inactive_color: BUTTON_INACTIVE_COLOR - text_color: root.color if self.state=='down' else self.inactive_color - outline_color: root.color if self.state=='down' else self.inactive_color - -: # only wants height +: # only wants height width: self.label.texture_size[0] + self.hor_padding * 2 - font_size: 0.75 * self.height / len(self.label.text.split('\n')) + font_size: 0.7 * self.height / len(self.label.text.split('\n')) -: # only wants height +: # only wants height width: self.label.texture_size[0] + self.hor_padding * 2 - font_size: 0.8 * self.height / len(self.label.text.split('\n')) + font_size: 0.7 * self.height / len(self.label.text.split('\n')) : @@ -275,12 +282,11 @@ mid_circles_container: mid_circles_container pass_btn: pass_btn adaptive_height: True - SizedMDFlatRectangleButton: + AutoSizedMDRectangleButton: id: pass_btn text: i18n._('pass-button-text') size_hint: None, 0.5 - width: 2*self.height - pos_hint: {'x': 0.1,'center_y':0.5} + pos_hint: {'center_x': 0.15,'center_y':0.5} on_left_release: root.katrain("play",None) BoxLayout: size_hint: None, 1 @@ -290,7 +296,7 @@ size_hint: 0.075, 0.5 NavIconButton: icon: 'img/flaticon/previous999.png' - on_press: print(self.size,self.image.size,self.parent.size,self.icon_size) #root.katrain('undo',999) + on_press: root.katrain('undo',999) NavIconButton: icon: 'img/flaticon/previous5.png' on_press: root.katrain('undo',5) @@ -323,21 +329,40 @@ on_press: root.katrain('redo',999) NavIconButton: icon: 'img/flaticon/route.png' + ClickableLabel: + pos_hint: {'center_x': 0.85,'center_y':0.5} + size_hint: None, 1 + width: self.height + canvas: + Color: + rgba: root.engine_status_col + Ellipse: + pos: self.pos[0] + self.width/2 - self.width/6, self.pos[1] + self.height/2 - self.width/6 + size: self.width/3, self.width/3 + Color: + rgba: BLACK + Line: + circle: self.pos[0] + self.width/2, self.pos[1] + self.height/2, self.width/6 + width: 1 + on_press: app.gui.controls.set_status(i18n._('ai-ponder')) + : icon: 'img/hamburger.png' - size_hint: None, 1 width: self.height icon_size: [self.height * 0.8, self.height * 0.8] # ---------- components of right pane ------- -: +: captures: 0 - name: 'Player' - outline_color: RED player: 'Black' - description: '...' + player_type: 'Player' + player_subtype: 'Normal game' + background_color: BOX_BACKGROUND_COLOR if self.active else BACKGROUND_COLOR + outline_color: BOX_BACKGROUND_COLOR + outline_width: 2 + padding: [2*CP_PADDING,CP_PADDING,CP_PADDING,CP_PADDING] CircleWithText: player: root.player text: str(root.captures) @@ -345,37 +370,15 @@ MDBoxLayout: size_hint: 0.75, 1 orientation: 'vertical' + spacing: CP_SPACING I18NLabel: - text: root.name + text: root.player_type + size_hint: 1,0.55 + font_size: 0.8 * self.height I18NLabel: - text: root.description - - -: - engine_status_col: [1,1,1,1] - MDBoxLayout: - orientation: 'vertical' - LightLabel: - size_hint: 1, 0.5 - text: 'AI\nStatus' - font_size: self.height/3 - halign: 'center' - valign: 'middle' - ClickableLabel: - size_hint: 1, 0.5 - canvas: - Color: - rgba: root.engine_status_col - Ellipse: - pos: self.pos[0] + self.width/2 - self.width/6, self.pos[1] + self.height/2 - self.width/6 - size: self.width/3, self.width/3 - Color: - rgba: BLACK - Line: - circle: self.pos[0] + self.width/2, self.pos[1] + self.height/2, self.width/6 - width: 1 - on_press: app.gui.controls.set_status("This simply indicates the Engine status, going from green (idle) to orange (processing queries). It turns red when the engine has crashed or fails to start.") - + text: root.player_subtype + size_hint: 1,0.45 + font_size: 0.7 * self.height : icon: 'img/flaticon/pause.png' @@ -530,12 +533,17 @@ : background_color: BOX_BACKGROUND_COLOR - outline_color: [0,0,0,0] do_scroll_x: False scroll_type: ['bars'] bar_width: 5 bar_color: BUTTON_COLOR label: label + canvas.before: + Color: + rgba: root.outline_color + Line: + rectangle: (*self.pos,*self.size) + width: 1 I18NLabel: id: label markup: root.markup @@ -580,7 +588,7 @@ status: status padding: CP_PADDING spacing: CP_SPACING - player_box_height: max(50, 0.1 * root.height) + player_box_height: max(50, 0.075 * root.height) timer_box_height: max(50, 0.125 * root.height) graph_box_height: max(100, 0.2 * root.height) stats_box_height: max(50, 0.125 * root.height) @@ -598,13 +606,13 @@ size_hint_y: None height: root.timer_box_height spacing: CP_SPACING - PonderInfo: - id: ponder - engine_status_col: root.engine_status_col - size_hint_x: 0.2 Timer: id: timer size_hint_x: 0.7 + BoxLayout: + size_hint_x: 0.3 + Label: + text: '??' CollapsablePanel: height_open: root.graph_box_height closed_label: 'closedlabel:scoregraph' @@ -629,7 +637,7 @@ size_hint_y_open: 1 closed_label: 'closedlabel:info¬es' options: ['info','notes'] - option_colors: [RED,GREEN] + option_colors: [SCORE_COLOR,WINRATE_COLOR] option_default_active: [True,False] on_option_state: info.size_hint_y = int(args[1]['info'])+1e-9 @@ -662,6 +670,7 @@ : adaptive_width: True + spacing: CP_SPACING size_hint: None, 0.7 pos_hint: {'center_y':0.5} I18NLabel: @@ -669,16 +678,22 @@ text: root.text halign: 'center' font_size: root.height / 3 + color: checkbox.selected_color if checkbox.active else checkbox.unselected_color size_hint_x: None width: self.texture_size[0] + 4 MDCheckbox: + id: checkbox size_hint: None,0.5 pos_hint: {'center_y': 0.5} width: self.height active: root.active selected_color: WHITE - unselected_color: WHITE - on_active: print(label.size,label.texture_size) #if app.gui: app.gui.update_state() + unselected_color: LIGHTGREY + on_active: if app.gui: app.gui.update_state() + +: + + : katrain: app.gui @@ -695,44 +710,42 @@ HamburgerButton: id: hamburger size_hint: None, 1 - width: self.height - pos_hint: {'top': 0} + pos_hint: {'center_y': 0.5,'left': 0} on_press: app.gui.nav_drawer.set_state("open") MDBoxLayout: pos_hint: {'center_x': 0.5,'center_y': 0.5} size_hint: None, 1 adaptive_width: True - spacing: 8 + spacing: show_children.width/4 AnalysisToggle: id: show_children - text: 'Next\nMoves' + text: i18n._("analysis:nextmoves") active: True AnalysisToggle: id: eval - text: 'Evaluation\nDots' + text: i18n._("analysis:dots") AnalysisToggle: id: ownership - text: 'Expected\nTerritory' + text: i18n._('analysis:territory') AnalysisToggle: id: policy - text: 'Policy\nMoves' + text: i18n._("analysis:policy") AnalysisToggle: id: hints text: 'Top\nMoves' - AutoSizedMDFlatRectangleButton: - md_bg_color: BOX_BACKGROUND_COLOR - size_hint_y: 0.7 + AutoSizedMDRectangleButton: + background_color: BOX_BACKGROUND_COLOR + size_hint_y: 0.5 id: analysis_button on_press: root.open_analysis_menu() text: 'Analysis' pos_hint: {'center_y':0.5} - - - on_press: print(self.size, root.size, image.size, root.parent.parent, root.parent) - font_size: self.height * 0.5 + size_hint_y: None + height: self.parent.item_height or 50 + background_color: BOX_BACKGROUND_COLOR MDFloatLayout: size_hint: None, 1 width: self.height @@ -742,7 +755,7 @@ mipmap: True size_hint: 0.7,0.7 pos_hint: {'center_y': 0.5,'center_x': 0.5} - Label: + I18NLabel: text: root.text text_size: self.size size_hint_x: 1 @@ -750,87 +763,85 @@ valign: 'middle' font_size: root.font_size color: WHITE - Label: + I18NLabel: text: root.shortcut halign: 'left' valign: 'middle' size_hint_x: 1/3 font_size: root.font_size - color: GREY + color: LIGHTGREY - + size_hint: 1,1 - font_size: 0.4 * self.height + icon_size: self.height * 0.9, self.height * 0.9 + +: + background_color: BACKGROUND_COLOR + font_size: self.height * 0.5 + height: self.parent.item_height or 50 + size_hint: 1,None : katrain: app.gui background_color: BOX_BACKGROUND_COLOR orientation: 'vertical' - canvas.after: - Color: - rgba: YELLOW - Line: - rectangle: (*self.pos,*self.size) - width: 1 - MDBoxLayout: - size_hint: 1, 1/10 - canvas.before: - Color: - rgba: RED - Line: - rectangle: (*self.pos,*self.size) - width: 1 - LangButton: - text: i18n._('English') - on_press: app.language = 'en' - LangButton: - text: i18n._('Dutch') - on_press: app.language = 'nl' - LangButton: - text: i18n._('Korean') - on_press: app.language = 'ko' + item_height: self.height/20 + MenuLabel: + text: i18n._('menu:playersetup') Label: + MenuLabel: MDBoxLayout: - canvas.before: - Color: - rgba: RED - Line: - rectangle: (*self.pos,*self.size) - width: 1 orientation: 'vertical' - size_hint: 1, 1/3 + size_hint: 1, None + adaptive_height: True + item_height: root.item_height MainMenuItem: - text: 'General Settings' - icon: 'img/flaticon/settings.png' - on_action: root.katrain('config-popup') + text: i18n._('menu:newgame') + icon: 'img/flaticon/newgame.png' + shortcut: 'Ctrl-N' + on_action: root.katrain("new-game-popup") + height: root.item_height MainMenuItem: - text: 'Save Game' + text: i18n._('menu:save') icon: 'img/flaticon/savegame.png' shortcut: 'Ctrl-S' on_action: root.katrain("analyze-sgf-popup") MainMenuItem: - text: 'Load Game' + text: i18n._('menu:load') icon: 'img/flaticon/loadgame.png' shortcut: 'Ctrl-L' on_action: root.katrain("analyze-sgf-popup") MainMenuItem: - text: 'New Game' - icon: 'img/flaticon/newgame.png' - size_hint_x: 1 - shortcut: 'Ctrl-N' - on_action: root.katrain("new-game-popup") + text: i18n._('menu:settings') + icon: 'img/flaticon/settings.png' + on_action: root.katrain('config-popup') + MenuLabel: + text: i18n._('menu:lang') + size_hint_y: None + MDBoxLayout: + size_hint: 1, None + height: 1.5 * root.item_height + LangButton: + icon: 'img/flaticon/flag-uk.png' + on_press: app.language = 'en' + LangButton: + icon: 'img/flaticon/flag-nl.png' + on_press: app.language = 'nl' + LangButton: + icon: 'img/flaticon/flag-ko.png' + on_press: app.language = 'ko' : -: - inactive_color: BACKGROUND_COLOR - active_color: YELLOW +: + inactive_background_color: BOX_BACKGROUND_COLOR + active_background_color: YELLOW ripple_color: BACKGROUND_COLOR - md_bg_color: self.active_color if self.state=='down' else self.inactive_color - text_color: self.inactive_color if self.state=='down' else self.active_color + text_color: self.inactive_background_color if self.state=='down' else self.active_background_color size_hint: 0.5,1 + font_size: self.height * 0.5 group: 'play_analyze' allow_no_selection: False @@ -863,7 +874,6 @@ background_color: BACKGROUND_COLOR MDBoxLayout: orientation: 'vertical' - padding: CP_PADDING, CP_PADDING, CP_PADDING, 0 AnalysisControls: id: analysis_controls size_hint_y: None diff --git a/katrain/gui/ai_settings.py b/katrain/gui/ai_settings.py index 59882f8..2be851c 100644 --- a/katrain/gui/ai_settings.py +++ b/katrain/gui/ai_settings.py @@ -5,7 +5,7 @@ from kivymd.uix.gridlayout import MDGridLayout from kivymd.uix.label import MDLabel from katrain.core.utils import OUTPUT_DEBUG, OUTPUT_ERROR -from katrain.gui.kivyutils import SizedMDFlatButton, LightHelpLabel, ScaledLightLabel, StyledSpinner +from katrain.gui.kivyutils import SizedMDButton, LightHelpLabel, ScaledLightLabel, StyledSpinner from katrain.gui.popups import QuickConfigGui, ConfigPopup, InputParseError KV = """ @@ -117,9 +117,9 @@ class ConfigAIPopupContents(QuickConfigGui): self.options_grid = MDGridLayout(cols=2, rows=max(len(v) for v in self.settings.values()) - 1, size_hint=(1, 7.5), spacing=1) # -1 for help in 1 col bottom_bl = MDBoxLayout(spacing=2) self.info_label = MDLabel() - bottom_bl.add_widget(SizedMDFlatButton(text=f"Apply", on_press=lambda _: self.update_config(False))) # raised? + bottom_bl.add_widget(SizedMDButton(text=f"Apply", on_press=lambda _: self.update_config(False))) # raised? bottom_bl.add_widget(self.info_label) - bottom_bl.add_widget(SizedMDFlatButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True))) + bottom_bl.add_widget(SizedMDButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True))) self.add_widget(self.options_grid) self.add_widget(bottom_bl) self.build_ai_options(ais[0]) diff --git a/katrain/gui/badukpan.py b/katrain/gui/badukpan.py index 35d4458..d94d10d 100644 --- a/katrain/gui/badukpan.py +++ b/katrain/gui/badukpan.py @@ -5,6 +5,7 @@ import time from kivy.clock import Clock from kivy.graphics.context_instructions import Color from kivy.graphics.vertex_instructions import Ellipse, Line, Rectangle +from kivy.properties import ListProperty from kivy.uix.boxlayout import BoxLayout from kivy.uix.widget import Widget from kivymd.uix.boxlayout import MDBoxLayout @@ -13,7 +14,7 @@ from kivymd.uix.menu import MDDropdownMenu from katrain.core.utils import OUTPUT_DEBUG, evaluation_class, i18n, MODE_PLAY from katrain.core.game import Move -from katrain.gui.kivyutils import draw_circle, draw_text +from katrain.gui.kivyutils import draw_circle, draw_text, AnalysisDropdownMenu from katrain.core.utils import var_to_grid from kivy.core.window import Window @@ -31,7 +32,7 @@ from katrain.gui.style import ( BOARD_COLOR, STARPOINT_SIZE, STONE_SIZE, - VISITS_FRAC_SMALL, + VISITS_FRAC_SMALL, ENGINE_DOWN_COL, ) @@ -410,18 +411,21 @@ class BadukPanWidget(Widget): class AnalysisControls(MDFloatLayout): + ANALYSIS_ICONS = ["git","git","git","git" ] + ANALYSIS_OPTIONS = ['analysis:extra','analysis:equalize','analysis:sweep','analysis:aimove'] + def __init__(self, **kwargs): super().__init__(**kwargs) self.analysis_menu = None Clock.schedule_once(self.build_menu, 0) def build_menu(self, _dt): - menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)] - self.analysis_menu = MDDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=4) + menu_items = [{"icon": icon, "text": i18n._(text)} for text,icon in zip(self.ANALYSIS_ICONS,self.ANALYSIS_OPTIONS)] + self.analysis_menu = AnalysisDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=4) def open_analysis_menu(self): self.analysis_menu.open() class BadukPanControls(MDFloatLayout): - pass + engine_status_col = ListProperty(ENGINE_DOWN_COL) diff --git a/katrain/gui/kivyutils.py b/katrain/gui/kivyutils.py index fc0170a..8689616 100644 --- a/katrain/gui/kivyutils.py +++ b/katrain/gui/kivyutils.py @@ -22,6 +22,7 @@ from kivymd.uix.behaviors import RectangularRippleBehavior, CircularRippleBehavi from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.button import BasePressedButton, BaseFlatButton from kivymd.uix.floatlayout import MDFloatLayout +from kivymd.uix.menu import MDDropdownMenu from kivymd.uix.navigationdrawer import MDNavigationDrawer from kivy.core.text import Label as CoreLabel from katrain.core.utils import i18n, I18NTextInput, I18NLabel @@ -29,6 +30,7 @@ from katrain.core.utils import i18n, I18NTextInput, I18NLabel # # --- new mixins +from katrain.gui.style import WHITE class BackgroundColor(Widget): @@ -67,47 +69,30 @@ class LeftButtonBehavior(ButtonBehavior): # stops buttons etc activating on rig # -- resizeable buttons -class SizedMDBaseButton(BasePressedButton, BaseFlatButton, LeftButtonBehavior): # avoid baserectangular for sizing +class SizedMDButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedButton, BaseFlatButton, BackgroundColor, OutlineColor): # avoid baserectangular for sizing text = StringProperty("") + text_color = ListProperty(WHITE) halign = OptionProperty("center", options=["left", "center", "right", "justify", "auto"]) label = ObjectProperty(None) height = NumericProperty(33) +class SizedMDToggleButton(ToggleButtonBehavior, SizedMDButton): + inactive_outline_color = ListProperty([0.5, 0.5, 0.5, 0]) + active_outline_color = ListProperty([1, 1, 1, 0]) + inactive_background_color = ListProperty([0.5, 0.5, 0.5, 1]) + active_background_color = ListProperty([1, 1, 1, 1]) -class SizedMDFlatButton(RectangularRippleBehavior, SizedMDBaseButton): +class SizedMDRectangleButton(SizedMDButton): pass +class SizedMDRectangleToggleButton(SizedMDToggleButton): + pass -class SizedMDFlatToggleButton(SizedMDFlatButton, ToggleButtonBehavior): - inactive_color = ListProperty([0.5, 0.5, 0.5, 1]) - active_color = ListProperty([1, 1, 1, 1]) - - @property - def active(self): - return self.state == "down" - - - -class SizedMDFlatRectangleButton(SizedMDFlatButton, OutlineColor): - color = ListProperty([1, 1, 1, 1]) - - -class SizedMDFlatRectangleToggleButton(SizedMDFlatRectangleButton, ToggleButtonBehavior): - inactive_color = ListProperty([0.5, 0.5, 0.5, 1]) - - @property - def active(self): - return self.state == "down" - - -class AutoSizedMDFlatRectangleButton(SizedMDFlatRectangleButton): - hor_padding = NumericProperty(4) - - -class AutoSizedMDFlatRectangleToggleButton(SizedMDFlatRectangleToggleButton): - hor_padding = NumericProperty(4) - +class AutoSizedMDRectangleButton(SizedMDRectangleButton): + hor_padding = NumericProperty(6) +class AutoSizedMDRectangleToggleButton(SizedMDRectangleToggleButton): + hor_padding = NumericProperty(6) class TransparentIconButton(CircularRippleBehavior, Button): @@ -146,11 +131,22 @@ class CircleWithText(Widget): # -- new gui elements +class PlayerInfo(MDBoxLayout,BackgroundColor,OutlineColor): + captures = NumericProperty(0) + player = OptionProperty("Black", options=["Black", "White"]) + player_type= StringProperty('Player') + player_subtype = StringProperty('') + active = BooleanProperty(True) + +class AnalysisDropdownMenu(MDDropdownMenu): + pass + + class AnalysisToggle(MDBoxLayout): text = StringProperty('') active = BooleanProperty(False) -class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout): +class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout,BackgroundColor): __events__ = ["on_action"] icon = StringProperty("") text = StringProperty("") @@ -167,12 +163,15 @@ class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout): class CollapsablePanelHeader(MDBoxLayout): pass +class CollapsablePanelTab(AutoSizedMDRectangleToggleButton): + pass + class CollapsablePanel(MDBoxLayout): __events__ = ["on_option_state"] options = ListProperty([]) options_height = NumericProperty(25) - options_left_padding = NumericProperty(6) + options_spacing = NumericProperty(6) option_labels = ListProperty([]) option_default_active = ListProperty([]) option_colors = ListProperty([]) @@ -195,17 +194,17 @@ class CollapsablePanel(MDBoxLayout): option_colors=self.build_options, options_height=self.build_options, option_default_active=self.build_options, - options_left_padding=self.build_options, + options_spacing=self.build_options, ) self.bind(state=self.build, size_hint_y_open=self.build, height_open=self.build) self.build_options() def build_options(self, *args, **kwargs): - self.header = CollapsablePanelHeader(height=self.options_height, size_hint_y=None, padding=[self.options_left_padding, 0, 0, 0], spacing=3) + self.header = CollapsablePanelHeader(height=self.options_height, size_hint_y=None, spacing=self.options_spacing) self.option_buttons = [] option_labels = self.option_labels or [i18n._(f"tab:{opt}") for opt in self.options] for lbl, opt_col, active in zip(option_labels, self.option_colors, self.option_default_active): - button = AutoSizedMDFlatRectangleToggleButton(text=lbl, color=opt_col, height=self.options_height, on_press=self.trigger_select, state="down" if active else "normal") + button = CollapsablePanelTab(text=lbl, active_outline_color=opt_col, height=self.options_height, on_press=self.trigger_select, state="down" if active else "normal") self.option_buttons.append(button) self.open_close_button = TransparentIconButton( # << / >> collapse button icon=self.open_close_icon(), @@ -319,7 +318,7 @@ class ScaledLightLabel(LightLabel, ToolTipBehavior): num_lines = NumericProperty(1) -class ClickableLabel(LightLabel, LeftButtonBehavior): +class ClickableLabel(LeftButtonBehavior,I18NLabel): pass @@ -327,8 +326,9 @@ class LightHelpLabel(ScaledLightLabel): pass -class ScrollableLabel(ScrollView, BackgroundColor, OutlineColor): +class ScrollableLabel(ScrollView, BackgroundColor): __events__ = ["on_ref_press"] + outline_color = ListProperty([0, 0, 0, 0]) # mixin not working for some reason text = StringProperty("") markup = BooleanProperty(False) diff --git a/katrain/gui/style.py b/katrain/gui/style.py index c0c762b..68d2329 100644 --- a/katrain/gui/style.py +++ b/katrain/gui/style.py @@ -4,6 +4,7 @@ def to_hexcol(kivycol): # basic color definitions RED = [0.8, 0.1, 0.1, 1] +WHITE = [0.95,0.95,0.95,1] # eval dots EVAL_COLORS = [ diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo index 2cba6de..87cf6a0 100644 Binary files a/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/en/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po index 2b515a8..8f0bdf6 100644 --- a/katrain/i18n/locales/en/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/en/LC_MESSAGES/katrain.po @@ -1,4 +1,4 @@ -# KaTrain i18n file +# KaTrain localization file msgid "" msgstr "" "Language: English\n" @@ -8,20 +8,63 @@ msgstr "" #. This is the font used, files ONLY relative to 'katrain' directory msgid "Roboto" -msgstr "Roboto" +msgstr "fonts/NotoSans-Regular.ttf" -msgid "English" -msgstr "English" +#. main hamburger menu +msgid "menu:playersetup" +msgstr "Player Setup" -msgid "Dutch" -msgstr "Dutch" +msgid "menu:newgame" +msgstr "New Game" -msgid "Korean" -msgstr "Korean" +msgid "menu:save" +msgstr "Save Game" +msgid "menu:load" +msgstr "Load Game" + +msgid "menu:settings" +msgstr "General Settings" + +msgid "menu:lang" +msgstr "Language" + +#. buttons at the top - should all include a line break +msgid "analysis:nextmoves" +msgstr "" +"Next\n" +"Moves" + +msgid "analysis:dots" +msgstr "" +"Show\n" +"Dots" + +msgid "analysis:topmoves" +msgstr "" +"Top\n" +"Moves" + +msgid "analysis:policy" +msgstr "" +"Policy\n" +"Moves" + +msgid "analysis:territory" +msgstr "" +"Expected\n" +"Territory" + +#. right panel buttons and below board msgid "pass-button-text" msgstr "Pass" +msgid "ai-ponder" +msgstr "" +"This simply indicates the Engine status, going from green (idle) to orange " +"(processing queries). It turns red when the engine has crashed or fails to " +"start." + #. tabs and labels on the right panel msgid "tab:score" msgstr "Score" @@ -47,7 +90,7 @@ msgstr "Move Stats" msgid "closedlabel:info¬es" msgstr "Move Info & Notes" -#. on the board after pass +#. on the board after passing once/twice msgid "board-pass" msgstr "pass" diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo index 0a44be4..119d042 100644 Binary files a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po index 325cd4b..de86a16 100644 --- a/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/ko/LC_MESSAGES/katrain.po @@ -52,7 +52,9 @@ msgid "board-pass" msgstr "패스" msgid "board-game-end" -msgstr "게임\n끝났다" +msgstr "" +"게임\n" +"끝났다" #. Select mode msgid "btn:Play" @@ -150,3 +152,64 @@ msgid "Engine died unexpectedly" msgstr "" "Engine died unexpectedly without sending output, possibly due to out of " "memory: {e}" + +#. TODO +msgid "analysis:territory" +msgstr "" +"Expected\n" +"Territory" + +#. TODO +msgid "analysis:topmoves" +msgstr "" +"Top\n" +"Moves" + +#. TODO +msgid "analysis:dots" +msgstr "" +"Show\n" +"Dots" + +#. TODO +msgid "analysis:nextmoves" +msgstr "" +"Next\n" +"Moves" + +#. TODO +msgid "analysis:policy" +msgstr "" +"Policy\n" +"Moves" + +#. TODO +msgid "ai-ponder" +msgstr "" +"This simply indicates the Engine status, going from green (idle) to orange " +"(processing queries). It turns red when the engine has crashed or fails to " +"start." + +#. TODO +msgid "menu:newgame" +msgstr "New Game" + +#. TODO +msgid "menu:load" +msgstr "Load Game" + +#. TODO +msgid "menu:save" +msgstr "Save Game" + +#. TODO +msgid "menu:lang" +msgstr "Language" + +#. TODO +msgid "menu:settings" +msgstr "General Settings" + +#. TODO +msgid "menu:playersetup" +msgstr "Player Setup" diff --git a/katrain/i18n/locales/nl/LC_MESSAGES/katrain.mo b/katrain/i18n/locales/nl/LC_MESSAGES/katrain.mo index 8bf5189..3b48b02 100644 Binary files a/katrain/i18n/locales/nl/LC_MESSAGES/katrain.mo and b/katrain/i18n/locales/nl/LC_MESSAGES/katrain.mo differ diff --git a/katrain/i18n/locales/nl/LC_MESSAGES/katrain.po b/katrain/i18n/locales/nl/LC_MESSAGES/katrain.po index 6b60e71..df989ed 100644 --- a/katrain/i18n/locales/nl/LC_MESSAGES/katrain.po +++ b/katrain/i18n/locales/nl/LC_MESSAGES/katrain.po @@ -183,3 +183,64 @@ msgstr "Points Gained" #. TODO msgid "SGF Notes Hint" msgstr "Your SGF notes for this position here." + +#. TODO +msgid "analysis:territory" +msgstr "" +"Expected\n" +"Territory" + +#. TODO +msgid "analysis:topmoves" +msgstr "" +"Top\n" +"Moves" + +#. TODO +msgid "analysis:dots" +msgstr "" +"Show\n" +"Dots" + +#. TODO +msgid "analysis:nextmoves" +msgstr "" +"Next\n" +"Moves" + +#. TODO +msgid "analysis:policy" +msgstr "" +"Policy\n" +"Moves" + +#. TODO +msgid "ai-ponder" +msgstr "" +"This simply indicates the Engine status, going from green (idle) to orange " +"(processing queries). It turns red when the engine has crashed or fails to " +"start." + +#. TODO +msgid "menu:newgame" +msgstr "New Game" + +#. TODO +msgid "menu:load" +msgstr "Load Game" + +#. TODO +msgid "menu:save" +msgstr "Save Game" + +#. TODO +msgid "menu:lang" +msgstr "Language" + +#. TODO +msgid "menu:settings" +msgstr "General Settings" + +#. TODO +msgid "menu:playersetup" +msgstr "Player Setup"