From 7e655aa744e3b7599388dd36f3aeb3b9f97e7bfe Mon Sep 17 00:00:00 2001 From: Sander Land Date: Tue, 26 May 2020 21:04:18 +0200 Subject: [PATCH] many style improvements --- .github/workflows/release.yaml | 3 + .github/workflows/test.yaml | 3 + i18n.py | 9 + katrain/__main__.py | 17 +- katrain/core/utils.py | 2 +- katrain/gui.kv | 278 +++++++++--------- katrain/gui/ai_settings.py | 6 +- katrain/gui/badukpan.py | 14 +- katrain/gui/kivyutils.py | 76 ++--- katrain/gui/style.py | 1 + .../i18n/locales/en/LC_MESSAGES/katrain.mo | Bin 2847 -> 3427 bytes .../i18n/locales/en/LC_MESSAGES/katrain.po | 61 +++- .../i18n/locales/ko/LC_MESSAGES/katrain.mo | Bin 2945 -> 3596 bytes .../i18n/locales/ko/LC_MESSAGES/katrain.po | 65 +++- .../i18n/locales/nl/LC_MESSAGES/katrain.mo | Bin 2855 -> 3505 bytes .../i18n/locales/nl/LC_MESSAGES/katrain.po | 61 ++++ 16 files changed, 402 insertions(+), 194 deletions(-) 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 2cba6dea14d5220de6370dc8a0b523430cfd867d..87cf6a0917fd212b7b761c002dda5bfb2c2f429b 100644 GIT binary patch delta 1428 zcmYk)Pi$009Ki8uyRNufkUvT&DKZzNO<>`GQ5r&G5V1*F3ELBbGVadqzU1wj$D7%< z8<8GNjEM(h7GjJhhNE(9;)!VBC|pRCi;=_-y%0QM;(-vqzkN?jv%8=9&CHwM@BOCV zY`?#A_1@Of6~*5nzSDfKk4dD|*@<(0(bB^{0rs0 ze^AaZKa&?Sg%Z!=7V@hj4CKH%Qjt1`lDLZ-u#ZyEC6q$06!A5bL^lg>qda#Pr4#py z`9~;)JSpZUc?&6E7j7oMI>?}kucK@{iIVsolmso5!jd8$pzQw$WBd%I6OU1@XcPT! z;9h(iKfoEhg)iYFl=HXovnnl{X0R6z;{h}{ho7T#=5{gvEAAt%Qq>f`hTHHoN@v=* z6EEV+_yw-u5BM#<%3J)1zvI_Y777M({~_egH_A#$DS<0AgF zh%cjb;7gQquAy}3dz9yHqMUQ9h<`yo>fYq}eBl9++}YnK3Ci4qTt$^1IcN&yzjzPI zfv=$KJBnPZI);*XzK9o5_MO={{As*4d@?>Y+&%HzaH5pHXQKV7OIkKlCNc5AM}Ds5 zf?tmkyApbC$v!oex;SbM*0%(kWl?b1(^D=TJv7Wp{rR3v`g5^KIw~JI)5=GQUGA8k z&4V;H1Dkmp`e{Dl%~G+%WQdZEU;DE(Jx2LEhPr%YtyO+7cChaBe}!waWTM!-A6wOS zN$>~iF1UtC{QlFn(~nJ73!%N1ZK#f~E_NfYebh_ifsT?^)HK0*9lBN@PdZUzwGSrr z{XX4sin*HqkRtE4H&bIPEgt$m*Fib4}~L?7PsnS!DfeP0t4%`dQ+2W?Oo> z%Y$;b%@6OMHC{I}`t;~p{5#Lw_JHcZlO-|D88A2(@})TXUQtEG(&v7p$^p$Cek6q&2myx< ziqloZIw&}aZm9}_2qF|j!KJi|6>$(j5W%5HvHl-(pyA&9&U4PW=iKuqUw1ypG*-K# zcZ|6>Ei+bT9+=_=$2b*-`71Tc0F=Y+2 zTQu6}m`82&2(|D_mp`IT@(uN3Yc3}#Lz3KwdeK4DItQ^GM^GCbb$J3c|16g90(P;# zEz?kGzay80Io?TZLzV6{j$;7_aRK}B6KcbC)CoN%@5MbhgvW3gYpBXRbNz2|KlwK{ zdTH!tl^#5VtYzb<3QW3O!W_ARvpA2Bv4>;6##cy})j2N3u{l(}>GEyVPjU~r>A%jb(_ zKU*mJh3rh(pS|qotA3$$O#`K3Wjc5mS&bdPbk#ps4(ib>!I)QVreeE7-v7sgT>Mnr a&1}}W^+3O`J z9MK>(Mi9?HM5{rf7+Mh;6f2>EMHE4OFj)0L?MsE;#y?NKso&r2VtVZDXMQt#zxmB? zZ)VH<*5=PcJqwD@9elU)UGI`esrgGb9c1_t@wNCCUWy;*@oDTOK8rWuFF1t%;?+3R zldW&VD~WH$tFVZyH`N2#Ks|~D76Oz64IIEZ9Kl7r0zbgZa1Dp?OdkJ;vcaz?1^DWO!A7tTZ%4^{7Y?z%dXRxs^jK#?sSqW>3`)WlN?~uK6!1P?j-Q|ub_S)8pYr%m zl#P0+QXEA2-SsFP8O`VK!~ynK_vQ-^p`855Jg#Fu@$)DZzk;&y5=!C~l)_f?_%zD% zU*ch0M>)tnydQaW52GCPFizmp*yI`YErWyjJ&xjbcDWG`qHGv)lNL5`2fm88;u;n) zMd`#2s*?G;aTkVo9lnlIz=z1CzTqYv`=O8iOXA;|*pB@iX9{n_6+Dig;v*dE4IHMA zlHerD$=8reeZfsSw~n&@8%nGHLOEbJ?PI9=az{`K-X{H*))u*K!TXWJs3%Yo`FZS6 z5 zd;TqP6qb!uUg!nW&UeLfl(@|(G*d|}I$|!Gile|UO>aJu7;F6`vKLQ9apy-Z+f(0L zGhw|Lcwt3lqsS{~qtG-eUd?1d9C*{lI+N7nY{Gd*@+Bq{KdiXb^F3#~2hzo(>2otW zU3xh^y14pT@44>gWYu@t`L#Hh)_z#_OI~7}PO3)l2`heRv`f6C?sn-)L>_&}Mm1fr z#)Nv*F9&9)P9hyyDl~dDwo%DAC(k`qH`X_9=We|>(MjEgPFqvfjVeEs>t}l`E{>i)IR#F$E2?Z zOd}hNcY3QQI?bJ+ui5mN361pvneX&hGPiE%A0N(otJ1ks?RQV;jn@|1?<}eR0K>g7 A9{>OV delta 817 zcmYMxO-Phc6vpv0Uz(0%jcB7WOMDnF=2B9u*mUqQNv6b6S@rfvp7 ziy|%`|6wU{EMQiT^;m@|JcaG3{T{5uK0Jv}i~AWHFD~pQ zma~yZCHROD{Enw_9V_q;mf#`QU?5nG>re#}sD_hRjn_~YyXE$WP<66cVHvYY7AN@O z1**^-D)A>5ucB_UgKF%+#bL$}CXS;TZA9g{f@PRO6>4>HC+huf?89D+Qs35CXtcjk zqw#UQ4veC1n&#^U_G2S1<5}EB6$~<8-7ta;coCD>j?I`wP3E)veFd9{4>426;sROJ zz;#sTU8o5>KqVf<^Eiu7@GE}6tGxULw@~NjxGp`}GU~7T=3GTh_9tpme=&ysu(cf> zIKy1DaSk=2q>Edet;p2vHZmmZLUPzW7Z0G$4`D7<+EiE!jQDc7&~TxxWX&Jy=y~)w zUASDf>5uO&OzgdWmhi@2dD*=8{O!ZL1L^Yg;C1M;x{OT-9ahjULNnG z9MnmbVh_rF{U{w7$n&pYH|ML7eBuJilYfxMb$p0;38msyl!LFMY`l(A*k&GYp{)NA zE#5_WkWt=`yt<1h>n%>>Wn5&9`h~%pxPt@u45ysJNt6R?T%?6__$)T@dAyB9{0pU1 zXQ)c@FX12>d>mKt5&RNas=i0**iXmkzZ9@b;tcNLJa$v&IxgXN_yUi0759-PYK4Bv zlYEZS+BGiHxeb*0A5aeZ8Tky zHI(OzDDQF<`Owu{$iKS8MfR!S3G^uYeS}iTGV*z-PqFm?a*!m}P!`_o-rPR2-u8YF z4kb1&8>fOeh!%Y4i)EYogD5uhY0b`=L#f0@VQJxDNot%6Q|k_=Y|^@^>Due(Y9_81 zqad!RY-EFSHi}K764Xod+pad7H6uV*FLNz(Si=+ za##vd<8@j!dMvJlvC%#a(z+ki70XR}*4dh_IAdZx5SAlzR;N~5M>$3hB+izM_p%tyo11L&>N|ngB^UTAlh*0kAdEQO%Be0LR?}76D2z%A zC+S?_jaKWXS{=)SvH8T5Qd2I>{NJ}3n`D#Cj|;DjOi)`rs2DXtr}VgVXwo#Y!BneD adb-u7X*!gp$4zWp5J|q(spfX!-TwfPg8t|L delta 746 zcmYMyPbh((s~q1Kh;<62%m0#5q^sfFr2uGgyl$tizS^dRj8&f$X7|g=5qW&d`t7 z7{YtB@dK;y2b<8UEXOUV3EEK)9LGlNM=fl^tS_MESw~yaBAX1Vnb<{5lttb6+{AaN zmAs-J?9;?P+TbIOpdK`ax=%0GU;;JKkcr1o@1MeXoWmgb<$-~=_8s*BH|33D0JYLt zF2k6@7+zo-zMv+w=&x32V<&cD9Fy3GYp9*MH1kF5A^yg63xgQDG~fX0h7(-01Jg(j zS;7un#bwN54kMIVz$;`*HaI=akuB7C+r;~*ujCN<$|)D^M8Qj4yhbT9p)I^M3y-LO uk~h?izEC%=;3=9U9%M@VCJv+C*XGM-tenen+>7~S)q&e7*@MowfASAOdqeU7 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"