fc
This commit is contained in:
1 parent
b062d78dba
commit
01f0663ac1
22 files changed
+584
-166
No files matched your search
Generated
+9
-9
@@ -112,17 +112,17 @@
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c",
|
||||
"sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"
|
||||
"sha256:558bb897a2232f5e4f8e2399089e35aecb746e1f9191b6584a151647e89267be",
|
||||
"sha256:7818f596b1e87be009031c7653d01acc46ed422e6656b394b0f765ce66ed4982"
|
||||
],
|
||||
"version": "==8.2.0"
|
||||
"version": "==8.3.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
|
||||
"sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
|
||||
"sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8",
|
||||
"sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"
|
||||
],
|
||||
"version": "==20.3"
|
||||
"version": "==20.4"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
@@ -155,10 +155,10 @@
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
|
||||
"sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
|
||||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
|
||||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
|
||||
],
|
||||
"version": "==1.14.0"
|
||||
"version": "==1.15.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
|
||||
@@ -102,10 +102,10 @@ Keyboard shortcuts are shown with **[key]**.
|
||||
* **[w]**: All dots: Show all evaluation dots instead of the last few.
|
||||
* You can configure how many are shown with this setting off, and whether they are shown for AIs under 'Play/Configure Teacher'.
|
||||
* **[e]**: Top moves: Show the next moves KataGo considered, colored by their expected point loss. Small dots indicate high uncertainty. Hover over any of them to see the principal variation.
|
||||
* **[r]**: Show owner: Show expected ownership of each intersection.
|
||||
* **[t]**: NN Policy: Show KataGo's policy network evaluation, i.e. where it thinks the best next move is purely from the position, and in the absence of any 'reading'.
|
||||
* **[r]**: NN Policy: Show KataGo's policy network evaluation, i.e. where it thinks the best next move is purely from the position, and in the absence of any 'reading'.
|
||||
* **[t]**: Show owner: Show expected ownership of each intersection.
|
||||
|
||||
* The analysis buttons are used for:
|
||||
* The analysis options are used for deeper evaluation of the position:
|
||||
* **[a]**: Extra: Re-evaluate the position using more visits, usually resulting in a more accurate evaluation.
|
||||
* **[s]**: Equalize: Re-evaluate all currently shown next moves with the same visits as the current top move. Useful to increase confidence in the suggestions with high uncertainty.
|
||||
* **[d]**: Sweep: Evaluate all possible next moves. This can take a bit of time even though 'fast_visits' is used, but the result is nothing if not colourful.
|
||||
@@ -114,7 +114,7 @@ Keyboard shortcuts are shown with **[key]**.
|
||||
|
||||
In addition to shortcuts mentioned above, there are:
|
||||
|
||||
* **[Tab]**: to switch between analysis and play modes. (NB. keyboard shortcuts function regardless)
|
||||
* **[Tab]**: to switch between analysis and play modes.
|
||||
* **[~]** or **[`]** or **[m]**: Hide side panel UI and only show the board.
|
||||
* **[enter]**: AI Move
|
||||
* **[p]**: Pass
|
||||
@@ -130,7 +130,7 @@ In addition to shortcuts mentioned above, there are:
|
||||
* **[Ctrl-l]**: Load SGF from file and do a normal analysis.
|
||||
* **[Ctrl-s]**: Save SGF with automated review to file.
|
||||
* **[Ctrl-n]**: Load SGF from clipboard
|
||||
|
||||
* **[F5]**: Open settings
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
import kivy
|
||||
from kivy.app import App
|
||||
from kivy.core.text import Label as CoreLabel
|
||||
from kivy.lang import Builder
|
||||
from kivy.properties import (
|
||||
BooleanProperty,
|
||||
ListProperty,
|
||||
NumericProperty,
|
||||
ObjectProperty,
|
||||
OptionProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from kivy.uix.behaviors import ButtonBehavior, ToggleButtonBehavior
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.checkbox import CheckBox
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.scrollview import ScrollView
|
||||
from kivy.uix.spinner import Spinner
|
||||
from kivy.uix.widget import Widget
|
||||
from kivymd.app import MDApp
|
||||
from kivymd.uix.behaviors import CircularRippleBehavior, RectangularRippleBehavior
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.button import BaseFlatButton, BasePressedButton
|
||||
from kivymd.uix.navigationdrawer import MDNavigationDrawer
|
||||
|
||||
WHITE = [1, 1, 1, 1]
|
||||
|
||||
|
||||
class TestBox(GridLayout):
|
||||
pass
|
||||
|
||||
|
||||
class BackgroundMixin(Widget):
|
||||
background_color = ListProperty([0, 0, 0, 0])
|
||||
background_radius = NumericProperty(0)
|
||||
outline_color = ListProperty([0, 0, 0, 0])
|
||||
outline_width = NumericProperty(1)
|
||||
background_radius = NumericProperty(0)
|
||||
|
||||
|
||||
class LeftButtonBehavior(ButtonBehavior): # stops buttons etc activating on right click
|
||||
def __init__(self, **kwargs):
|
||||
self.register_event_type("on_left_release")
|
||||
self.register_event_type("on_left_press")
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
return super().on_touch_down(touch)
|
||||
|
||||
def on_release(self):
|
||||
if not self.last_touch or self.last_touch.button == "left":
|
||||
self.dispatch("on_left_release")
|
||||
return super().on_release()
|
||||
|
||||
def on_press(self):
|
||||
if not self.last_touch or self.last_touch.button == "left":
|
||||
self.dispatch("on_left_press")
|
||||
return super().on_press()
|
||||
|
||||
def on_left_release(self):
|
||||
pass
|
||||
|
||||
def on_left_press(self):
|
||||
pass
|
||||
|
||||
|
||||
# -- resizeable buttons
|
||||
class SizedButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedButton, BaseFlatButton, BackgroundMixin): # avoid baserectangular for sizing
|
||||
text = StringProperty("")
|
||||
text_color = ListProperty(WHITE)
|
||||
text_size = ListProperty([100, 100])
|
||||
halign = OptionProperty("center", options=["left", "center", "right", "justify", "auto"])
|
||||
label = ObjectProperty(None)
|
||||
padding_x = NumericProperty(6)
|
||||
padding_y = NumericProperty(0)
|
||||
fsz = NumericProperty(None)
|
||||
|
||||
|
||||
class AutoSizedButton(SizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class ToggleButtonMixin(ToggleButtonBehavior):
|
||||
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 SizedRectangleButton(SizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class SizedRectangleToggleButton(ToggleButtonMixin, SizedRectangleButton):
|
||||
pass
|
||||
|
||||
|
||||
class AutoSizedRectangleButton(AutoSizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class AutoSizedRectangleToggleButton(ToggleButtonMixin, AutoSizedRectangleButton):
|
||||
pass
|
||||
|
||||
|
||||
class TransparentIconButton(CircularRippleBehavior, Button):
|
||||
icon_size = ListProperty([25, 25])
|
||||
icon = StringProperty("")
|
||||
|
||||
|
||||
KV = """
|
||||
#:set LIGHTGREY [0.7,0.7,0.7,1]
|
||||
#:set WHITE [1,1,1,1]
|
||||
|
||||
#:set BUTTON_INACTIVE_COLOR LIGHTGREY
|
||||
#:set BACKGROUND_COLOR [16/255,18/255,32/255,1]
|
||||
#:set BOX_BACKGROUND_COLOR [46/255,65/255,88/255,1]
|
||||
#:set TEXT_COLOR WHITE
|
||||
<Label>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: [1,0,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
|
||||
# mixins
|
||||
<BackgroundMixin>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: root.background_color
|
||||
RoundedRectangle:
|
||||
size: self.size
|
||||
pos: self.pos
|
||||
radius: [root.background_radius, ]
|
||||
Color:
|
||||
rgba: root.outline_color
|
||||
Line:
|
||||
rounded_rectangle: (*self.pos,self.width,self.height,root.background_radius)
|
||||
width: root.outline_width
|
||||
|
||||
<SizedButton>:
|
||||
ripple_duration_in_slow: 0.6
|
||||
text_color: WHITE
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
label: label
|
||||
text_size: root.size
|
||||
onlytext: ''
|
||||
on_press: print('size: {}\\ntexture_size: {}\\ntext_size: {} - font {} - {} - {} ?\\npos: {} - halign {}'.format(label.size,label.texture_size,label.text_size,label.font_size,root.font_size,0.6 * self.height / len(self.label.text.split('\\n')),label.pos,label.halign),self.label.text.split('\\n'))
|
||||
Label:
|
||||
id: label
|
||||
padding: [root.padding_x,root.padding_y]
|
||||
color: root.text_color
|
||||
font_size: 0.6 * self.height / len(self.text.split('\\n')) if root.fsz is None else root.fsz
|
||||
on_font_size: print(args,self.font_size,self.text)
|
||||
halign: root.halign
|
||||
text: 'size: {}\\ntexture_size: {}\\ntext_size: {}\\npos: {}halign {}\\n{}'.format(self.size,self.texture_size,self.text_size,self.pos,self.halign,root.text) if not root.onlytext else root.onlytext
|
||||
|
||||
<AutoSizedButton>:
|
||||
width: root.label.texture_size[0]
|
||||
|
||||
<SizedToggleButton>
|
||||
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
|
||||
|
||||
<SizedRectangleButton>:
|
||||
outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
<SizedRectangleToggleButton>:
|
||||
inactive_outline_color: BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
<AutoSizedRectangleButton>: # only wants height
|
||||
outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
|
||||
<AutoSizedRoundedRectangleButton@AutoSizedRectangleButton>:
|
||||
background_radius: self.height/3.5
|
||||
halign: 'left'
|
||||
|
||||
<PassBtn@AutoSizedRoundedRectangleButton>:
|
||||
id: pass_btn
|
||||
onlytext: 'Pass'
|
||||
background_radius: 10
|
||||
height: 50
|
||||
|
||||
<BGBoxLayout@BoxLayout+BackgroundMixin>
|
||||
background_color: BACKGROUND_COLOR
|
||||
padding: 100
|
||||
|
||||
<TransparentIconButton>:
|
||||
background_normal: ''
|
||||
background_color: (0,0,0,0)
|
||||
image: image
|
||||
Image:
|
||||
id: image
|
||||
size: root.icon_size
|
||||
pos: [root.pos[i] + (root.size[i] - root.icon_size[i])/2 for i in [0,1]]
|
||||
source: root.icon
|
||||
mipmap: True
|
||||
|
||||
|
||||
<TestBox>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: [0,1,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
cols: 2
|
||||
rows: 3
|
||||
BGBoxLayout:
|
||||
SizedButton:
|
||||
text: 'SizedButton'
|
||||
height: 125
|
||||
width: 300
|
||||
BGBoxLayout:
|
||||
AutoSizedRectangleButton:
|
||||
text: 'AutoSizedRectangleButton'
|
||||
size_hint_y: None
|
||||
height: 150
|
||||
BGBoxLayout:
|
||||
SizedRectangleButton:
|
||||
text: 'SizedRectangleButton'
|
||||
height: 125
|
||||
width: 300
|
||||
halign: 'left'
|
||||
background_radius: 25
|
||||
BGBoxLayout:
|
||||
AutoSizedRoundedRectangleButton:
|
||||
text: 'AutoSizedRectangleButton'
|
||||
halign: 'left'
|
||||
size_hint_y: None
|
||||
height: 150
|
||||
BGBoxLayout:
|
||||
PassBtn:
|
||||
"""
|
||||
|
||||
|
||||
Builder.load_string(KV)
|
||||
|
||||
|
||||
class MyApp(MDApp):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def build(self):
|
||||
layout = TestBox()
|
||||
return layout
|
||||
|
||||
|
||||
MyApp().run()
|
||||
File renamed without changes.
@@ -0,0 +1,64 @@
|
||||
import kivy
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.label import Label
|
||||
|
||||
|
||||
class TestBox(GridLayout):
|
||||
pass
|
||||
|
||||
|
||||
KV = """
|
||||
<Label>:
|
||||
valign: 'top'
|
||||
halign: 'right'
|
||||
xtext: ''
|
||||
text: 'size: {}\\ntexture_size: {}\\ntext_size: {}\\npos: {}\\n{}'.format(self.size,self.texture_size,self.text_size,self.pos,root.xtext)
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: [1,0,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
|
||||
|
||||
|
||||
<TestBox>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: [0,1,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
cols: 2
|
||||
rows: 2
|
||||
Label:
|
||||
xtext: 'size=texturesize'
|
||||
size: self.texture_size
|
||||
Label:
|
||||
xtext: 'texturesize=size'
|
||||
texture_size: self.size
|
||||
Label:
|
||||
xtext: 'textsize=size'
|
||||
text_size: self.size
|
||||
Label:
|
||||
xtext: 'texturesize=textsize=size'
|
||||
texture_size: self.size
|
||||
text_size: self.size
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
Builder.load_string(KV)
|
||||
|
||||
|
||||
class MyApp(App):
|
||||
def build(self):
|
||||
layout = TestBox()
|
||||
return layout
|
||||
|
||||
|
||||
MyApp().run()
|
||||
@@ -0,0 +1,9 @@
|
||||
from datetime import datetime
|
||||
|
||||
import yappi
|
||||
|
||||
from katrain.__main__ import run_app
|
||||
|
||||
yappi.start()
|
||||
run_app()
|
||||
yappi.get_func_stats().save("callgrind.out." + datetime.now().isoformat(), "CALLGRIND")
|
||||
File renamed without changes.
+15
-7
@@ -204,6 +204,10 @@ class KaTrainGui(Screen):
|
||||
ai_move(self.game, mode, settings)
|
||||
|
||||
def _do_undo(self, n_times=1):
|
||||
if n_times == "smart":
|
||||
n_times = 1
|
||||
if self.play_analyze_mode == "play" and self.game.last_player.ai and self.game.next_player.human:
|
||||
n_times = 2
|
||||
self.board_gui.animating_pv = None
|
||||
self.game.undo(n_times)
|
||||
|
||||
@@ -299,15 +303,14 @@ class KaTrainGui(Screen):
|
||||
self("undo")
|
||||
return super().on_touch_up(touch)
|
||||
|
||||
def _on_keyboard_down(self, _keyboard, keycode, _text, modifiers):
|
||||
if isinstance(App.get_running_app().root_window.children[0], Popup) or self.controls.note.focus:
|
||||
return # if in new game or load, don't allow keyboard shortcuts
|
||||
|
||||
shortcuts = {
|
||||
@property
|
||||
def shortcuts(self):
|
||||
return {
|
||||
"q": self.analysis_controls.show_children,
|
||||
"w": self.analysis_controls.eval,
|
||||
"e": self.analysis_controls.hints,
|
||||
"r": self.analysis_controls.ownership,
|
||||
"t": self.analysis_controls.policy,
|
||||
"t": self.analysis_controls.ownership,
|
||||
"r": self.analysis_controls.policy,
|
||||
"enter": ("ai-move",),
|
||||
"a": ("analyze-extra", "extra"),
|
||||
"s": ("analyze-extra", "equalize"),
|
||||
@@ -316,6 +319,11 @@ class KaTrainGui(Screen):
|
||||
"right": ("switch-branch", 1),
|
||||
"left": ("switch-branch", -1),
|
||||
}
|
||||
|
||||
def _on_keyboard_down(self, _keyboard, keycode, _text, modifiers):
|
||||
if isinstance(App.get_running_app().root_window.children[0], Popup) or self.controls.note.focus:
|
||||
return # if in new game or load, don't allow keyboard shortcuts
|
||||
shortcuts = self.shortcuts
|
||||
if keycode[1] in shortcuts.keys():
|
||||
shortcut = shortcuts[keycode[1]]
|
||||
if isinstance(shortcut, Widget):
|
||||
|
||||
+19
-15
@@ -5,7 +5,7 @@ import threading
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Union
|
||||
|
||||
from katrain.core.utils import var_to_grid, OUTPUT_INFO, OUTPUT_DEBUG
|
||||
from katrain.core.utils import var_to_grid, OUTPUT_INFO, OUTPUT_DEBUG, i18n
|
||||
from katrain.core.engine import KataGoEngine
|
||||
from katrain.core.game_node import GameNode
|
||||
from katrain.core.sgf_parser import SGF, Move
|
||||
@@ -291,32 +291,36 @@ class Game:
|
||||
def analyze_extra(self, mode):
|
||||
stones = {s.coords for s in self.stones}
|
||||
cn = self.current_node
|
||||
if not cn.analysis_ready:
|
||||
self.katrain.controls.set_status("Wait for initial analysis to complete before doing a board-sweep or refinement", self.current_node)
|
||||
return
|
||||
|
||||
engine = self.engines[cn.next_player]
|
||||
if mode == "extra":
|
||||
visits = cn.analysis["root"]["visits"] + engine.config["max_visits"]
|
||||
visits = cn.analysis_visits_requested + engine.config["max_visits"]
|
||||
self.katrain.controls.set_status(f"Performing additional analysis to {visits} visits")
|
||||
cn.analyze(engine, visits=visits, priority=-1_000, time_limit=False)
|
||||
return
|
||||
elif mode == "sweep":
|
||||
board_size_x, board_size_y = self.board_size
|
||||
policy_grid = var_to_grid(self.current_node.policy, size=(board_size_x, board_size_y)) if self.current_node.policy else None
|
||||
analyze_moves = sorted(
|
||||
[
|
||||
Move(coords=(x, y), player=cn.next_player)
|
||||
for x in range(board_size_x)
|
||||
for y in range(board_size_y)
|
||||
if (policy_grid is None and (x, y) not in stones) or policy_grid[y][x] >= 0
|
||||
],
|
||||
key=lambda mv: -policy_grid[mv.coords[1]][mv.coords[0]],
|
||||
)
|
||||
if cn.analysis_ready:
|
||||
policy_grid = var_to_grid(self.current_node.policy, size=(board_size_x, board_size_y)) if self.current_node.policy else None
|
||||
analyze_moves = sorted(
|
||||
[
|
||||
Move(coords=(x, y), player=cn.next_player)
|
||||
for x in range(board_size_x)
|
||||
for y in range(board_size_y)
|
||||
if (policy_grid is None and (x, y) not in stones) or policy_grid[y][x] >= 0
|
||||
],
|
||||
key=lambda mv: -policy_grid[mv.coords[1]][mv.coords[0]],
|
||||
)
|
||||
else:
|
||||
analyze_moves = [Move(coords=(x, y), player=cn.next_player) for x in range(board_size_x) for y in range(board_size_y) if (x, y) not in stones]
|
||||
visits = engine.config["fast_visits"]
|
||||
self.katrain.controls.set_status(f"Refining analysis of entire board to {visits} visits")
|
||||
priority = -1_000_000_000
|
||||
else: # mode=='equalize':
|
||||
if not cn.analysis_ready:
|
||||
self.katrain.controls.set_status(i18n._("wait-before-equalize"), self.current_node)
|
||||
return
|
||||
|
||||
analyze_moves = [Move.from_gtp(gtp, player=cn.next_player) for gtp, _ in cn.analysis["moves"].items()]
|
||||
visits = max(d["visits"] for d in cn.analysis["moves"].values())
|
||||
self.katrain.controls.set_status(f"Equalizing analysis of candidate moves to {visits} visits")
|
||||
|
||||
@@ -20,6 +20,7 @@ class GameNode(SGFNode):
|
||||
self.note = ""
|
||||
self.move_number = 0
|
||||
self.time_used = 0
|
||||
self.analysis_visits_requested = 0
|
||||
self.undo_threshold = random.random() # for fractional undos, store the random threshold in the move itself for consistency
|
||||
self._favourite_child = None
|
||||
|
||||
@@ -62,6 +63,8 @@ class GameNode(SGFNode):
|
||||
|
||||
# various analysis functions
|
||||
def analyze(self, engine, priority=0, visits=None, time_limit=True, refine_move=None, analyze_fast=False):
|
||||
if visits and not refine_move:
|
||||
self.analysis_visits_requested = max(self.analysis_visits_requested, engine.config["max_visits"])
|
||||
engine.request_analysis(
|
||||
self, lambda result: self.set_analysis(result, refine_move), priority=priority, visits=visits, analyze_fast=analyze_fast, time_limit=time_limit, next_move=refine_move
|
||||
)
|
||||
|
||||
+105
-62
@@ -32,6 +32,11 @@
|
||||
|
||||
#:set NOTES_FONT_SIZE dp(18)
|
||||
|
||||
#<DefaultLabel@Label>:
|
||||
# font_name: 'Roboto'
|
||||
#<Label>:
|
||||
# font_name: i18n._('LANG_FONT')
|
||||
|
||||
<I18NLabel>:
|
||||
font_name: i18n._('LANG_FONT')
|
||||
canvas.before:
|
||||
@@ -45,16 +50,7 @@
|
||||
font_name: i18n._('LANG_FONT')
|
||||
|
||||
# mixins
|
||||
<OutlineColor>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: root.outline_color
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
rounded_rectangle: (*self.pos,*self.size,root.background_radius,root.background_radius,root.background_radius,root.background_radius,self.height)
|
||||
width: root.outline_width
|
||||
|
||||
<BackgroundColor>:
|
||||
<BackgroundMixin>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: root.background_color
|
||||
@@ -62,6 +58,11 @@
|
||||
size: self.size
|
||||
pos: self.pos
|
||||
radius: [root.background_radius, ]
|
||||
Color:
|
||||
rgba: root.outline_color
|
||||
Line:
|
||||
rounded_rectangle: (*self.pos,self.width,self.height,root.background_radius)
|
||||
width: root.outline_width or 1
|
||||
|
||||
|
||||
<ToolTipLabel>: # TODO
|
||||
@@ -84,45 +85,55 @@
|
||||
|
||||
# new widgets
|
||||
|
||||
<SizedMDButton>:
|
||||
<SizedButton>:
|
||||
ripple_duration_in_slow: 0.6
|
||||
text_color: WHITE
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
label: label
|
||||
text_size: root.size
|
||||
I18NLabel:
|
||||
id: label
|
||||
text: root.text
|
||||
size: self.texture_size
|
||||
size_hint_x: None
|
||||
padding: [root.padding_x,root.padding_y]
|
||||
color: root.text_color
|
||||
font_size: root.font_size
|
||||
font_size: 0.6 * self.height / len(self.text.split('\\n')) if root._font_size is None else root._font_size
|
||||
halign: root.halign
|
||||
text: root.text
|
||||
|
||||
<SizedMDToggleButton>
|
||||
<AutoSizedButton>:
|
||||
width: root.label.texture_size[0]
|
||||
|
||||
<ToggleButtonMixin>:
|
||||
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
|
||||
|
||||
<SizedMDRectangleButton>:
|
||||
<SizedRectangleButton>:
|
||||
outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
<SizedMDRectangleToggleButton>:
|
||||
<AutoSizedRectangleButton>:
|
||||
outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
<SizedRectangleToggleButton>:
|
||||
inactive_outline_color: BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
<AutoSizedMDRectangleButton>: # only wants height
|
||||
width: self.label.texture_size[0] + self.hor_padding * 2
|
||||
font_size: 0.7 * self.height / len(self.label.text.split('\n'))
|
||||
<AutoSizedRectangleToggleButton>:
|
||||
inactive_outline_color: BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: WHITE
|
||||
text_color: self.outline_color
|
||||
|
||||
<AutoSizedMDRectangleToggleButton>: # only wants height
|
||||
width: self.label.texture_size[0] + self.hor_padding * 2
|
||||
font_size: 0.7 * self.height / len(self.label.text.split('\n'))
|
||||
<SizedRoundedRectangleButton@SizedRectangleButton>:
|
||||
background_radius: self.height/3.5
|
||||
|
||||
<AutoSizedRoundedRectangleButton@AutoSizedRectangleButton>:
|
||||
background_radius: self.height/3.5
|
||||
|
||||
|
||||
<BGMDBoxLayout@MDBoxLayout+BackgroundColor>:
|
||||
<BGMDBoxLayout@MDBoxLayout+BackgroundMixin>:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
|
||||
<TransparentIconButton>:
|
||||
@@ -251,7 +262,9 @@
|
||||
Label:
|
||||
id: lbl
|
||||
text: root.text
|
||||
text_size: None, root.min_size
|
||||
bold: True
|
||||
valign: 'center'
|
||||
color: BLACK if root.player=='White' else WHITE
|
||||
pos: (image.x, image.y)
|
||||
size: image.size
|
||||
@@ -275,10 +288,9 @@
|
||||
mid_circles_container: mid_circles_container
|
||||
pass_btn: pass_btn
|
||||
adaptive_height: True
|
||||
AutoSizedMDRectangleButton:
|
||||
AutoSizedRoundedRectangleButton:
|
||||
id: pass_btn
|
||||
text: i18n._('pass-button-text')
|
||||
background_radius: 10
|
||||
size_hint: None, 0.5
|
||||
pos_hint: {'center_x': 0.15,'center_y':0.5}
|
||||
on_left_release: root.katrain("play",None)
|
||||
@@ -298,7 +310,7 @@
|
||||
icon: 'img/flaticon/previous.png'
|
||||
on_press: root.katrain('undo')
|
||||
MDFloatLayout:
|
||||
size_hint: 0.065, 1
|
||||
size_hint: 0.05, 1
|
||||
id: mid_circles_container
|
||||
CircleWithText:
|
||||
size_hint: 5/8, 1
|
||||
@@ -323,6 +335,7 @@
|
||||
on_press: root.katrain('redo',999)
|
||||
NavIconButton:
|
||||
icon: 'img/flaticon/route.png'
|
||||
on_press: root.katrain('switch-branch',1)
|
||||
ClickableLabel:
|
||||
pos_hint: {'center_x': 0.85,'center_y':0.5}
|
||||
size_hint: None, 1
|
||||
@@ -389,22 +402,34 @@
|
||||
<Timer@BGMDBoxLayout>:
|
||||
state: (30,5,1)
|
||||
spacing: CP_SPACING
|
||||
padding: CP_PADDING * 2
|
||||
padding: CP_PADDING * 4, CP_PADDING * 2
|
||||
paused: True
|
||||
TimerLabel:
|
||||
size_hint: 0.5,1
|
||||
id: timer
|
||||
halign: 'right'
|
||||
valign: 'middle'
|
||||
font_size: 0.85*self.size[1]
|
||||
text: f"{root.state[0]//60}:{int(root.state[0] % 60):02d}"
|
||||
TimerLabel:
|
||||
size_hint: 0.2,1
|
||||
id: periods
|
||||
text: f"x{root.state[1]}"
|
||||
font_size: self.width*0.45
|
||||
multiline: False
|
||||
valign: 'top'
|
||||
MDBoxLayout:
|
||||
size_hint: 0.7,1
|
||||
TimerLabel:
|
||||
size_hint: 0.4,1
|
||||
id: timer
|
||||
text_size: self.size
|
||||
halign: 'right'
|
||||
valign: 'middle'
|
||||
font_size: 0.85*self.size[1]
|
||||
text: f"{root.state[0]//60}:{int(root.state[0] % 60):02d}"
|
||||
TimerLabel:
|
||||
size_hint: 0.05,1
|
||||
text: "x"
|
||||
font_size: self.height * 0.3
|
||||
text_size: self.width, self.height * 0.95
|
||||
halign: 'right'
|
||||
valign: 'top'
|
||||
TimerLabel:
|
||||
size_hint: 0.1,1
|
||||
font_size: self.height * 0.35
|
||||
text_size: self.size
|
||||
halign: 'left'
|
||||
valign: 'top'
|
||||
id: periods
|
||||
text: str(root.state[1])
|
||||
multiline: False
|
||||
MDBoxLayout:
|
||||
size_hint: 0.2,1
|
||||
PauseButton:
|
||||
@@ -504,12 +529,18 @@
|
||||
size_hint: 0.6,1
|
||||
id: desc
|
||||
text: root.label if not root.hidden else ''
|
||||
font_size: self.size[1] * 0.8
|
||||
font_size: self.size[1] * 0.7
|
||||
text_size: self.size
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
I18NLabel:
|
||||
size_hint: 0.4,1
|
||||
text: root.text if not root.hidden else ''
|
||||
color: root.color
|
||||
font_size: desc.font_size
|
||||
text_size: self.size
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
id: value
|
||||
bold: True
|
||||
|
||||
@@ -569,6 +600,7 @@
|
||||
#:set CP_SMALL_SPACING 3
|
||||
#:set CP_PADDING 6
|
||||
|
||||
|
||||
<CollapsablePanelHeader>:
|
||||
canvas.after:
|
||||
Color:
|
||||
@@ -593,7 +625,7 @@
|
||||
player_box_height: max(50, 0.075 * root.height)
|
||||
timer_box_height: max(50, 0.1 * 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.15 * root.height)
|
||||
tab_option_height: max(15,root.height / 30)
|
||||
BoxLayout: # -- Players
|
||||
size_hint_y: None
|
||||
@@ -611,10 +643,19 @@
|
||||
Timer:
|
||||
id: timer
|
||||
size_hint_x: 0.7
|
||||
BoxLayout:
|
||||
MDBoxLayout:
|
||||
orientation: 'vertical'
|
||||
padding: 2*CP_PADDING,CP_PADDING
|
||||
spacing: CP_SPACING
|
||||
size_hint_x: 0.3
|
||||
Label:
|
||||
text: '??'
|
||||
SizedRoundedRectangleButton:
|
||||
text: i18n._('pass-button-text')
|
||||
size_hint: 1, 0.5
|
||||
on_left_release: root.katrain("play",None)
|
||||
SizedRoundedRectangleButton:
|
||||
text: i18n._('undo-button-text')
|
||||
size_hint: 1, 0.5
|
||||
on_left_release: root.katrain("undo","smart")
|
||||
CollapsablePanel:
|
||||
height_open: root.graph_box_height
|
||||
closed_label: 'closedlabel:scoregraph'
|
||||
@@ -670,11 +711,12 @@
|
||||
size_hint_y: 1e-9 # takes up remaining space if info is closed
|
||||
|
||||
|
||||
<AnalysisToggle@MDBoxLayout>:
|
||||
<AnalysisToggle>:
|
||||
adaptive_width: True
|
||||
spacing: CP_SPACING
|
||||
size_hint: None, 0.7
|
||||
pos_hint: {'center_y':0.5}
|
||||
checkbox: checkbox
|
||||
I18NLabel:
|
||||
id: label
|
||||
text: root.text
|
||||
@@ -688,7 +730,7 @@
|
||||
size_hint: None,0.5
|
||||
pos_hint: {'center_y': 0.5}
|
||||
width: self.height
|
||||
active: root.active
|
||||
active: root.default_active
|
||||
selected_color: WHITE
|
||||
unselected_color: LIGHTGREY
|
||||
on_active: if app.gui: app.gui.update_state()
|
||||
@@ -733,20 +775,20 @@
|
||||
AnalysisToggle:
|
||||
id: show_children
|
||||
text: i18n._("analysis:nextmoves")
|
||||
active: True
|
||||
default_active: True
|
||||
AnalysisToggle:
|
||||
id: eval
|
||||
text: i18n._("analysis:dots")
|
||||
AnalysisToggle:
|
||||
id: ownership
|
||||
text: i18n._('analysis:territory')
|
||||
id: hints
|
||||
text: i18n._("analysis:topmoves")
|
||||
AnalysisToggle:
|
||||
id: policy
|
||||
text: i18n._("analysis:policy")
|
||||
AnalysisToggle:
|
||||
id: hints
|
||||
text: 'Top\nMoves'
|
||||
AutoSizedMDRectangleButton:
|
||||
id: ownership
|
||||
text: i18n._('analysis:territory')
|
||||
AutoSizedRoundedRectangleButton:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
size_hint_y: 0.5
|
||||
id: analysis_button
|
||||
@@ -789,13 +831,13 @@
|
||||
size_hint: 1,1
|
||||
icon_size: self.height * 0.9, self.height * 0.9
|
||||
|
||||
<MenuLabel@I18NLabel+BackgroundColor>:
|
||||
<MenuLabel@I18NLabel+BackgroundMixin>:
|
||||
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+BackgroundMixin>:
|
||||
katrain: app.gui
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
orientation: 'vertical'
|
||||
@@ -831,7 +873,6 @@
|
||||
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
|
||||
@@ -844,17 +885,19 @@
|
||||
LangButton:
|
||||
icon: 'img/flaticon/flag-ko.png'
|
||||
on_press: app.language = 'ko'
|
||||
MenuLabel:
|
||||
text: i18n._('menu:support')
|
||||
|
||||
<OutlineBox@MDBoxLayout+OutlineColor>:
|
||||
<OutlineBox@MDBoxLayout+BackgroundMixin>:
|
||||
|
||||
|
||||
<PlayAnalyzeButton@SizedMDToggleButton>:
|
||||
<PlayAnalyzeButton@SizedToggleButton>:
|
||||
inactive_background_color: BOX_BACKGROUND_COLOR
|
||||
active_background_color: YELLOW
|
||||
ripple_color: BACKGROUND_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
|
||||
_font_size: self.height * 0.5
|
||||
group: 'play_analyze'
|
||||
allow_no_selection: False
|
||||
|
||||
|
||||
@@ -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 SizedMDButton, LightHelpLabel, ScaledLightLabel, StyledSpinner
|
||||
from katrain.gui.kivyutils import SizedButton, 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(SizedMDButton(text=f"Apply", on_press=lambda _: self.update_config(False))) # raised?
|
||||
bottom_bl.add_widget(SizedButton(text=f"Apply", on_press=lambda _: self.update_config(False))) # raised?
|
||||
bottom_bl.add_widget(self.info_label)
|
||||
bottom_bl.add_widget(SizedMDButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True)))
|
||||
bottom_bl.add_widget(SizedButton(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])
|
||||
|
||||
+14
-13
@@ -9,13 +9,14 @@ from kivy.metrics import sp
|
||||
from kivy.properties import ListProperty, StringProperty, NumericProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.widget import Widget
|
||||
from kivymd.app import MDApp
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.floatlayout import MDFloatLayout
|
||||
from kivymd.uix.menu import MDDropdownMenu, RightContent
|
||||
|
||||
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, BackgroundColor
|
||||
from katrain.gui.kivyutils import draw_circle, draw_text
|
||||
from katrain.core.utils import var_to_grid
|
||||
from kivy.core.window import Window
|
||||
|
||||
@@ -205,9 +206,9 @@ class BadukPanWidget(Widget):
|
||||
Color(0.25, 0.25, 0.25)
|
||||
coord_offset = self.grid_size * 1.5 / 2
|
||||
for i in range(board_size_x):
|
||||
draw_text(pos=(self.gridpos_x[i], self.gridpos_y[0] - coord_offset), text=Move.GTP_COORD[i], font_size=self.grid_size / 1.5)
|
||||
draw_text(pos=(self.gridpos_x[i], self.gridpos_y[0] - coord_offset), text=Move.GTP_COORD[i], font_size=self.grid_size / 1.5, font_name="Roboto")
|
||||
for i in range(board_size_y):
|
||||
draw_text(pos=(self.gridpos_x[0] - coord_offset, self.gridpos_y[i]), text=str(i + 1), font_size=self.grid_size / 1.5)
|
||||
draw_text(pos=(self.gridpos_x[0] - coord_offset, self.gridpos_y[i]), text=str(i + 1), font_size=self.grid_size / 1.5, font_name="Roboto")
|
||||
|
||||
def draw_board_contents(self, *_args):
|
||||
if not (self.katrain and self.katrain.game):
|
||||
@@ -402,7 +403,7 @@ class BadukPanWidget(Widget):
|
||||
|
||||
draw_circle(board_coords, self.stone_size, stone_color[move_player])
|
||||
Color(*stone_color[opp_player])
|
||||
draw_text(pos=board_coords, text=str(i + 1), font_size=self.grid_size / 1.45)
|
||||
draw_text(pos=board_coords, text=str(i + 1), font_size=self.grid_size / 1.45, font_name="Roboto")
|
||||
|
||||
def set_animating_pv(self, pv, node):
|
||||
if node is not None and (not self.animating_pv or not (self.animating_pv[0] == pv and self.animating_pv[1] == node)):
|
||||
@@ -422,7 +423,7 @@ class AnalysisDropdownMenu(MDDropdownMenu):
|
||||
|
||||
class AnalysisControls(MDFloatLayout):
|
||||
ANALYSIS_OPTIONS = ["analysis:extra", "analysis:equalize", "analysis:sweep", "analysis:aimove"]
|
||||
ANALYSIS_SHORTCUTS = ["a", "s", "d", "Enter"]
|
||||
ANALYSIS_SHORTCUTS = ["a", "s", "d", "enter"]
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -434,14 +435,14 @@ class AnalysisControls(MDFloatLayout):
|
||||
{"text": i18n._(text) + f" ({shortcut})"} # , "right_content_cls": AnalysisDropdownMenuRightContent(text=shortcut)}
|
||||
for text, shortcut in zip(self.ANALYSIS_OPTIONS, self.ANALYSIS_SHORTCUTS)
|
||||
]
|
||||
self.analysis_menu = AnalysisDropdownMenu(
|
||||
caller=self.analysis_button,
|
||||
items=menu_items,
|
||||
width_mult=5,
|
||||
use_icon_item=False,
|
||||
callback=lambda item: print(item, item.icon, item.text, item.children[-1].children, item.ids),
|
||||
)
|
||||
print(self.analysis_menu.use_icon_item)
|
||||
self.analysis_menu = AnalysisDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=5, use_icon_item=False, callback=self.action)
|
||||
|
||||
def action(self, item):
|
||||
katrain = MDApp.get_running_app().gui
|
||||
shortcuts = katrain.shortcuts
|
||||
for text, shortcut in zip(self.ANALYSIS_OPTIONS, self.ANALYSIS_SHORTCUTS):
|
||||
if item.text.startswith(i18n._(text)):
|
||||
katrain(*shortcuts[shortcut])
|
||||
|
||||
def open_analysis_menu(self):
|
||||
while not self.analysis_menu:
|
||||
|
||||
@@ -2,10 +2,10 @@ import math
|
||||
|
||||
from kivy.properties import ListProperty, NumericProperty, BooleanProperty
|
||||
|
||||
from katrain.gui.kivyutils import BackgroundColor
|
||||
from katrain.gui.kivyutils import BackgroundMixin
|
||||
|
||||
|
||||
class ScoreGraph(BackgroundColor):
|
||||
class ScoreGraph(BackgroundMixin):
|
||||
show_score = BooleanProperty(True)
|
||||
show_winrate = BooleanProperty(True)
|
||||
|
||||
|
||||
+41
-25
@@ -9,6 +9,7 @@ from kivy.properties import BooleanProperty, ListProperty, NumericProperty, Stri
|
||||
from kivy.uix.behaviors import ToggleButtonBehavior, ButtonBehavior
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.checkbox import CheckBox
|
||||
from kivy.uix.filechooser import FileChooserLayout, FileChooserListLayout
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.scrollview import ScrollView
|
||||
@@ -31,12 +32,10 @@ from katrain.core.utils import i18n, I18NTextInput, I18NLabel
|
||||
from katrain.gui.style import WHITE
|
||||
|
||||
|
||||
class BackgroundColor(Widget):
|
||||
background_color = ListProperty([1, 1, 1, 0])
|
||||
class BackgroundMixin(Widget):
|
||||
background_color = ListProperty([0, 0, 0, 0])
|
||||
background_radius = NumericProperty(0)
|
||||
|
||||
class OutlineColor(Widget):
|
||||
outline_color = ListProperty([1, 1, 1, 0])
|
||||
outline_color = ListProperty([0, 0, 0, 0])
|
||||
outline_width = NumericProperty(1)
|
||||
background_radius = NumericProperty(0)
|
||||
|
||||
@@ -68,35 +67,46 @@ class LeftButtonBehavior(ButtonBehavior): # stops buttons etc activating on rig
|
||||
|
||||
|
||||
# -- resizeable buttons
|
||||
class SizedMDButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedButton, BaseFlatButton, BackgroundColor, OutlineColor): # avoid baserectangular for sizing
|
||||
class SizedButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedButton, BaseFlatButton, BackgroundMixin): # avoid baserectangular for sizing
|
||||
text = StringProperty("")
|
||||
text_color = ListProperty(WHITE)
|
||||
text_size = ListProperty([100, 100])
|
||||
halign = OptionProperty("center", options=["left", "center", "right", "justify", "auto"])
|
||||
label = ObjectProperty(None)
|
||||
height = NumericProperty(33)
|
||||
padding_x = NumericProperty(6)
|
||||
padding_y = NumericProperty(0)
|
||||
_font_size = NumericProperty(None)
|
||||
|
||||
|
||||
class SizedMDToggleButton(ToggleButtonBehavior, SizedMDButton):
|
||||
class AutoSizedButton(SizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class SizedRectangleButton(SizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class AutoSizedRectangleButton(AutoSizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class ToggleButtonMixin(ToggleButtonBehavior):
|
||||
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 SizedMDRectangleButton(SizedMDButton):
|
||||
class SizedToggleButton(ToggleButtonMixin, SizedButton):
|
||||
pass
|
||||
|
||||
|
||||
class SizedMDRectangleToggleButton(SizedMDToggleButton):
|
||||
class SizedRectangleToggleButton(ToggleButtonMixin, SizedRectangleButton):
|
||||
pass
|
||||
|
||||
|
||||
class AutoSizedMDRectangleButton(SizedMDRectangleButton):
|
||||
hor_padding = NumericProperty(6)
|
||||
|
||||
|
||||
class AutoSizedMDRectangleToggleButton(SizedMDRectangleToggleButton):
|
||||
hor_padding = NumericProperty(6)
|
||||
class AutoSizedRectangleToggleButton(ToggleButtonMixin, AutoSizedRectangleButton):
|
||||
pass
|
||||
|
||||
|
||||
class TransparentIconButton(CircularRippleBehavior, Button):
|
||||
@@ -136,7 +146,7 @@ class CircleWithText(Widget):
|
||||
# -- new gui elements
|
||||
|
||||
|
||||
class PlayerInfo(MDBoxLayout, BackgroundColor, OutlineColor):
|
||||
class PlayerInfo(MDBoxLayout, BackgroundMixin):
|
||||
captures = NumericProperty(0)
|
||||
player = OptionProperty("Black", options=["Black", "White"])
|
||||
player_type = StringProperty("Player")
|
||||
@@ -146,10 +156,17 @@ class PlayerInfo(MDBoxLayout, BackgroundColor, OutlineColor):
|
||||
|
||||
class AnalysisToggle(MDBoxLayout):
|
||||
text = StringProperty("")
|
||||
active = BooleanProperty(False)
|
||||
default_active = BooleanProperty(False)
|
||||
|
||||
def trigger_action(self, *args, **kwargs):
|
||||
return self.checkbox.trigger_action(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def active(self):
|
||||
return self.checkbox.active
|
||||
|
||||
|
||||
class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout, BackgroundColor):
|
||||
class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout, BackgroundMixin):
|
||||
__events__ = ["on_action"]
|
||||
icon = StringProperty("")
|
||||
text = StringProperty("")
|
||||
@@ -168,7 +185,7 @@ class CollapsablePanelHeader(MDBoxLayout):
|
||||
pass
|
||||
|
||||
|
||||
class CollapsablePanelTab(AutoSizedMDRectangleToggleButton):
|
||||
class CollapsablePanelTab(AutoSizedRectangleToggleButton):
|
||||
pass
|
||||
|
||||
|
||||
@@ -271,13 +288,12 @@ class CollapsablePanel(MDBoxLayout):
|
||||
pass
|
||||
|
||||
|
||||
class StatsBox(MDBoxLayout, BackgroundColor):
|
||||
class StatsBox(MDBoxLayout, BackgroundMixin):
|
||||
winrate = StringProperty("...")
|
||||
score = StringProperty("...")
|
||||
points_lost = NumericProperty(None, allownone=True)
|
||||
player = StringProperty("")
|
||||
|
||||
|
||||
# --- not checked
|
||||
|
||||
|
||||
@@ -332,7 +348,7 @@ class LightHelpLabel(ScaledLightLabel):
|
||||
pass
|
||||
|
||||
|
||||
class ScrollableLabel(ScrollView, BackgroundColor):
|
||||
class ScrollableLabel(ScrollView, BackgroundMixin):
|
||||
__events__ = ["on_ref_press"]
|
||||
outline_color = ListProperty([0, 0, 0, 0]) # mixin not working for some reason
|
||||
text = StringProperty("")
|
||||
@@ -504,8 +520,8 @@ class LabelledIntInput(LabelledTextInput):
|
||||
return int(self.text)
|
||||
|
||||
|
||||
def draw_text(pos, text, **kw):
|
||||
label = CoreLabel(text=text, bold=True, font_name=i18n._("Roboto"), **kw) #
|
||||
def draw_text(pos, text, font_name=None, **kw):
|
||||
label = CoreLabel(text=text, bold=True, font_name=font_name or i18n.font, **kw) #
|
||||
label.refresh()
|
||||
Rectangle(texture=label.texture, pos=(pos[0] - label.texture.size[0] / 2, pos[1] - label.texture.size[1] / 2), size=label.texture.size)
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ from katrain.core.utils import OUTPUT_DEBUG, OUTPUT_ERROR
|
||||
from katrain.core.engine import KataGoEngine
|
||||
from katrain.core.game import Game, GameNode
|
||||
from katrain.gui.kivyutils import (
|
||||
BackgroundColor,
|
||||
LabelledCheckBox,
|
||||
LabelledFloatInput,
|
||||
LabelledIntInput,
|
||||
@@ -23,6 +22,7 @@ from katrain.gui.kivyutils import (
|
||||
ScaledLightLabel,
|
||||
StyledButton,
|
||||
StyledSpinner,
|
||||
BackgroundMixin,
|
||||
)
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ class ConfigTeacherPopup(QuickConfigGui):
|
||||
for i, (thr, undos, color) in enumerate(zip(thresholds, undos, colors)):
|
||||
thrbox.add_widget(LabelledFloatInput(text=str(thr), input_property=f"eval_thresholds::{i}"))
|
||||
thrbox.add_widget(LabelledFloatInput(text=str(undos), input_property=f"num_undo_prompts::{i}"))
|
||||
thrbox.add_widget(BackgroundColor(background_color=color[:3]))
|
||||
thrbox.add_widget(BackgroundMixin(background_color=color[:3]))
|
||||
thrbox.add_widget(LabelledCheckBox(text=str(color[3] == 1), input_property=f"alpha::{i}"))
|
||||
thrbox.add_widget(LabelledCheckBox(size_hint=(0.5, 1), text=str(self.sgf_settings["save_feedback"][i]), input_property=f"save_feedback::{i}"))
|
||||
self.add_widget(thrbox)
|
||||
|
||||
Binary file not shown.
@@ -29,6 +29,9 @@ msgstr "General Settings"
|
||||
msgid "menu:lang"
|
||||
msgstr "Language"
|
||||
|
||||
msgid "menu:support"
|
||||
msgstr "Support or Contribute"
|
||||
|
||||
#. buttons at the top - should all include a line break
|
||||
msgid "analysis:nextmoves"
|
||||
msgstr ""
|
||||
@@ -78,6 +81,10 @@ msgstr ""
|
||||
"(processing queries). It turns red when the engine has crashed or fails to "
|
||||
"start."
|
||||
|
||||
#. undo button on the right
|
||||
msgid "undo-button-text"
|
||||
msgstr "Undo"
|
||||
|
||||
#. tabs and labels on the right panel
|
||||
msgid "tab:score"
|
||||
msgstr "Score"
|
||||
@@ -181,6 +188,9 @@ msgid "SGF Notes Hint"
|
||||
msgstr "Your SGF notes for this position here."
|
||||
|
||||
#. misc errors and info messages
|
||||
msgid "wait-before-equalize"
|
||||
msgstr "Wait for initial analysis to complete before requesting a refinement."
|
||||
|
||||
msgid "Copied SGF to clipboard."
|
||||
msgstr "Copied SGF to clipboard."
|
||||
|
||||
@@ -200,7 +210,7 @@ msgstr ""
|
||||
|
||||
msgid "Starting Kata failed"
|
||||
msgstr ""
|
||||
"Starting kata with command '{command}' failed with error {error}. Please "
|
||||
"Starting KataGo with command '{command}' failed with error {error}. Please "
|
||||
"make sure the 'katago' value under 'engine' in settings points to the "
|
||||
"correct KataGo executable."
|
||||
|
||||
|
||||
Binary file not shown.
@@ -10,15 +10,6 @@ msgstr ""
|
||||
msgid "LANG_FONT"
|
||||
msgstr "fonts/NotoSansKR-Regular.otf"
|
||||
|
||||
msgid "English"
|
||||
msgstr "영어"
|
||||
|
||||
msgid "Dutch"
|
||||
msgstr "네덜란드어"
|
||||
|
||||
msgid "Korean"
|
||||
msgstr "한국어"
|
||||
|
||||
msgid "pass-button-text"
|
||||
msgstr "패스"
|
||||
|
||||
@@ -229,3 +220,15 @@ msgstr "Force AI Move"
|
||||
#. TODO
|
||||
msgid "analysis:extra"
|
||||
msgstr "Deeper analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "undo-button-text"
|
||||
msgstr "Undo"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:support"
|
||||
msgstr "Support or Contribute"
|
||||
|
||||
#. TODO
|
||||
msgid "wait-before-equalize"
|
||||
msgstr "Wait for initial analysis to complete before requesting a refinement."
|
||||
Binary file not shown.
@@ -7,17 +7,8 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. This is the font used, files ONLY relative to 'katrain' directory
|
||||
msgid "Roboto"
|
||||
msgstr "Roboto"
|
||||
|
||||
msgid "English"
|
||||
msgstr "Engels"
|
||||
|
||||
msgid "Dutch"
|
||||
msgstr "Nederlands"
|
||||
|
||||
msgid "Korean"
|
||||
msgstr "Koreaans"
|
||||
msgid "LANG_FONT"
|
||||
msgstr "fonts/NotoSans-Regular.ttf"
|
||||
|
||||
msgid "pass-button-text"
|
||||
msgstr "Pas"
|
||||
@@ -262,5 +253,13 @@ msgid "analysis:extra"
|
||||
msgstr "Deeper analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "LANG_FONT"
|
||||
msgstr "fonts/NotoSans-Regular.ttf"
|
||||
msgid "undo-button-text"
|
||||
msgstr "Undo"
|
||||
|
||||
#. TODO
|
||||
msgid "menu:support"
|
||||
msgstr "Support or Contribute"
|
||||
|
||||
#. TODO
|
||||
msgid "wait-before-equalize"
|
||||
msgstr "Wait for initial analysis to complete before requesting a refinement."
|
||||
Reference in new issue
Block a user