many style improvements

This commit is contained in:
Sander Land committed 2020-05-26 21:04:18 +02:00
1 parent adad2d562f
commit 7e655aa744
16 files changed
+402 -194

No files matched your search

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