theme
This commit is contained in:
1 parent
3d43bf660f
commit
bfa673d4b6
22 files changed
+477
-404
No files matched your search
@@ -0,0 +1,3 @@
|
||||
[flake8]
|
||||
ignore = E501, E203, W503, E402 # line length, space before binary op, line break before binary op, import not at top
|
||||
exclude = .git,__pycache__,build,dist
|
||||
+39
-15
@@ -1,7 +1,11 @@
|
||||
"""isort:skip_file"""
|
||||
# first, logging level lower
|
||||
import json
|
||||
import os
|
||||
|
||||
from kivy.core.window import Window
|
||||
from kivy.uix.widget import Widget
|
||||
|
||||
os.environ["KCFG_KIVY_LOG_LEVEL"] = os.environ.get("KCFG_KIVY_LOG_LEVEL", "warning")
|
||||
if "KIVY_AUDIO" not in os.environ:
|
||||
os.environ["KIVY_AUDIO"] = "sdl2" # some backends hard crash / this seems to be most stable
|
||||
@@ -46,9 +50,11 @@ from kivy.lang import Builder
|
||||
from kivy.resources import resource_add_path
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.uix.screenmanager import Screen
|
||||
from katrain.core.ai import generate_ai_move
|
||||
from kivy.core.window import Window
|
||||
from kivy.resources import resource_find
|
||||
from kivy.properties import NumericProperty, ObjectProperty, StringProperty
|
||||
from kivy.clock import Clock
|
||||
from kivy.metrics import dp
|
||||
from katrain.core.ai import generate_ai_move
|
||||
|
||||
from katrain.core.lang import DEFAULT_LANGUAGE, i18n
|
||||
from katrain.core.constants import (
|
||||
@@ -57,7 +63,6 @@ from katrain.core.constants import (
|
||||
OUTPUT_INFO,
|
||||
OUTPUT_DEBUG,
|
||||
OUTPUT_EXTRA_DEBUG,
|
||||
MODE_PLAY,
|
||||
MODE_ANALYZE,
|
||||
HOMEPAGE,
|
||||
VERSION,
|
||||
@@ -66,18 +71,23 @@ from katrain.core.constants import (
|
||||
PLAYING_NORMAL,
|
||||
PLAYER_HUMAN,
|
||||
SGF_INTERNAL_COMMENTS_MARKER,
|
||||
MODE_PLAY,
|
||||
DATA_FOLDER,
|
||||
)
|
||||
from katrain.gui.popups import ConfigTeacherPopup, ConfigTimerPopup, I18NPopup, SaveSGFPopup
|
||||
from katrain.core.base_katrain import KaTrainBase
|
||||
from katrain.core.engine import KataGoEngine
|
||||
from katrain.core.game import Game, IllegalMoveException, KaTrainSGF
|
||||
from katrain.core.sgf_parser import Move, ParseError
|
||||
from katrain.gui.kivyutils import *
|
||||
from katrain.gui.popups import ConfigPopup, LoadSGFPopup, NewGamePopup, ConfigAIPopup
|
||||
from katrain.gui.style import ENGINE_BUSY_COL, ENGINE_DOWN_COL, ENGINE_READY_COL
|
||||
from katrain.gui.widgets import *
|
||||
from katrain.gui.badukpan import AnalysisControls, BadukPanControls, BadukPanWidget
|
||||
from katrain.gui.controlspanel import ControlsPanel
|
||||
from katrain.gui.theme import Theme
|
||||
from kivymd.app import MDApp
|
||||
|
||||
# used in kv
|
||||
from katrain.gui.kivyutils import *
|
||||
from katrain.gui.widgets import MoveTree, I18NFileBrowser, SelectionSlider, ScoreGraph # noqa F401
|
||||
from katrain.gui.badukpan import AnalysisControls, BadukPanControls, BadukPanWidget # noqa F401
|
||||
from katrain.gui.controlspanel import ControlsPanel # noqa F401
|
||||
|
||||
|
||||
class KaTrainGui(Screen, KaTrainBase):
|
||||
@@ -165,11 +175,11 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
|
||||
# update engine status dot
|
||||
if not self.engine or not self.engine.katago_process or self.engine.katago_process.poll() is not None:
|
||||
self.board_controls.engine_status_col = ENGINE_DOWN_COL
|
||||
self.board_controls.engine_status_col = Theme.ENGINE_DOWN_COLOR
|
||||
elif len(self.engine.queries) == 0:
|
||||
self.board_controls.engine_status_col = ENGINE_READY_COL
|
||||
self.board_controls.engine_status_col = Theme.ENGINE_READY_COLOR
|
||||
else:
|
||||
self.board_controls.engine_status_col = ENGINE_BUSY_COL
|
||||
self.board_controls.engine_status_col = Theme.ENGINE_BUSY_COLOR
|
||||
self.board_controls.queries_remaining = len(self.engine.queries)
|
||||
|
||||
# redraw board/stones
|
||||
@@ -590,7 +600,8 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
yappi.start()
|
||||
self.log("starting profiler", OUTPUT_ERROR)
|
||||
elif keycode[1] == "f10" and self.debug_level >= OUTPUT_EXTRA_DEBUG:
|
||||
import yappi, time
|
||||
import time
|
||||
import yappi
|
||||
|
||||
stats = yappi.get_func_stats()
|
||||
filename = f"callgrind.{int(time.time())}.prof"
|
||||
@@ -607,7 +618,6 @@ class KaTrainApp(MDApp):
|
||||
super().__init__()
|
||||
|
||||
def build(self):
|
||||
global DEFAULT_FONT
|
||||
self.icon = ICON # how you're supposed to set an icon
|
||||
|
||||
self.title = f"KaTrain v{VERSION}"
|
||||
@@ -617,8 +627,22 @@ class KaTrainApp(MDApp):
|
||||
|
||||
kv_file = find_package_resource("katrain/gui.kv")
|
||||
popup_kv_file = find_package_resource("katrain/popups.kv")
|
||||
resource_add_path(PATHS["PACKAGE"])
|
||||
DEFAULT_FONT = resource_find(DEFAULT_FONT)
|
||||
resource_add_path(PATHS["PACKAGE"] + "/sounds")
|
||||
resource_add_path(PATHS["PACKAGE"] + "/img")
|
||||
resource_add_path(os.path.abspath(os.path.expanduser(DATA_FOLDER))) # prefer resources in .katrain
|
||||
|
||||
theme_file = resource_find("theme.json")
|
||||
if theme_file:
|
||||
try:
|
||||
with open(theme_file) as f:
|
||||
theme_overrides = json.load(f)
|
||||
for k, v in theme_overrides.items():
|
||||
setattr(Theme, k, v)
|
||||
print(f"[{theme_file}] Found theme override {k} = {v}")
|
||||
except Exception as e: # noqa E722
|
||||
print(f"Failed to load theme file {theme_file}: {e}")
|
||||
|
||||
Theme.DEFAULT_FONT = resource_find(Theme.DEFAULT_FONT)
|
||||
Builder.load_file(kv_file)
|
||||
|
||||
Window.bind(on_request_close=self.on_request_close)
|
||||
|
||||
+3
-3
@@ -125,11 +125,11 @@ def policy_weighted_move(policy_moves, lower_bound, weaken_fac):
|
||||
def generate_influence_territory_weights(ai_mode, ai_settings, policy_grid, size):
|
||||
thr_line = ai_settings["threshold"] - 1 # zero-based
|
||||
if ai_mode == AI_INFLUENCE:
|
||||
weight = lambda x, y: (1 / ai_settings["line_weight"]) ** (
|
||||
weight = lambda x, y: (1 / ai_settings["line_weight"]) ** ( # noqa E731
|
||||
max(0, thr_line - min(size[0] - 1 - x, x)) + max(0, thr_line - min(size[1] - 1 - y, y))
|
||||
)
|
||||
) # noqa E731
|
||||
else:
|
||||
weight = lambda x, y: (1 / ai_settings["line_weight"]) ** (
|
||||
weight = lambda x, y: (1 / ai_settings["line_weight"]) ** ( # noqa E731
|
||||
max(0, min(size[0] - 1 - x, x, size[1] - 1 - y, y) - thr_line)
|
||||
)
|
||||
weighted_coords = [
|
||||
|
||||
@@ -6,7 +6,18 @@ from kivy import Config
|
||||
from kivy.storage.jsonstore import JsonStore
|
||||
|
||||
from katrain.core.ai import ai_rank_estimation
|
||||
from katrain.core.constants import *
|
||||
from katrain.core.constants import (
|
||||
PLAYER_HUMAN,
|
||||
PLAYER_AI,
|
||||
PLAYING_NORMAL,
|
||||
PLAYING_TEACHING,
|
||||
OUTPUT_INFO,
|
||||
OUTPUT_ERROR,
|
||||
OUTPUT_DEBUG,
|
||||
AI_DEFAULT,
|
||||
CONFIG_MIN_VERSION,
|
||||
DATA_FOLDER,
|
||||
)
|
||||
from katrain.core.utils import find_package_resource
|
||||
|
||||
|
||||
@@ -44,7 +55,7 @@ class Player:
|
||||
|
||||
|
||||
class KaTrainBase:
|
||||
USER_CONFIG_FILE = os.path.expanduser("~/.katrain/config.json")
|
||||
USER_CONFIG_FILE = os.path.expanduser(os.path.join(DATA_FOLDER, "config.json"))
|
||||
PACKAGE_CONFIG_FILE = "katrain/config.json"
|
||||
|
||||
"""Settings, logging, and players functionality, so other classes like bots who need a katrain instance can be used without a GUI"""
|
||||
@@ -91,7 +102,7 @@ class KaTrainBase:
|
||||
else: # user file exists
|
||||
try:
|
||||
version = JsonStore(user_config_file).get("general")["version"]
|
||||
except Exception: # broken file etc
|
||||
except Exception: # noqa E722 broken file etc
|
||||
version = "0.0.0"
|
||||
if version < CONFIG_MIN_VERSION:
|
||||
backup = user_config_file + f".{version}.backup"
|
||||
|
||||
@@ -3,6 +3,7 @@ VERSION = "1.7.0"
|
||||
HOMEPAGE = "https://github.com/sanderland/katrain"
|
||||
CONFIG_MIN_VERSION = "1.7.0" # keep config files from this version
|
||||
ANALYSIS_FORMAT_VERSION = "1.0"
|
||||
DATA_FOLDER = "~/.katrain"
|
||||
|
||||
OUTPUT_ERROR = -1
|
||||
OUTPUT_KATAGO_STDERR = -0.5
|
||||
|
||||
@@ -215,7 +215,7 @@ class Game:
|
||||
if not copy_from_node.children:
|
||||
break
|
||||
copy_from_node = copy_from_node.ordered_children[0]
|
||||
except:
|
||||
except IllegalMoveException:
|
||||
pass # illegal move = stop
|
||||
self._calculate_groups() # recalculate groups
|
||||
self.katrain.controls.set_status(
|
||||
|
||||
@@ -15,7 +15,7 @@ from katrain.core.constants import (
|
||||
from katrain.core.lang import i18n
|
||||
from katrain.core.sgf_parser import Move, SGFNode
|
||||
from katrain.core.utils import evaluation_class, pack_floats, unpack_floats, var_to_grid
|
||||
from katrain.gui.style import INFO_PV_COLOR
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
|
||||
def analysis_dumps(analysis):
|
||||
@@ -287,7 +287,7 @@ class GameNode(SGFNode):
|
||||
def make_pv(self, player, pv, interactive):
|
||||
pvtext = f"{player}{' '.join(pv)}"
|
||||
if interactive:
|
||||
pvtext = f"[u][ref={pvtext}][color={INFO_PV_COLOR}]{pvtext}[/color][/ref][/u]"
|
||||
pvtext = f"[u][ref={pvtext}][color={Theme.INFO_PV_COLOR}]{pvtext}[/color][/ref][/u]"
|
||||
return pvtext
|
||||
|
||||
def comment(self, sgf=False, teach=False, details=False, interactive=True):
|
||||
|
||||
@@ -5,7 +5,7 @@ import sys
|
||||
from kivy._event import Observable
|
||||
|
||||
from katrain.core.utils import find_package_resource
|
||||
from katrain.gui.style import DEFAULT_FONT
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
|
||||
class Lang(Observable):
|
||||
@@ -53,7 +53,7 @@ class Lang(Observable):
|
||||
return
|
||||
# get the right locales directory, and instantiate a gettext
|
||||
self.lang = lang
|
||||
self.font_name = self.FONTS.get(lang) or DEFAULT_FONT
|
||||
self.font_name = self.FONTS.get(lang) or Theme.DEFAULT_FONT
|
||||
i18n_dir, _ = os.path.split(find_package_resource("katrain/i18n/__init__.py"))
|
||||
locale_dir = os.path.join(i18n_dir, "locales")
|
||||
locales = gettext.translation("katrain", locale_dir, languages=[lang, DEFAULT_LANGUAGE])
|
||||
|
||||
@@ -439,7 +439,7 @@ class SGF:
|
||||
re = "W+"
|
||||
elif "lack win" in lines[10]:
|
||||
re = "B+"
|
||||
except:
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
if handicap < 0 or handicap > 9:
|
||||
@@ -527,7 +527,7 @@ class SGF:
|
||||
try:
|
||||
grlt = int(re.search(grlt_regex, line).group(1))
|
||||
zipsu = int(re.search(zipsu_regex, line).group(1))
|
||||
except:
|
||||
except: # noqa E722
|
||||
return ""
|
||||
return gib_make_result(grlt, zipsu)
|
||||
|
||||
@@ -561,7 +561,7 @@ class SGF:
|
||||
komi = int(re.search(r"GONGJE:(\d+),", line).group(1)) / 10
|
||||
if komi:
|
||||
root.set_property("KM", komi)
|
||||
except:
|
||||
except: # noqa E722
|
||||
pass
|
||||
|
||||
if line.startswith("\\[GAMETAG="):
|
||||
@@ -570,7 +570,7 @@ class SGF:
|
||||
match = re.search(r"C(\d\d\d\d):(\d\d):(\d\d)", line)
|
||||
date = "{}-{}-{}".format(match.group(1), match.group(2), match.group(3))
|
||||
root.set_property("DT", date)
|
||||
except:
|
||||
except: # noqa E722
|
||||
pass
|
||||
|
||||
if "RE" not in root.properties:
|
||||
@@ -583,7 +583,7 @@ class SGF:
|
||||
komi = int(re.search(r",G(\d+),", line).group(1)) / 10
|
||||
if komi:
|
||||
root.set_property("KM", komi)
|
||||
except:
|
||||
except: # noqa E722
|
||||
pass
|
||||
|
||||
if line[0:3] == "INI":
|
||||
@@ -592,7 +592,7 @@ class SGF:
|
||||
setup = line.split()
|
||||
try:
|
||||
handicap = int(setup[3])
|
||||
except IndexError:
|
||||
except ParseError:
|
||||
continue
|
||||
|
||||
if handicap < 0 or handicap > 9:
|
||||
|
||||
+100
-122
@@ -10,30 +10,14 @@
|
||||
#:import MODE_ANALYZE katrain.core.constants.MODE_ANALYZE
|
||||
#:import STATUS_INFO katrain.core.constants.STATUS_INFO
|
||||
|
||||
#:import Theme katrain.gui.theme.Theme
|
||||
#:import BLACK katrain.gui.theme.BLACK
|
||||
#:import LIGHTER_GREY katrain.gui.theme.LIGHTER_GREY
|
||||
|
||||
#:import WHITE katrain.gui.style.WHITE
|
||||
#:import BLACK katrain.gui.style.BLACK
|
||||
#:import LIGHTGREY katrain.gui.style.LIGHTGREY
|
||||
#:import LIGHTERGREY katrain.gui.style.LIGHTERGREY
|
||||
#:import GREEN katrain.gui.style.GREEN
|
||||
#:import YELLOW katrain.gui.style.YELLOW
|
||||
#:import RED katrain.gui.style.RED
|
||||
#:import DARKRED katrain.gui.style.DARKRED
|
||||
#:import ORANGE katrain.gui.style.ORANGE
|
||||
|
||||
#:import BACKGROUND_COLOR katrain.gui.style.BACKGROUND_COLOR
|
||||
#:import BOX_BACKGROUND_COLOR katrain.gui.style.BOX_BACKGROUND_COLOR
|
||||
#:import LIGHTER_BACKGROUND_COLOR katrain.gui.style.LIGHTER_BACKGROUND_COLOR
|
||||
#:import TEXT_COLOR katrain.gui.style.TEXT_COLOR
|
||||
#:import SCORE_COLOR katrain.gui.style.SCORE_COLOR
|
||||
#:import WINRATE_COLOR katrain.gui.style.WINRATE_COLOR
|
||||
#:import POINTLOSS_COLOR katrain.gui.style.POINTLOSS_COLOR
|
||||
#:set BUTTON_INACTIVE_COLOR LIGHTGREY
|
||||
|
||||
#:set CP_SPACING dp(6)
|
||||
#:set CP_SMALL_SPACING dp(3)
|
||||
#:set CP_PADDING dp(6)
|
||||
#:set NOTES_FONT_SIZE sp(18)
|
||||
#:set CP_SPACING Theme.CP_SPACING
|
||||
#:set CP_SMALL_SPACING Theme.CP_SMALL_SPACING
|
||||
#:set CP_PADDING Theme.CP_PADDING
|
||||
|
||||
#:set EPSILON 1e-9
|
||||
|
||||
@@ -68,8 +52,8 @@
|
||||
|
||||
<SizedButton>:
|
||||
ripple_duration_in_slow: 0.6
|
||||
text_color: TEXT_COLOR
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
text_color: Theme.TEXT_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
label: label
|
||||
text_size: root.size
|
||||
Label:
|
||||
@@ -85,27 +69,27 @@
|
||||
width: root.label.texture_size[0]
|
||||
|
||||
<ToggleButtonMixin>:
|
||||
inactive_background_color: BACKGROUND_COLOR
|
||||
active_background_color: BOX_BACKGROUND_COLOR
|
||||
inactive_background_color: Theme.BACKGROUND_COLOR
|
||||
active_background_color: Theme.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
|
||||
outline_color: Theme.BUTTON_BORDER_COLOR
|
||||
text_color: self.outline_color
|
||||
|
||||
<AutoSizedRectangleButton>:
|
||||
outline_color: WHITE
|
||||
outline_color: Theme.BUTTON_BORDER_COLOR
|
||||
text_color: self.outline_color
|
||||
|
||||
<SizedRectangleToggleButton>:
|
||||
inactive_outline_color: BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: WHITE
|
||||
inactive_outline_color: Theme.BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: Theme.BUTTON_BORDER_COLOR
|
||||
text_color: self.outline_color
|
||||
|
||||
<AutoSizedRectangleToggleButton>:
|
||||
inactive_outline_color: BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: WHITE
|
||||
inactive_outline_color: Theme.BUTTON_INACTIVE_COLOR
|
||||
active_outline_color: Theme.BUTTON_BORDER_COLOR
|
||||
text_color: self.outline_color
|
||||
|
||||
<SizedRoundedRectangleButton@SizedRectangleButton>:
|
||||
@@ -115,7 +99,7 @@
|
||||
background_radius: self.height/3.5
|
||||
|
||||
<BGBoxLayout>:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
|
||||
<TransparentIconButton>:
|
||||
background_normal: ''
|
||||
@@ -131,20 +115,20 @@
|
||||
|
||||
|
||||
<I18NSpinnerOption@SpinnerOption>:
|
||||
background_color: LIGHTER_BACKGROUND_COLOR
|
||||
background_color: Theme.LIGHTER_BACKGROUND_COLOR
|
||||
background_normal: ''
|
||||
lang_change_tracking: i18n._('') # for font
|
||||
color: WHITE
|
||||
color: Theme.INPUT_FONT_COLOR
|
||||
canvas.after:
|
||||
Color:
|
||||
rgba: LIGHTGREY
|
||||
rgba: LIGHT_GREY
|
||||
Line
|
||||
points: self.x,self.y,self.x+self.width,self.y
|
||||
width: 1
|
||||
|
||||
<Spinner>:
|
||||
-font_size: self.height * 0.5
|
||||
background_color: [*[c*255/88 for c in BACKGROUND_COLOR[:3]], 1] # compensate for texture
|
||||
background_color: [*[c*255/88 for c in Theme.BACKGROUND_COLOR[:3]], 1] # compensate for texture
|
||||
option_cls: 'I18NSpinnerOption'
|
||||
|
||||
<Button>:
|
||||
@@ -159,7 +143,7 @@
|
||||
id: image
|
||||
pos: (root.pos[0] + (root.width - root.min_size)/2,root.pos[1] + (root.height - root.min_size)/2)
|
||||
size: (root.min_size,root.min_size)
|
||||
source: 'img/white.png' if root.player=='W' else 'img/black.png'
|
||||
source: 'white_circle.png' if root.player=='W' else 'black_circle.png'
|
||||
mipmap: True
|
||||
Label:
|
||||
id: lbl
|
||||
@@ -167,7 +151,7 @@
|
||||
text_size: None, root.min_size
|
||||
bold: True
|
||||
valign: 'center'
|
||||
color: BLACK if root.player=='W' else WHITE
|
||||
color: Theme.CIRCLE_TEXT_COLORS[root.player]
|
||||
pos: (image.x, image.y)
|
||||
size: image.size
|
||||
font_size: root.min_size * 1.2 / (1 + 1 * len(self.text))
|
||||
@@ -203,13 +187,13 @@
|
||||
Label:
|
||||
size_hint: 0.075, 0.5
|
||||
NavIconButton:
|
||||
icon: 'img/Previous-End.png'
|
||||
icon: 'Previous-End.png'
|
||||
on_press: root.katrain('undo',999)
|
||||
NavIconButton:
|
||||
icon: 'img/Previous-5.png'
|
||||
icon: 'Previous-5.png'
|
||||
on_press: root.katrain('undo',10)
|
||||
NavIconButton:
|
||||
icon: 'img/Previous.png'
|
||||
icon: 'Previous.png'
|
||||
on_press: root.katrain('undo')
|
||||
MDFloatLayout:
|
||||
size_hint: 0.05, 1
|
||||
@@ -227,16 +211,16 @@
|
||||
player: 'W'
|
||||
text: ''
|
||||
NavIconButton:
|
||||
icon: 'img/Next.png'
|
||||
icon: 'Next.png'
|
||||
on_press: root.katrain('redo')
|
||||
NavIconButton:
|
||||
icon: 'img/Next-5.png'
|
||||
icon: 'Next-5.png'
|
||||
on_press: root.katrain('redo',10)
|
||||
NavIconButton:
|
||||
icon: 'img/Next-End.png'
|
||||
icon: 'Next-End.png'
|
||||
on_press: root.katrain('redo',999)
|
||||
NavIconButton:
|
||||
icon: 'img/Next-Mistake.png'
|
||||
icon: 'Next-Mistake.png'
|
||||
color: [0.79,0.06,0.06,1]
|
||||
on_press: root.katrain('next-mistake')
|
||||
ClickableLabel:
|
||||
@@ -245,7 +229,7 @@
|
||||
width: self.height
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: YELLOW
|
||||
rgba: Theme.ENGINE_PONDERING_COLOR
|
||||
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
|
||||
@@ -268,7 +252,7 @@
|
||||
|
||||
|
||||
<HamburgerButton@TransparentIconButton>:
|
||||
icon: 'img/hamburger.png'
|
||||
icon: 'hamburger.png'
|
||||
width: self.height
|
||||
icon_size: [self.height * 0.5, self.height * 0.5]
|
||||
|
||||
@@ -279,8 +263,8 @@
|
||||
player: 'B'
|
||||
player_type: 'player:human'
|
||||
player_subtype: 'game:normal'
|
||||
background_color: BOX_BACKGROUND_COLOR if self.active else BACKGROUND_COLOR
|
||||
outline_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR if self.active else Theme.BACKGROUND_COLOR
|
||||
outline_color: Theme.BOX_BACKGROUND_COLOR
|
||||
outline_width: 2
|
||||
padding: [2*CP_PADDING,CP_PADDING,CP_PADDING,CP_PADDING]
|
||||
CircleWithText:
|
||||
@@ -314,9 +298,9 @@
|
||||
height: self.width
|
||||
size_hint: 1, None
|
||||
min_size: min(self.height,self.width)
|
||||
inactive_line_color: WHITE
|
||||
inactive_line_color: Theme.BUTTON_BORDER_COLOR
|
||||
inactive_fill_color: [1,1,1,0]
|
||||
active_line_color: ORANGE
|
||||
active_line_color: Theme.PAUSE_ACTIVE_COLOR
|
||||
active_fill_color: [1,1,1,0]
|
||||
line_width: max(1.1,self.min_size/20)
|
||||
line_color: root.active_line_color if self.active else root.inactive_line_color
|
||||
@@ -345,10 +329,9 @@
|
||||
cap: 'square'
|
||||
|
||||
|
||||
|
||||
<TimerLabel@Label>
|
||||
timeout: False
|
||||
color: ORANGE if self.timeout else GREEN
|
||||
color: Theme.TIMER_TEXT_TIMEOUT_COLOR if self.timeout else Theme.TIMER_TEXT_COLOR
|
||||
markup: True
|
||||
max_lines: 1
|
||||
font_name: 'fonts/digital-7 (mono).ttf'
|
||||
@@ -363,7 +346,7 @@
|
||||
MDFloatLayout:
|
||||
size_hint: 0.4,1
|
||||
TimerLabel:
|
||||
color: BACKGROUND_COLOR
|
||||
color: Theme.BACKGROUND_COLOR
|
||||
text: '{}:88'.format('188' if root.state[0] >= 6000 else '88')
|
||||
font_size: 0.85*self.height
|
||||
pos_hint: {'right':1,'center_y':0.5}
|
||||
@@ -441,30 +424,30 @@
|
||||
|
||||
<StatsBox>
|
||||
orientation: 'vertical'
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
labels: {'score':score_label,'winrate':winrate_label,'points':pointloss_label}
|
||||
StatsLabel:
|
||||
id: winrate_label
|
||||
label: i18n._('stats:winrate')
|
||||
text: root.winrate
|
||||
color: WINRATE_COLOR
|
||||
color: Theme.WINRATE_COLOR
|
||||
StatsLabel:
|
||||
id: score_label
|
||||
label: i18n._('stats:score')
|
||||
text: root.score
|
||||
color: SCORE_COLOR
|
||||
color: Theme.SCORE_COLOR
|
||||
StatsLabel:
|
||||
id: pointloss_label
|
||||
label: i18n._('stats:pointslost') if root.points_lost is None or root.points_lost > 0 else i18n._('stats:pointsgained')
|
||||
text: '{}: {:.1f}'.format(root.player,abs(root.points_lost)) if root.points_lost is not None else '...'
|
||||
color: POINTLOSS_COLOR
|
||||
color: Theme.POINTLOSS_COLOR
|
||||
|
||||
<ScrollableLabel>:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
do_scroll_x: False
|
||||
scroll_type: ['bars']
|
||||
bar_width: 5
|
||||
bar_color: LIGHTGREY
|
||||
bar_color: Theme.SCROLLBAR_COLOR
|
||||
label: label
|
||||
canvas.before:
|
||||
Color:
|
||||
@@ -477,9 +460,9 @@
|
||||
lang_change_tracking: i18n._('')
|
||||
markup: root.markup
|
||||
padding: 5, 5
|
||||
font_size: NOTES_FONT_SIZE
|
||||
font_size: Theme.NOTES_FONT_SIZE
|
||||
line_height: root.line_height
|
||||
color: TEXT_COLOR
|
||||
color: Theme.TEXT_COLOR
|
||||
size_hint_y: None
|
||||
height: self.texture_size[1]
|
||||
text_size: self.width, None
|
||||
@@ -497,7 +480,7 @@
|
||||
<CollapsablePanelHeader>:
|
||||
canvas.after:
|
||||
Color:
|
||||
rgba: BOX_BACKGROUND_COLOR
|
||||
rgba: Theme.BOX_BACKGROUND_COLOR
|
||||
Line:
|
||||
width: 1
|
||||
points: (self.x,self.y+1,self.x+self.width,self.y+1)
|
||||
@@ -567,7 +550,7 @@
|
||||
options_height: root.tab_option_height
|
||||
closed_label: 'closedlabel:scoregraph'
|
||||
options: ['score','winrate']
|
||||
option_colors: [SCORE_COLOR,WINRATE_COLOR]
|
||||
option_colors: [Theme.SCORE_COLOR,Theme.WINRATE_COLOR]
|
||||
option_active: [True,False,False]
|
||||
on_option_state:
|
||||
graph.show_graphs(args[1])
|
||||
@@ -584,7 +567,7 @@
|
||||
options_height: root.tab_option_height
|
||||
closed_label: 'closedlabel:movestats'
|
||||
options: ['score','winrate','points']
|
||||
option_colors: [SCORE_COLOR,WINRATE_COLOR,POINTLOSS_COLOR]
|
||||
option_colors: [Theme.SCORE_COLOR,Theme.WINRATE_COLOR,Theme.POINTLOSS_COLOR]
|
||||
option_active: [True,True,True]
|
||||
on_option_state:
|
||||
for k, v in args[1].items(): stats.labels[k].hidden = not v
|
||||
@@ -596,26 +579,26 @@
|
||||
size_hint_y_open: 1
|
||||
closed_label: 'closedlabel:info¬es'
|
||||
options: ['info','info-details','notes']
|
||||
option_colors: [WHITE,WHITE,YELLOW]
|
||||
option_colors: [Theme.INFO_TAB_FONT_COLOR,Theme.INFO_TAB_FONT_COLOR,Theme.NOTES_TAB_FONT_COLOR]
|
||||
option_active: [True,False,False]
|
||||
on_option_state:
|
||||
info.detailed = args[1]['info-details']
|
||||
info.size_hint_y = int(args[1]['info'] or info.detailed)+1e-9
|
||||
info.size_hint_y = int(args[1]['info'] or info.detailed)+EPSILON
|
||||
info.opacity = int(args[1]['info'] or info.detailed)
|
||||
notebox.size_hint_y = int(args[1]['notes'])*0.66+1e-9
|
||||
notebox.size_hint_y = int(args[1]['notes'])*0.66+EPSILON
|
||||
notebox.opacity = int(args[1]['notes'])
|
||||
app.gui.update_state()
|
||||
options_height: root.tab_option_height
|
||||
BGBoxLayout:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
orientation: 'vertical'
|
||||
ScrollableLabel:
|
||||
id: status
|
||||
error: False
|
||||
size_hint: 1, None
|
||||
height: min(self.parent.height*0.66,self.label.texture_size[1])
|
||||
outline_color: RED if self.error else WHITE
|
||||
background_color: LIGHTER_BACKGROUND_COLOR
|
||||
outline_color: Theme.ERROR_BORDER_COLOR if self.error else Theme.INFO_TAB_FONT_COLOR
|
||||
background_color: Theme.LIGHTER_BACKGROUND_COLOR
|
||||
ScrollableLabel:
|
||||
id: info
|
||||
detailed: False
|
||||
@@ -630,28 +613,28 @@
|
||||
size_hint: 1,0
|
||||
LabelledTextInput:
|
||||
id: note
|
||||
font_size: NOTES_FONT_SIZE
|
||||
font_size: Theme.NOTES_FONT_SIZE
|
||||
multiline: True
|
||||
on_text: root.katrain.set_note(self.text)
|
||||
hint_text: i18n._('SGF Notes Hint')
|
||||
color_mode: 'custom'
|
||||
line_color_focus: TEXT_COLOR
|
||||
line_color_focus: Theme.TEXT_COLOR
|
||||
size_hint: 1, 1
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: LIGHTERGREY
|
||||
rgba: LIGHTER_GREY
|
||||
Line:
|
||||
points: self.x, self.y+self.height, self.x+self.width, self.y+self.height
|
||||
width: 1
|
||||
Label:
|
||||
size_hint_y: 1e-9 # takes up remaining space if info is closed
|
||||
size_hint_y: EPSILON # takes up remaining space if info is closed
|
||||
|
||||
|
||||
<MenuItem>
|
||||
font_size: self.height * 0.5
|
||||
size_hint_y: None
|
||||
height: dp(50)
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
width_margin: 1.33
|
||||
content_width: icon.width + label.texture_size[0] * self.width_margin
|
||||
MDFloatLayout:
|
||||
@@ -674,7 +657,7 @@
|
||||
size_hint: None, None
|
||||
font_size: root.font_size
|
||||
font_name: root.font_name
|
||||
color: WHITE
|
||||
color: Theme.MENU_ITEM_FONT_COLOR
|
||||
Label:
|
||||
text: root.shortcut
|
||||
halign: 'left'
|
||||
@@ -682,7 +665,7 @@
|
||||
size_hint_x: 1/3
|
||||
font_size: root.font_size
|
||||
font_name: root.font_name
|
||||
color: LIGHTGREY
|
||||
color: Theme.MENU_ITEM_SHORTCUT_COLOR
|
||||
|
||||
|
||||
|
||||
@@ -716,15 +699,15 @@
|
||||
|
||||
<AnalysisMenuItem@MenuItem>:
|
||||
on_close: app.gui.analysis_controls.close_dropdown()
|
||||
background_color: LIGHTER_BACKGROUND_COLOR
|
||||
background_color: Theme.LIGHTER_BACKGROUND_COLOR
|
||||
height: dp(45)
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: WHITE
|
||||
rgba: Theme.MENU_ITEM_FONT_COLOR
|
||||
Line:
|
||||
points: self.x,self.y, self.x,self.y+self.height
|
||||
Color:
|
||||
rgba: LIGHTGREY
|
||||
rgba: Theme.MENU_ITEM_SHORTCUT_COLOR
|
||||
Line
|
||||
points: self.x,self.y,self.x+self.width,self.y
|
||||
width: 1
|
||||
@@ -735,52 +718,52 @@
|
||||
katrain: app.gui
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:extra")
|
||||
icon: 'img/Extra.png'
|
||||
icon: 'Extra.png'
|
||||
shortcut: 'a'
|
||||
on_action: root.katrain("analyze-extra", "extra")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:equalize")
|
||||
icon: 'img/Equalize.png'
|
||||
icon: 'Equalize.png'
|
||||
shortcut: 's'
|
||||
on_action: root.katrain("analyze-extra", "equalize")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:sweep")
|
||||
icon: 'img/Sweep.png'
|
||||
icon: 'Sweep.png'
|
||||
shortcut: 'd'
|
||||
on_action: root.katrain("analyze-extra", "sweep")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:alternatives")
|
||||
icon: 'img/Alternative.png'
|
||||
icon: 'Alternative.png'
|
||||
shortcut: 'f'
|
||||
on_action: root.katrain("analyze-extra", "alternative")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:region")
|
||||
icon: 'img/local.png'
|
||||
icon: 'local.png'
|
||||
shortcut: 'g'
|
||||
on_action: root.katrain("select-box",)
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:insert")
|
||||
icon: 'img/Insert-Move.png'
|
||||
icon: 'Insert-Move.png'
|
||||
shortcut: 'i'
|
||||
on_action: root.katrain("insert-mode")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:playtoend")
|
||||
icon: 'img/Finish.png'
|
||||
icon: 'Finish.png'
|
||||
shortcut: 'l'
|
||||
on_action: root.katrain("play-to-end")
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:game")
|
||||
icon: 'img/analysis.png'
|
||||
icon: 'analysis.png'
|
||||
shortcut: ''
|
||||
on_action: root.open_game_analysis_popup()
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:continuous")
|
||||
icon: 'img/play.png'
|
||||
icon: 'play.png'
|
||||
shortcut: 'space'
|
||||
on_action: root.katrain.toggle_continuous_analysis()
|
||||
AnalysisMenuItem:
|
||||
text: i18n._("analysis:aimove")
|
||||
icon: 'img/ai.png'
|
||||
icon: 'ai.png'
|
||||
shortcut: 'enter'
|
||||
on_action: root.katrain("ai-move")
|
||||
|
||||
@@ -827,7 +810,7 @@
|
||||
width: analysis_button.width
|
||||
size_hint: None, 1
|
||||
AutoSizedRectangleButton:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
size_hint_y: 0.5
|
||||
pos_hint: {'center_y': 0.5, 'x': 0}
|
||||
id: analysis_button
|
||||
@@ -838,7 +821,7 @@
|
||||
x: self.parent.x + 2
|
||||
size_hint: None, 0.4
|
||||
width: self.height/2
|
||||
source: 'img/menu.png'
|
||||
source: 'menu.png'
|
||||
mipmap: True
|
||||
|
||||
|
||||
@@ -854,7 +837,7 @@
|
||||
|
||||
|
||||
<MenuLabel@BackgroundMixin+Label>:
|
||||
background_color: BACKGROUND_COLOR
|
||||
background_color: Theme.BACKGROUND_COLOR
|
||||
font_size: self.height * 0.5
|
||||
height: self.parent.item_height or 50
|
||||
size_hint: 1,None
|
||||
@@ -934,7 +917,7 @@
|
||||
<HamburgerMenuContents@MDBoxLayout+BackgroundMixin>:
|
||||
katrain: app.gui
|
||||
player_setup: player_setup
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
orientation: 'vertical'
|
||||
item_height: self.height/20
|
||||
MenuLabel:
|
||||
@@ -952,43 +935,43 @@
|
||||
item_height: root.item_height
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:newgame')
|
||||
icon: 'img/New-Game.png'
|
||||
icon: 'New-Game.png'
|
||||
shortcut: 'Ctrl-N'
|
||||
on_action: root.katrain("new-game-popup")
|
||||
height: root.item_height
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:save')
|
||||
icon: 'img/Save-Game.png'
|
||||
icon: 'Save-Game.png'
|
||||
shortcut: 'Ctrl-S'
|
||||
on_action: root.katrain("save-game")
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:save-as')
|
||||
icon: 'img/Save-Game-As.png'
|
||||
icon: 'Save-Game-As.png'
|
||||
shortcut: 'Ctrl-D'
|
||||
on_action: root.katrain("save-game-as-popup")
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:load')
|
||||
icon: 'img/Load-Game.png'
|
||||
icon: 'Load-Game.png'
|
||||
shortcut: 'Ctrl-L'
|
||||
on_action: root.katrain("analyze-sgf-popup")
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:clocksettings')
|
||||
icon: 'img/Time-Settings.png'
|
||||
icon: 'Time-Settings.png'
|
||||
shortcut: 'F5'
|
||||
on_action: root.katrain('timer-popup')
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:teachsettings')
|
||||
icon: 'img/Teaching-Settings.png'
|
||||
icon: 'Teaching-Settings.png'
|
||||
shortcut: 'F6'
|
||||
on_action: root.katrain('teacher-popup')
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:aisettings')
|
||||
icon: 'img/AI-Settings.png'
|
||||
icon: 'AI-Settings.png'
|
||||
shortcut: 'F7'
|
||||
on_action: root.katrain('ai-popup')
|
||||
MainMenuItem:
|
||||
text: i18n._('menu:settings')
|
||||
icon: 'img/General-Settings.png'
|
||||
icon: 'General-Settings.png'
|
||||
shortcut: 'F8'
|
||||
on_action: root.katrain('config-popup')
|
||||
MenuLabel:
|
||||
@@ -998,28 +981,28 @@
|
||||
height: 1.5 * root.item_height
|
||||
padding: CP_PADDING, 0
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-uk.png'
|
||||
icon: 'flags/flag-uk.png'
|
||||
on_press: app.language = 'en'
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-de.png'
|
||||
icon: 'flags/flag-de.png'
|
||||
on_press: app.language = 'de'
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-fr.png'
|
||||
icon: 'flags/flag-fr.png'
|
||||
on_press: app.language = 'fr'
|
||||
# LangButton:
|
||||
# icon: 'img/flags/flag-es.png'
|
||||
# icon: 'flags/flag-es.png'
|
||||
# on_press: app.language = 'es'
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-ru.png'
|
||||
icon: 'flags/flag-ru.png'
|
||||
on_press: app.language = 'ru'
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-cn.png'
|
||||
icon: 'flags/flag-cn.png'
|
||||
on_press: app.language = 'cn'
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-ko.png'
|
||||
icon: 'flags/flag-ko.png'
|
||||
on_press: app.language = 'ko'
|
||||
LangButton:
|
||||
icon: 'img/flags/flag-jp.png'
|
||||
icon: 'flags/flag-jp.png'
|
||||
on_press: app.language = 'jp'
|
||||
BoxLayout:
|
||||
size_hint: 1,None
|
||||
@@ -1037,10 +1020,10 @@
|
||||
|
||||
|
||||
<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
|
||||
inactive_background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
active_background_color: Theme.PLAY_ANALYZE_TAB_COLOR
|
||||
ripple_color: Theme.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
|
||||
group: 'play_analyze'
|
||||
@@ -1051,7 +1034,6 @@
|
||||
play: play
|
||||
analyze: analyze
|
||||
OutlineBox:
|
||||
outline_color: WHITE
|
||||
size_hint: 0.7,0.7
|
||||
pos_hint: {'center_x':0.5,'center_y':0.45}
|
||||
PlayAnalyzeButton:
|
||||
@@ -1079,7 +1061,7 @@
|
||||
Screen:
|
||||
name: 'gui'
|
||||
BGBoxLayout:
|
||||
background_color: BACKGROUND_COLOR
|
||||
background_color: Theme.BACKGROUND_COLOR
|
||||
MDBoxLayout:
|
||||
orientation: 'vertical'
|
||||
AnalysisControls:
|
||||
@@ -1116,7 +1098,3 @@
|
||||
on_state: if self.state=='close': root.update_state() # ai move etc on nav drawer close
|
||||
HamburgerMenuContents:
|
||||
id: nav_drawer_contents
|
||||
|
||||
|
||||
|
||||
|
||||
+67
-67
@@ -34,13 +34,13 @@ from katrain.core.lang import i18n
|
||||
from katrain.core.utils import evaluation_class, format_visits, var_to_grid
|
||||
from katrain.gui.kivyutils import draw_circle, draw_text, cached_texture
|
||||
from katrain.gui.popups import I18NPopup, ReAnalyzeGamePopup
|
||||
from katrain.gui.style import *
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
|
||||
class BadukPanWidget(Widget):
|
||||
def __init__(self, **kwargs):
|
||||
super(BadukPanWidget, self).__init__(**kwargs)
|
||||
self.stones_sounds = [SoundLoader.load(f"sounds/stone{i}.wav") for i in [1, 2, 3, 4, 5]]
|
||||
self.stones_sounds = [SoundLoader.load(file) for file in Theme.STONE_SOUNDS]
|
||||
self.trainer_config = {}
|
||||
self.ghost_stone = []
|
||||
self.gridpos_x = []
|
||||
@@ -208,16 +208,18 @@ class BadukPanWidget(Widget):
|
||||
Rectangle(
|
||||
pos=(self.gridpos_x[x] - stone_size, self.gridpos_y[y] - stone_size),
|
||||
size=(2 * stone_size, 2 * stone_size),
|
||||
texture=cached_texture(f"img/{player}_stone.png"),
|
||||
texture=cached_texture(Theme.STONE_TEXTURE[player]),
|
||||
)
|
||||
if evalcol:
|
||||
eval_radius = math.sqrt(evalscale) # scale area by evalscale
|
||||
evalsize = self.stone_size * (EVAL_DOT_MIN_SIZE + eval_radius * (EVAL_DOT_MAX_SIZE - EVAL_DOT_MIN_SIZE))
|
||||
evalsize = self.stone_size * (
|
||||
Theme.EVAL_DOT_MIN_SIZE + eval_radius * (Theme.EVAL_DOT_MAX_SIZE - Theme.EVAL_DOT_MIN_SIZE)
|
||||
)
|
||||
Color(*evalcol)
|
||||
Rectangle(
|
||||
pos=(self.gridpos_x[x] - evalsize, self.gridpos_y[y] - evalsize),
|
||||
size=(2 * evalsize, 2 * evalsize),
|
||||
texture=cached_texture("img/dot.png"),
|
||||
texture=cached_texture(Theme.EVAL_DOT_TEXTURE),
|
||||
)
|
||||
if innercol:
|
||||
Color(*innercol)
|
||||
@@ -225,12 +227,12 @@ class BadukPanWidget(Widget):
|
||||
Rectangle(
|
||||
pos=(self.gridpos_x[x] - inner_size, self.gridpos_y[y] - inner_size),
|
||||
size=(2 * inner_size, 2 * inner_size),
|
||||
texture=cached_texture("img/inner.png"),
|
||||
texture=cached_texture(Theme.LAST_MOVE_TEXTURE),
|
||||
)
|
||||
|
||||
def eval_color(self, points_lost, show_dots_for_class: List[bool] = None) -> Optional[List[float]]:
|
||||
i = evaluation_class(points_lost, self.trainer_config["eval_thresholds"])
|
||||
colors = EVAL_COLORS[self.trainer_config["theme"]]
|
||||
colors = Theme.EVAL_COLORS[self.trainer_config["theme"]]
|
||||
if show_dots_for_class is None or show_dots_for_class[i]:
|
||||
return colors[i]
|
||||
|
||||
@@ -256,7 +258,7 @@ class BadukPanWidget(Widget):
|
||||
board_height_with_margins = y_grid_spaces * self.grid_size
|
||||
extra_px_margin_x = (self.width - board_width_with_margins) / 2
|
||||
extra_px_margin_y = (self.height - board_height_with_margins) / 2
|
||||
self.stone_size = self.grid_size * STONE_SIZE
|
||||
self.stone_size = self.grid_size * Theme.STONE_SIZE
|
||||
|
||||
self.gridpos_x = [
|
||||
self.pos[0] + extra_px_margin_x + math.floor((grid_spaces_margin_x[0] + i) * self.grid_size + 0.5)
|
||||
@@ -268,19 +270,19 @@ class BadukPanWidget(Widget):
|
||||
]
|
||||
|
||||
if katrain.game.insert_mode:
|
||||
Color(1, 1, 1, 0.75) # dreamy
|
||||
Color(*Theme.INSERT_BOARD_COLOR_TINT) # dreamy
|
||||
else:
|
||||
Color(1, 0.95, 0.8, 1) # image is a bit too light
|
||||
Color(*Theme.BOARD_COLOR_TINT) # image is a bit too light
|
||||
Rectangle(
|
||||
pos=(
|
||||
self.gridpos_x[0] - self.grid_size * grid_spaces_margin_x[0],
|
||||
self.gridpos_y[0] - self.grid_size * grid_spaces_margin_y[0],
|
||||
),
|
||||
size=(self.grid_size * x_grid_spaces, self.grid_size * y_grid_spaces),
|
||||
texture=cached_texture("img/board.png"),
|
||||
texture=cached_texture(Theme.BOARD_TEXTURE),
|
||||
)
|
||||
|
||||
Color(*LINE_COLOR)
|
||||
Color(*Theme.LINE_COLOR)
|
||||
for i in range(board_size_x):
|
||||
Line(points=[(self.gridpos_x[i], self.gridpos_y[0]), (self.gridpos_x[i], self.gridpos_y[-1])])
|
||||
for i in range(board_size_y):
|
||||
@@ -295,10 +297,10 @@ class BadukPanWidget(Widget):
|
||||
[int(size / 2)] if size % 2 == 1 and size > 7 else []
|
||||
)
|
||||
|
||||
starpt_size = self.grid_size * STARPOINT_SIZE
|
||||
starpt_size = self.grid_size * Theme.STARPOINT_SIZE
|
||||
for x in star_point_coords(board_size_x):
|
||||
for y in star_point_coords(board_size_y):
|
||||
draw_circle((self.gridpos_x[x], self.gridpos_y[y]), starpt_size, LINE_COLOR)
|
||||
draw_circle((self.gridpos_x[x], self.gridpos_y[y]), starpt_size, Theme.LINE_COLOR)
|
||||
|
||||
# coordinates
|
||||
if self.draw_coords_enabled:
|
||||
@@ -365,7 +367,7 @@ class BadukPanWidget(Widget):
|
||||
evalcol = self.eval_color(points_lost, show_dots_for_class)
|
||||
else:
|
||||
evalcol = None
|
||||
inner = STONE_COLORS[m.opponent] if i == 0 and not m in placements else None
|
||||
inner = Theme.STONE_COLORS[m.opponent] if i == 0 and m not in placements else None
|
||||
drawn_stone[m.coords] = m.player
|
||||
self.draw_stone(
|
||||
x=m.coords[0],
|
||||
@@ -381,9 +383,9 @@ class BadukPanWidget(Widget):
|
||||
for y in range(0, board_size_y):
|
||||
evalcol = self.eval_color(16 * y / board_size_y)
|
||||
self.draw_stone(0, y, "B", evalcol=evalcol, evalscale=y / (board_size_y - 1))
|
||||
self.draw_stone(1, y, "B", innercol=STONE_COLORS["W"], evalcol=evalcol)
|
||||
self.draw_stone(1, y, "B", innercol=Theme.STONE_COLORS["W"], evalcol=evalcol)
|
||||
self.draw_stone(2, y, "W", evalcol=evalcol, evalscale=y / (board_size_y - 1))
|
||||
self.draw_stone(3, y, "W", innercol=STONE_COLORS["B"], evalcol=evalcol)
|
||||
self.draw_stone(3, y, "W", innercol=Theme.STONE_COLORS["B"], evalcol=evalcol)
|
||||
|
||||
# ownership - allow one move out of date for smooth animation
|
||||
ownership = current_node.ownership or (current_node.parent and current_node.parent.ownership)
|
||||
@@ -404,7 +406,7 @@ class BadukPanWidget(Widget):
|
||||
for x in range(board_size_x):
|
||||
loss = max(0, (-1 if current_node.children[-1].move.player == "B" else 1) * loss_grid[y][x])
|
||||
if loss > 0:
|
||||
Color(*EVAL_COLORS[self.trainer_config["theme"]][1][:3], loss)
|
||||
Color(*Theme.EVAL_COLORS[self.trainer_config["theme"]][1][:3], loss)
|
||||
Rectangle(
|
||||
pos=(self.gridpos_x[x] - rsz / 2, self.gridpos_y[y] - rsz / 2), size=(rsz, rsz)
|
||||
)
|
||||
@@ -414,7 +416,7 @@ class BadukPanWidget(Widget):
|
||||
for x in range(board_size_x):
|
||||
ix_owner = "B" if ownership_grid[y][x] > 0 else "W"
|
||||
if ix_owner != (has_stone.get((x, y), -1)):
|
||||
Color(*STONE_COLORS[ix_owner][:3], abs(ownership_grid[y][x]))
|
||||
Color(*Theme.STONE_COLORS[ix_owner][:3], abs(ownership_grid[y][x]))
|
||||
Rectangle(
|
||||
pos=(self.gridpos_x[x] - rsz / 2, self.gridpos_y[y] - rsz / 2), size=(rsz, rsz)
|
||||
)
|
||||
@@ -436,42 +438,41 @@ class BadukPanWidget(Widget):
|
||||
if katrain.analysis_controls.policy.active and policy:
|
||||
policy_grid = var_to_grid(policy, (board_size_x, board_size_y))
|
||||
best_move_policy = max(*policy)
|
||||
colors = EVAL_COLORS[self.trainer_config["theme"]]
|
||||
colors = Theme.EVAL_COLORS[self.trainer_config["theme"]]
|
||||
text_lb = 0.01 * 0.01
|
||||
for y in range(board_size_y - 1, -1, -1):
|
||||
for x in range(board_size_x):
|
||||
move_policy = policy_grid[y][x]
|
||||
pol_order = 5 - int(-math.log10(max(1e-9, move_policy - 1e-9)))
|
||||
if pol_order >= 0:
|
||||
if move_policy > text_lb:
|
||||
Color(0.95, 0.75, 0.47, 1)
|
||||
draw_circle(
|
||||
(self.gridpos_x[x], self.gridpos_y[y]),
|
||||
self.stone_size * HINT_SCALE * 0.98,
|
||||
[0.95, 0.75, 0.47, 1],
|
||||
)
|
||||
scale = 0.95
|
||||
else:
|
||||
scale = 0.5
|
||||
if move_policy < 0:
|
||||
continue
|
||||
pol_order = max(0, 5 + int(math.log10(max(1e-9, move_policy - 1e-9))))
|
||||
if move_policy > text_lb:
|
||||
draw_circle(
|
||||
(self.gridpos_x[x], self.gridpos_y[y]),
|
||||
HINT_SCALE * self.stone_size * scale,
|
||||
(*colors[pol_order][:3], POLICY_ALPHA),
|
||||
self.stone_size * Theme.HINT_SCALE * 0.98,
|
||||
Theme.APPROX_BOARD_COLOR,
|
||||
)
|
||||
scale = 0.95
|
||||
else:
|
||||
scale = 0.5
|
||||
draw_circle(
|
||||
(self.gridpos_x[x], self.gridpos_y[y]),
|
||||
Theme.HINT_SCALE * self.stone_size * scale,
|
||||
(*colors[pol_order][:3], Theme.POLICY_ALPHA),
|
||||
)
|
||||
if move_policy > text_lb:
|
||||
Color(*Theme.HINT_TEXT_COLOR)
|
||||
draw_text(
|
||||
pos=(self.gridpos_x[x], self.gridpos_y[y]),
|
||||
text=f"{100 * move_policy :.2f}"[:4] + "%",
|
||||
font_name="Roboto",
|
||||
halign="center",
|
||||
)
|
||||
if move_policy == best_move_policy:
|
||||
Color(*Theme.TOP_MOVE_BORDER_COLOR[:3], Theme.POLICY_ALPHA)
|
||||
Line(
|
||||
circle=(self.gridpos_x[x], self.gridpos_y[y], self.stone_size - dp(1.2),), width=dp(2),
|
||||
)
|
||||
if move_policy > text_lb:
|
||||
Color(*BLACK)
|
||||
draw_text(
|
||||
pos=(self.gridpos_x[x], self.gridpos_y[y]),
|
||||
text=f"{100 * move_policy :.2f}"[:4] + "%",
|
||||
font_name="Roboto",
|
||||
halign="center",
|
||||
)
|
||||
if move_policy == best_move_policy:
|
||||
Color(*TOP_MOVE_BORDER_COLOR[:3], POLICY_ALPHA)
|
||||
Line(
|
||||
circle=(self.gridpos_x[x], self.gridpos_y[y], self.stone_size - dp(1.2),),
|
||||
width=dp(2),
|
||||
)
|
||||
|
||||
with pass_btn.canvas.after:
|
||||
move_policy = policy[-1]
|
||||
@@ -480,7 +481,7 @@ class BadukPanWidget(Widget):
|
||||
draw_circle(
|
||||
(pass_btn.pos[0] + pass_btn.width / 2, pass_btn.pos[1] + pass_btn.height / 2),
|
||||
pass_btn.height / 2,
|
||||
(*colors[pol_order][:3], GHOST_ALPHA),
|
||||
(*colors[pol_order][:3], Theme.GHOST_ALPHA),
|
||||
)
|
||||
|
||||
# pass circle
|
||||
@@ -491,18 +492,18 @@ class BadukPanWidget(Widget):
|
||||
katrain.controls.timer.paused = True
|
||||
else:
|
||||
text = i18n._("board-pass")
|
||||
Color(0.45, 0.05, 0.45, 0.7)
|
||||
Color(*Theme.PASS_CIRCLE_COLOR)
|
||||
center = (self.gridpos_x[int(board_size_x / 2)], self.gridpos_y[int(board_size_y / 2)])
|
||||
size = min(self.width, self.height) * 0.227
|
||||
Ellipse(pos=(center[0] - size / 2, center[1] - size / 2), size=(size, size))
|
||||
Color(0.85, 0.85, 0.85)
|
||||
Color(*Theme.PASS_CIRCLE_TEXT_COLOR)
|
||||
draw_text(pos=center, text=text, font_size=size * 0.25, halign="center")
|
||||
|
||||
self.redraw_hover_contents_trigger()
|
||||
|
||||
def draw_roi_box(self, region_of_interest, width=2):
|
||||
xmin, xmax, ymin, ymax = region_of_interest
|
||||
Color(*LIGHTER_BACKGROUND_COLOR)
|
||||
Color(*Theme.REGION_BORDER_COLOR)
|
||||
Line(
|
||||
rectangle=(
|
||||
self.gridpos_x[xmin] - self.grid_size / 3,
|
||||
@@ -514,7 +515,7 @@ class BadukPanWidget(Widget):
|
||||
)
|
||||
|
||||
def draw_hover_contents(self, *_args):
|
||||
ghost_alpha = GHOST_ALPHA
|
||||
ghost_alpha = Theme.GHOST_ALPHA
|
||||
katrain = self.katrain
|
||||
game_ended = katrain.game.end_result
|
||||
current_node = katrain.game.current_node
|
||||
@@ -560,17 +561,17 @@ class BadukPanWidget(Widget):
|
||||
move = Move.from_gtp(move_dict["move"])
|
||||
if move.coords is not None:
|
||||
engine_best_move = move_dict.get("order", 99) == 0
|
||||
scale = HINT_SCALE
|
||||
scale = Theme.HINT_SCALE
|
||||
text_on = True
|
||||
alpha = HINTS_ALPHA
|
||||
alpha = Theme.HINTS_ALPHA
|
||||
if (
|
||||
move_dict["visits"] < low_visits_threshold
|
||||
and not engine_best_move
|
||||
and not move_dict["move"] in child_moves
|
||||
):
|
||||
scale = UNCERTAIN_HINT_SCALE
|
||||
scale = Theme.UNCERTAIN_HINT_SCALE
|
||||
text_on = False
|
||||
alpha = HINTS_LO_ALPHA
|
||||
alpha = Theme.HINTS_LO_ALPHA
|
||||
|
||||
if "pv" in move_dict:
|
||||
self.active_pv_moves.append((move.coords, move_dict["pv"], current_node))
|
||||
@@ -579,18 +580,17 @@ class BadukPanWidget(Widget):
|
||||
evalsize = self.stone_size * scale
|
||||
evalcol = self.eval_color(move_dict["pointsLost"])
|
||||
if text_on and top_moves_show: # remove grid lines using a board colored circle
|
||||
Color(0.95, 0.75, 0.47, 1)
|
||||
draw_circle(
|
||||
(self.gridpos_x[move.coords[0]], self.gridpos_y[move.coords[1]]),
|
||||
self.stone_size * scale * 0.98,
|
||||
[0.95, 0.75, 0.47, 1],
|
||||
Theme.APPROX_BOARD_COLOR,
|
||||
)
|
||||
|
||||
Color(*evalcol[:3], alpha)
|
||||
Rectangle(
|
||||
pos=(self.gridpos_x[move.coords[0]] - evalsize, self.gridpos_y[move.coords[1]] - evalsize),
|
||||
size=(2 * evalsize, 2 * evalsize),
|
||||
texture=cached_texture("img/topmove.png"),
|
||||
texture=cached_texture(Theme.TOP_MOVE_TEXTURE),
|
||||
)
|
||||
if text_on and top_moves_show: # TODO: faster if not sized?
|
||||
keys = {"size": self.grid_size / 3, "smallsize": self.grid_size / 3.33}
|
||||
@@ -614,7 +614,7 @@ class BadukPanWidget(Widget):
|
||||
keys[TOP_MOVE_WINRATE] = f"{winrate*100:.1f}"
|
||||
keys[TOP_MOVE_DELTA_WINRATE] = f"{-move_dict['winrateLost']:+.1%}"
|
||||
keys[TOP_MOVE_VISITS] = format_visits(move_dict["visits"])
|
||||
Color(*BLACK)
|
||||
Color(*Theme.HINT_TEXT_COLOR)
|
||||
draw_text(
|
||||
pos=(self.gridpos_x[move.coords[0]], self.gridpos_y[move.coords[1]]),
|
||||
text=fmt.format(**keys),
|
||||
@@ -626,7 +626,7 @@ class BadukPanWidget(Widget):
|
||||
|
||||
if engine_best_move:
|
||||
top_move_coords = move.coords
|
||||
Color(*TOP_MOVE_BORDER_COLOR)
|
||||
Color(*Theme.TOP_MOVE_BORDER_COLOR)
|
||||
Line(
|
||||
circle=(
|
||||
self.gridpos_x[move.coords[0]],
|
||||
@@ -648,7 +648,7 @@ class BadukPanWidget(Widget):
|
||||
|
||||
if move.coords != top_move_coords: # for contrast
|
||||
dashed_width = 18
|
||||
Color(*STONE_CONTRAST_COLORS[child_node.player])
|
||||
Color(*Theme.NEXT_MOVE_DASH_CONTRAST_COLORS[child_node.player])
|
||||
Line(
|
||||
circle=(
|
||||
self.gridpos_x[move.coords[0]],
|
||||
@@ -659,7 +659,7 @@ class BadukPanWidget(Widget):
|
||||
)
|
||||
else:
|
||||
dashed_width = 10
|
||||
Color(*STONE_COLORS[child_node.player])
|
||||
Color(*Theme.STONE_COLORS[child_node.player])
|
||||
for s in range(0, 360, 30):
|
||||
Line(
|
||||
circle=(
|
||||
@@ -727,9 +727,9 @@ class BadukPanWidget(Widget):
|
||||
Rectangle( # not sure why the -1 here, but seems to center better
|
||||
pos=(board_coords[0] - stone_size - 1, board_coords[1] - stone_size),
|
||||
size=(2 * stone_size + 1, 2 * stone_size + 1),
|
||||
texture=cached_texture(f"img/{move_player}_stone.png"),
|
||||
texture=cached_texture(Theme.STONE_TEXTURE[move_player]),
|
||||
)
|
||||
Color(*STONE_TEXT_COLORS[move_player])
|
||||
Color(*Theme.PV_TEXT_COLORS[move_player])
|
||||
draw_text(pos=board_coords, text=str(i + 1), font_size=self.grid_size * sizefac / 1.45, font_name="Roboto")
|
||||
|
||||
def set_animating_pv(self, pv, node):
|
||||
@@ -781,6 +781,6 @@ class AnalysisControls(MDBoxLayout):
|
||||
|
||||
|
||||
class BadukPanControls(MDFloatLayout):
|
||||
engine_status_col = ListProperty(ENGINE_DOWN_COL)
|
||||
engine_status_col = ListProperty(Theme.ENGINE_DOWN_COLOR)
|
||||
engine_status_pondering = NumericProperty(-1)
|
||||
queries_remaining = NumericProperty(0)
|
||||
@@ -2,7 +2,7 @@ import time
|
||||
|
||||
from kivy.clock import Clock
|
||||
from kivy.core.audio import SoundLoader
|
||||
from kivy.properties import NumericProperty, ObjectProperty, OptionProperty
|
||||
from kivy.properties import ObjectProperty, OptionProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivymd.uix.floatlayout import MDFloatLayout
|
||||
|
||||
|
||||
+11
-11
@@ -3,7 +3,7 @@ from kivy.core.image import Image
|
||||
from kivy.core.text import Label as CoreLabel
|
||||
from kivy.core.text.markup import MarkupLabel as CoreMarkupLabel
|
||||
from kivy.core.window import Window
|
||||
from kivy.graphics import *
|
||||
from kivy.graphics import Color, Ellipse, Rectangle
|
||||
from kivy.properties import (
|
||||
BooleanProperty,
|
||||
ListProperty,
|
||||
@@ -30,7 +30,7 @@ from kivymd.uix.textfield import MDTextField
|
||||
|
||||
from katrain.core.constants import AI_STRATEGIES_RECOMMENDED_ORDER, GAME_TYPES, MODE_PLAY, PLAYER_AI
|
||||
from katrain.core.lang import i18n
|
||||
from katrain.gui.style import DEFAULT_FONT, WHITE
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
|
||||
class BackgroundMixin(Widget): # -- mixins
|
||||
@@ -69,14 +69,14 @@ class LeftButtonBehavior(ButtonBehavior): # stops buttons etc activating on rig
|
||||
# -- resizeable buttons / avoid baserectangular for sizing
|
||||
class SizedButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedButton, BaseFlatButton, BackgroundMixin):
|
||||
text = StringProperty("")
|
||||
text_color = ListProperty(WHITE)
|
||||
text_color = ListProperty(Theme.BUTTON_TEXT_COLOR)
|
||||
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)
|
||||
_font_size = NumericProperty(None)
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
|
||||
|
||||
class AutoSizedButton(SizedButton):
|
||||
@@ -143,7 +143,7 @@ class StatsLabel(MDBoxLayout):
|
||||
label = StringProperty("")
|
||||
color = ListProperty([1, 1, 1, 1])
|
||||
hidden = BooleanProperty(False)
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
|
||||
|
||||
class MyNavigationDrawer(MDNavigationDrawer):
|
||||
@@ -214,7 +214,7 @@ class KeyValueSpinner(Spinner):
|
||||
sync_height_frac = NumericProperty(1.0)
|
||||
value_refs = ListProperty()
|
||||
selected_index = NumericProperty(0)
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -283,7 +283,7 @@ class I18NSpinner(KeyValueSpinner):
|
||||
sync_height_frac = NumericProperty(1.0)
|
||||
value_refs = ListProperty()
|
||||
selected_index = NumericProperty(0)
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -406,7 +406,7 @@ class TriStateMDCheckbox(MDCheckbox):
|
||||
class AnalysisToggle(MDBoxLayout):
|
||||
text = StringProperty("")
|
||||
default_active = BooleanProperty(False)
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
disabled = BooleanProperty(False)
|
||||
tri_state = BooleanProperty(False)
|
||||
|
||||
@@ -426,7 +426,7 @@ class MenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout, Backg
|
||||
icon = StringProperty("")
|
||||
text = StringProperty("")
|
||||
shortcut = StringProperty("")
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
content_width = NumericProperty(100)
|
||||
|
||||
def on_left_release(self):
|
||||
@@ -466,8 +466,8 @@ class CollapsablePanel(MDBoxLayout):
|
||||
closed_label = StringProperty("Closed Panel")
|
||||
|
||||
state = OptionProperty("open", options=["open", "close"])
|
||||
close_icon = "img/Previous-5.png"
|
||||
open_icon = "img/Next-5.png"
|
||||
close_icon = "Previous-5.png"
|
||||
open_icon = "Next-5.png"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.open_close_button, self.header = None, None
|
||||
|
||||
+10
-9
@@ -29,18 +29,19 @@ from katrain.core.constants import (
|
||||
OUTPUT_ERROR,
|
||||
OUTPUT_INFO,
|
||||
STATUS_INFO,
|
||||
DATA_FOLDER,
|
||||
)
|
||||
from katrain.core.engine import KataGoEngine
|
||||
from katrain.core.lang import i18n, rank_label
|
||||
from katrain.core.utils import PATHS, find_package_resource
|
||||
from katrain.gui.kivyutils import BackgroundMixin, I18NSpinner
|
||||
from katrain.gui.style import DEFAULT_FONT, EVAL_COLORS
|
||||
from katrain.gui.theme import Theme
|
||||
from katrain.gui.widgets.progress_loader import ProgressLoader
|
||||
|
||||
|
||||
class I18NPopup(Popup):
|
||||
title_key = StringProperty("")
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -326,14 +327,14 @@ class ConfigTeacherPopup(QuickConfigGui):
|
||||
savesgfs = self.katrain.config("trainer/save_feedback")
|
||||
show_dots = self.katrain.config("trainer/show_dots")
|
||||
|
||||
self.themes_spinner.value_refs = list(EVAL_COLORS.keys())
|
||||
self.themes_spinner.value_refs = list(Theme.EVAL_COLORS.keys())
|
||||
self.options_grid.clear_widgets()
|
||||
|
||||
for k in ["dot color", "point loss threshold", "num undos", "show dots", "save dots"]:
|
||||
self.options_grid.add_widget(DescriptionLabel(text=i18n._(k), font_name=i18n.font_name, font_size=dp(17)))
|
||||
|
||||
for i, (color, threshold, undo, show_dot, savesgf) in enumerate(
|
||||
zip(EVAL_COLORS[theme], thresholds, undos, show_dots, savesgfs)
|
||||
zip(Theme.EVAL_COLORS[theme], thresholds, undos, show_dots, savesgfs)
|
||||
):
|
||||
self.add_option_widgets(
|
||||
[
|
||||
@@ -420,8 +421,8 @@ class ConfigAIPopup(QuickConfigGui):
|
||||
class ConfigPopup(QuickConfigGui):
|
||||
def __init__(self, katrain):
|
||||
super().__init__(katrain)
|
||||
self.paths = [self.katrain.config("engine/model"), "katrain/models", "~/.katrain"]
|
||||
self.katago_paths = [self.katrain.config("engine/katago"), "~/.katrain"]
|
||||
self.paths = [self.katrain.config("engine/model"), "katrain/models", DATA_FOLDER]
|
||||
self.katago_paths = [self.katrain.config("engine/katago"), DATA_FOLDER]
|
||||
Clock.schedule_once(self.check_katas)
|
||||
MDApp.get_running_app().bind(language=self.check_models)
|
||||
MDApp.get_running_app().bind(language=self.check_katas)
|
||||
@@ -560,7 +561,7 @@ class ConfigPopup(QuickConfigGui):
|
||||
for name, url in self.MODELS.items():
|
||||
filename = os.path.split(url)[1]
|
||||
if not any(os.path.split(f)[1] == filename for f in self.model_files.values):
|
||||
savepath = os.path.expanduser(os.path.join("~/.katrain", filename))
|
||||
savepath = os.path.expanduser(os.path.join(DATA_FOLDER, filename))
|
||||
savepath_tmp = savepath + ".part"
|
||||
self.katrain.log(f"Downloading {name} model from {url} to {savepath_tmp}", OUTPUT_INFO)
|
||||
progress = ProgressLoader(
|
||||
@@ -627,8 +628,8 @@ class ConfigPopup(QuickConfigGui):
|
||||
filename = os.path.split(url)[1]
|
||||
exe_name = unzipped_name(filename)
|
||||
if not any(os.path.split(f)[1] == exe_name for f in self.katago_files.values):
|
||||
savepath_tmp = os.path.expanduser(os.path.join("~/.katrain", filename))
|
||||
exe_path_name = os.path.expanduser(os.path.join("~/.katrain", exe_name))
|
||||
savepath_tmp = os.path.expanduser(os.path.join(DATA_FOLDER, filename))
|
||||
exe_path_name = os.path.expanduser(os.path.join(DATA_FOLDER, exe_name))
|
||||
self.katrain.log(f"Downloading binary {name} from {url} to {savepath_tmp}", OUTPUT_INFO)
|
||||
progress = ProgressLoader(
|
||||
download_url=url,
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
def to_hexcol(kivycol):
|
||||
return "#" + "".join(f"{round(c * 255):02x}" for c in kivycol[:3])
|
||||
|
||||
|
||||
DEFAULT_FONT = "fonts/NotoSansCJKsc-Regular.otf"
|
||||
|
||||
# basic color definitions
|
||||
WHITE = [0.95, 0.95, 0.95, 1]
|
||||
BLACK = [0.05, 0.05, 0.05, 1]
|
||||
LIGHTGREY = [0.7, 0.7, 0.7, 1]
|
||||
GREY = [0.5, 0.5, 0.5, 1]
|
||||
LIGHTERGREY = [0.85, 0.85, 0.85, 1]
|
||||
|
||||
RED = [0.8, 0.1, 0.1, 1]
|
||||
GREEN = [0.1, 0.8, 0.1, 1]
|
||||
YELLOW = [0.8, 0.8, 0.1, 1]
|
||||
DARKRED = [0.3, 0.1, 0.1, 1]
|
||||
ORANGE = [242 / 255, 96 / 255, 34 / 255, 1]
|
||||
LIGHT_ORANGE = [1, 0.5, 0.25, 1]
|
||||
# gui colors
|
||||
BACKGROUND_COLOR = [36 / 255, 48 / 255, 62 / 255, 1]
|
||||
BOX_BACKGROUND_COLOR = [46 / 255, 65 / 255, 88 / 255, 1]
|
||||
LIGHTER_BACKGROUND_COLOR = [64 / 255, 85 / 255, 110 / 255, 1]
|
||||
TEXT_COLOR = WHITE
|
||||
|
||||
SCORE_COLOR = [0.3, 0.7, 0.9, 1]
|
||||
WINRATE_COLOR = GREEN
|
||||
POINTLOSS_COLOR = YELLOW
|
||||
|
||||
# eval dots
|
||||
EVAL_COLORS = {
|
||||
"theme:normal": [
|
||||
[0.447, 0.129, 0.42, 1],
|
||||
[0.8, 0, 0, 1],
|
||||
[0.9, 0.4, 0.1, 1],
|
||||
[0.95, 0.95, 0, 1],
|
||||
[0.67, 0.9, 0.18, 1],
|
||||
[0.117, 0.588, 0, 1],
|
||||
],
|
||||
"theme:red-green-colourblind": [
|
||||
[1, 0, 1, 1],
|
||||
[1, 0, 0, 1],
|
||||
[1, 0.5, 0, 1],
|
||||
[1, 1, 0, 1],
|
||||
[0, 1, 1, 1],
|
||||
[0, 0, 1, 1],
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
EVAL_DOT_MAX_SIZE = 0.5
|
||||
EVAL_DOT_MIN_SIZE = 0.25
|
||||
|
||||
STONE_COLORS = {"B": BLACK, "W": WHITE}
|
||||
STONE_CONTRAST_COLORS = {"B": LIGHTERGREY, "W": GREY}
|
||||
OUTLINE_COLORS = {"B": [0.3, 0.3, 0.3, 0.5], "W": [0.7, 0.7, 0.7, 0.5]}
|
||||
STONE_TEXT_COLORS = {"W": BLACK, "B": WHITE}
|
||||
|
||||
# board
|
||||
LINE_COLOR = [0, 0, 0]
|
||||
STARPOINT_SIZE = 0.1
|
||||
BOARD_COLOR = [0.85, 0.68, 0.40, 1]
|
||||
STONE_SIZE = 0.505 # texture edge is transparent
|
||||
|
||||
GHOST_ALPHA = 0.6
|
||||
POLICY_ALPHA = 0.5
|
||||
|
||||
HINTS_LO_ALPHA = 0.6
|
||||
HINTS_ALPHA = 0.8
|
||||
TOP_MOVE_BORDER_COLOR = [10 / 255, 200 / 255, 250 / 255, 1.0]
|
||||
CHILD_SCALE = 0.95
|
||||
HINT_SCALE = 0.98
|
||||
UNCERTAIN_HINT_SCALE = 0.7
|
||||
|
||||
|
||||
# ponder light
|
||||
ENGINE_DOWN_COL = EVAL_COLORS["theme:normal"][1]
|
||||
ENGINE_BUSY_COL = EVAL_COLORS["theme:normal"][2]
|
||||
ENGINE_READY_COL = EVAL_COLORS["theme:normal"][-1]
|
||||
|
||||
# info
|
||||
INFO_PV_COLOR = to_hexcol(YELLOW)
|
||||
@@ -0,0 +1,145 @@
|
||||
from kivy.metrics import sp
|
||||
|
||||
|
||||
def to_hexcol(kivycol):
|
||||
return "#" + "".join(f"{round(c * 255):02x}" for c in kivycol[:3])
|
||||
|
||||
|
||||
# basic colors
|
||||
WHITE = [0.95, 0.95, 0.95, 1]
|
||||
BLACK = [0.05, 0.05, 0.05, 1]
|
||||
LIGHT_GREY = [0.7, 0.7, 0.7, 1]
|
||||
GREY = [0.5, 0.5, 0.5, 1]
|
||||
LIGHTER_GREY = [0.85, 0.85, 0.85, 1]
|
||||
RED = [0.8, 0.1, 0.1, 1]
|
||||
GREEN = [0.1, 0.8, 0.1, 1]
|
||||
YELLOW = [0.8, 0.8, 0.1, 1]
|
||||
ORANGE = [242 / 255, 96 / 255, 34 / 255, 1]
|
||||
LIGHT_ORANGE = [1, 0.5, 0.25, 1]
|
||||
BLUE = [0.3, 0.7, 0.9, 1]
|
||||
|
||||
|
||||
class Theme:
|
||||
# font
|
||||
DEFAULT_FONT = "fonts/NotoSansCJKsc-Regular.otf"
|
||||
INPUT_FONT_SIZE = sp(25)
|
||||
DESC_FONT_SIZE = sp(20)
|
||||
NOTES_FONT_SIZE = sp(18)
|
||||
|
||||
# gui colors
|
||||
BACKGROUND_COLOR = [36 / 255, 48 / 255, 62 / 255, 1]
|
||||
BOX_BACKGROUND_COLOR = [46 / 255, 65 / 255, 88 / 255, 1]
|
||||
LIGHTER_BACKGROUND_COLOR = [64 / 255, 85 / 255, 110 / 255, 1]
|
||||
SCROLLBAR_COLOR = LIGHT_GREY
|
||||
TEXT_COLOR = WHITE
|
||||
SCORE_COLOR = BLUE # blue
|
||||
WINRATE_COLOR = GREEN # green
|
||||
POINTLOSS_COLOR = YELLOW # yellow
|
||||
BUTTON_INACTIVE_COLOR = LIGHT_GREY
|
||||
BUTTON_BORDER_COLOR = WHITE
|
||||
BUTTON_TEXT_COLOR = WHITE
|
||||
PAUSE_ACTIVE_COLOR = ORANGE
|
||||
TIMER_TEXT_COLOR = GREEN
|
||||
TIMER_TEXT_TIMEOUT_COLOR = ORANGE
|
||||
CIRCLE_TEXT_COLORS = {"W": BLACK, "B": WHITE}
|
||||
NOTES_TAB_FONT_COLOR = YELLOW
|
||||
INFO_TAB_FONT_COLOR = WHITE
|
||||
ERROR_BORDER_COLOR = RED
|
||||
MENU_ITEM_FONT_COLOR = WHITE
|
||||
MENU_ITEM_SHORTCUT_COLOR = LIGHT_GREY
|
||||
PLAY_ANALYZE_TAB_COLOR = YELLOW
|
||||
INPUT_FONT_COLOR = WHITE
|
||||
|
||||
# gui spacing
|
||||
CP_SPACING = 6
|
||||
CP_SMALL_SPACING = 3
|
||||
CP_PADDING = 6
|
||||
|
||||
# textures
|
||||
STONE_TEXTURE = {"B": "B_stone.png", "W": "W_stone.png"}
|
||||
EVAL_DOT_TEXTURE = "dot.png"
|
||||
LAST_MOVE_TEXTURE = "inner.png"
|
||||
TOP_MOVE_TEXTURE = "topmove.png"
|
||||
BOARD_TEXTURE = "board.png"
|
||||
GRAPH_TEXTURE = "graph_bg.png"
|
||||
# sounds
|
||||
STONE_SOUNDS = [f"stone{i}.wav" for i in [1, 2, 3, 4, 5]]
|
||||
|
||||
# eval dots
|
||||
EVAL_COLORS = {
|
||||
"theme:normal": [
|
||||
[0.447, 0.129, 0.42, 1],
|
||||
[0.8, 0, 0, 1],
|
||||
[0.9, 0.4, 0.1, 1],
|
||||
[0.95, 0.95, 0, 1],
|
||||
[0.67, 0.9, 0.18, 1],
|
||||
[0.117, 0.588, 0, 1],
|
||||
],
|
||||
"theme:red-green-colourblind": [
|
||||
[1, 0, 1, 1],
|
||||
[1, 0, 0, 1],
|
||||
[1, 0.5, 0, 1],
|
||||
[1, 1, 0, 1],
|
||||
[0, 1, 1, 1],
|
||||
[0, 0, 1, 1],
|
||||
],
|
||||
}
|
||||
|
||||
EVAL_DOT_MAX_SIZE = 0.5
|
||||
EVAL_DOT_MIN_SIZE = 0.25
|
||||
|
||||
# board theme
|
||||
APPROX_BOARD_COLOR = [0.95, 0.75, 0.47, 1] # for drawing on top of / hiding what's under it
|
||||
BOARD_COLOR_TINT = [1, 0.95, 0.8, 1] # multiplied by texture
|
||||
|
||||
HINT_TEXT_COLOR = BLACK
|
||||
|
||||
REGION_BORDER_COLOR = LIGHTER_BACKGROUND_COLOR
|
||||
INSERT_BOARD_COLOR_TINT = [1, 1, 1, 0.75]
|
||||
PASS_CIRCLE_COLOR = [0.45, 0.05, 0.45, 0.7]
|
||||
PASS_CIRCLE_TEXT_COLOR = [0.85, 0.85, 0.85]
|
||||
|
||||
STONE_COLORS = {"B": BLACK, "W": WHITE}
|
||||
NEXT_MOVE_DASH_CONTRAST_COLORS = {"B": LIGHTER_GREY, "W": GREY}
|
||||
OUTLINE_COLORS = {"B": [0.3, 0.3, 0.3, 0.5], "W": [0.7, 0.7, 0.7, 0.5]}
|
||||
PV_TEXT_COLORS = {"W": BLACK, "B": WHITE} # numbers in PV
|
||||
|
||||
# board
|
||||
LINE_COLOR = [0, 0, 0]
|
||||
STARPOINT_SIZE = 0.1
|
||||
BOARD_COLOR = [0.85, 0.68, 0.40, 1]
|
||||
STONE_SIZE = 0.505 # texture edge is transparent
|
||||
|
||||
GHOST_ALPHA = 0.6
|
||||
POLICY_ALPHA = 0.5
|
||||
|
||||
HINTS_LO_ALPHA = 0.6
|
||||
HINTS_ALPHA = 0.8
|
||||
TOP_MOVE_BORDER_COLOR = [10 / 255, 200 / 255, 250 / 255, 1.0]
|
||||
CHILD_SCALE = 0.95
|
||||
HINT_SCALE = 0.98
|
||||
UNCERTAIN_HINT_SCALE = 0.7
|
||||
|
||||
# ponder light
|
||||
ENGINE_DOWN_COLOR = EVAL_COLORS["theme:normal"][1]
|
||||
ENGINE_BUSY_COLOR = EVAL_COLORS["theme:normal"][2]
|
||||
ENGINE_READY_COLOR = EVAL_COLORS["theme:normal"][-1]
|
||||
ENGINE_PONDERING_COLOR = YELLOW
|
||||
|
||||
# info PV link
|
||||
INFO_PV_COLOR = to_hexcol(YELLOW)
|
||||
|
||||
# graph
|
||||
GRAPH_DOT_COLOR = [0.85, 0.3, 0.3, 1]
|
||||
WINRATE_MARKER_COLOR = [0.05, 0.7, 0.05, 1]
|
||||
SCORE_MARKER_COLOR = [0.2, 0.6, 0.8, 1]
|
||||
|
||||
# move tree
|
||||
MOVE_TREE_LINE = LIGHT_GREY
|
||||
MOVE_TREE_CURRENT = YELLOW
|
||||
MOVE_TREE_SELECTED = RED
|
||||
MOVE_TREE_INSERT_NODE_PARENT = GREEN
|
||||
MOVE_TREE_INSERT_CURRENT = ORANGE
|
||||
MOVE_TREE_INSERT_OTHER = LIGHT_ORANGE
|
||||
MOVE_TREE_COLLAPSED = LIGHT_GREY
|
||||
MOVE_TREE_STONE_OUTLINE_COLORS = {"W": BLACK, "B": WHITE}
|
||||
@@ -51,7 +51,7 @@ from kivy.uix.filechooser import FileChooserListLayout, FileChooserListView
|
||||
from kivy.uix.treeview import TreeView, TreeViewLabel
|
||||
from kivy.utils import platform
|
||||
|
||||
from katrain.gui.style import DEFAULT_FONT
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
if platform == "win":
|
||||
from ctypes import windll, create_unicode_buffer
|
||||
@@ -106,7 +106,7 @@ def get_drives():
|
||||
|
||||
|
||||
class I18NFileChooserListView(FileChooserListView):
|
||||
font_name = StringProperty(DEFAULT_FONT)
|
||||
font_name = StringProperty(Theme.DEFAULT_FONT)
|
||||
show_hidden = BooleanProperty(True) # avoid errors
|
||||
|
||||
|
||||
|
||||
@@ -7,10 +7,12 @@ from kivy.properties import BooleanProperty, Clock, ListProperty, NumericPropert
|
||||
from kivy.uix.widget import Widget
|
||||
from kivymd.app import MDApp
|
||||
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
|
||||
class Graph(Widget):
|
||||
marker_font_size = NumericProperty(0)
|
||||
background_image = StringProperty("img/graph_bg.png")
|
||||
background_image = StringProperty(Theme.GRAPH_TEXTURE)
|
||||
background_color = ListProperty([1, 1, 1, 1])
|
||||
highlighted_index = NumericProperty(0)
|
||||
nodes = ListProperty([])
|
||||
@@ -157,21 +159,10 @@ class ScoreGraph(Graph):
|
||||
|
||||
Builder.load_string(
|
||||
"""
|
||||
#:set GRAPH_CENTER_COLOR [0.5,0.5,0.5]
|
||||
#:set GRAPH_DOT_COLOR [0.85,0.3,0.3,1]
|
||||
#:set WINRATE_MARKER_COLOR [0.05, 0.7, 0.05, 1]
|
||||
#:set SCORE_MARKER_COLOR [0.2, 0.6, 0.8, 1]
|
||||
|
||||
#:import LIGHTER_BACKGROUND_COLOR katrain.gui.style.LIGHTER_BACKGROUND_COLOR
|
||||
#:import BOX_BACKGROUND_COLOR katrain.gui.style.BOX_BACKGROUND_COLOR
|
||||
#:import SCORE_COLOR katrain.gui.style.SCORE_COLOR
|
||||
#:import WINRATE_COLOR katrain.gui.style.WINRATE_COLOR
|
||||
#:import BLACK katrain.gui.style.BLACK
|
||||
#:import WHITE katrain.gui.style.WHITE
|
||||
#:import YELLOW katrain.gui.style.YELLOW
|
||||
#:import Theme katrain.gui.theme.Theme
|
||||
|
||||
<Graph>:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
marker_font_size: 0.1 * self.height
|
||||
canvas.before:
|
||||
Color:
|
||||
@@ -189,12 +180,12 @@ Builder.load_string(
|
||||
<ScoreGraph>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: SCORE_COLOR
|
||||
rgba: Theme.SCORE_COLOR
|
||||
Line:
|
||||
points: root.score_points if root.show_score else []
|
||||
width: dp(1.1)
|
||||
Color:
|
||||
rgba: WINRATE_COLOR
|
||||
rgba: Theme.WINRATE_COLOR
|
||||
Line:
|
||||
points: root.winrate_points if root.show_winrate else []
|
||||
width: dp(1.1)
|
||||
@@ -204,13 +195,13 @@ Builder.load_string(
|
||||
points: root.navigate_move[1], root.y, root.navigate_move[1], root.y+root.height
|
||||
width: 1
|
||||
Color:
|
||||
rgba: GRAPH_DOT_COLOR
|
||||
rgba: Theme.GRAPH_DOT_COLOR
|
||||
Ellipse:
|
||||
id: score_dot
|
||||
pos: [c - self.highlight_size / 2 for c in (self.score_dot_pos if not self.navigate_move[0] else [self.navigate_move[1],self.navigate_move[2]] ) ]
|
||||
size: (self.highlight_size,self.highlight_size) if root.show_score else (0.0001,0.0001)
|
||||
Color:
|
||||
rgba: GRAPH_DOT_COLOR
|
||||
rgba: Theme.GRAPH_DOT_COLOR
|
||||
Ellipse:
|
||||
id: winrate_dot
|
||||
pos: [c - self.highlight_size / 2 for c in (self.winrate_dot_pos if not self.navigate_move[0] else [self.navigate_move[1],self.navigate_move[3]] ) ]
|
||||
@@ -218,32 +209,32 @@ Builder.load_string(
|
||||
# score ticks
|
||||
GraphMarkerLabel:
|
||||
font_size: root.marker_font_size
|
||||
color: SCORE_MARKER_COLOR
|
||||
color: Theme.SCORE_MARKER_COLOR
|
||||
pos: root.x + root.width - self.width-1, root.pos[1]+root.height - self.font_size - 1
|
||||
text: 'B+{}'.format(root.score_scale)
|
||||
opacity: int(root.show_score)
|
||||
GraphMarkerLabel:
|
||||
font_size: root.marker_font_size
|
||||
color: SCORE_MARKER_COLOR
|
||||
color: Theme.SCORE_MARKER_COLOR
|
||||
pos: root.x + root.width - self.width-1, root.y + root.height*0.5 - self.height/2 + 2
|
||||
text: i18n._('Jigo')
|
||||
opacity: int(root.show_score)
|
||||
GraphMarkerLabel:
|
||||
font_size: root.marker_font_size
|
||||
color: SCORE_MARKER_COLOR
|
||||
color: Theme.SCORE_MARKER_COLOR
|
||||
pos: root.x + root.width - self.width-1, root.pos[1]
|
||||
text: 'W+' + str(int(root.score_scale))
|
||||
opacity: int(root.show_score)
|
||||
# wr ticks
|
||||
GraphMarkerLabel:
|
||||
font_size: root.marker_font_size
|
||||
color: WINRATE_MARKER_COLOR
|
||||
color: Theme.WINRATE_MARKER_COLOR
|
||||
pos: root.pos[0]+1, root.pos[1] + root.height - self.font_size - 1
|
||||
text: "{}%".format(50 + root.winrate_scale)
|
||||
opacity: int(root.show_winrate)
|
||||
GraphMarkerLabel:
|
||||
font_size: root.marker_font_size
|
||||
color: WINRATE_MARKER_COLOR
|
||||
color: Theme.WINRATE_MARKER_COLOR
|
||||
pos:root.pos[0]+1, root.pos[1]
|
||||
text: "{}%".format(50 - root.winrate_scale)
|
||||
opacity: int(root.show_winrate)
|
||||
|
||||
@@ -11,7 +11,7 @@ from kivy.uix.widget import Widget
|
||||
from kivymd.app import MDApp
|
||||
|
||||
from katrain.gui.kivyutils import BackgroundMixin, draw_circle, draw_text
|
||||
from katrain.gui.style import GREEN, LIGHT_ORANGE, LIGHTGREY, ORANGE, RED, STONE_COLORS, STONE_TEXT_COLORS, YELLOW
|
||||
from katrain.gui.theme import Theme
|
||||
|
||||
|
||||
class MoveTreeDropdown(DropDown):
|
||||
@@ -155,8 +155,8 @@ class MoveTreeCanvas(Widget):
|
||||
stack += children[move][::-1] # stack, so push top child last to process first
|
||||
|
||||
def draw_stone(pos, player, special_color=None):
|
||||
draw_circle(pos, self.move_size / 2 - 0.5, (special_color or STONE_COLORS[player]))
|
||||
Color(*STONE_TEXT_COLORS[player])
|
||||
draw_circle(pos, self.move_size / 2 - 0.5, (special_color or Theme.STONE_COLORS[player]))
|
||||
Color(*Theme.MOVE_TREE_STONE_OUTLINE_COLORS[player])
|
||||
Line(circle=(*pos, self.move_size / 2), width=1)
|
||||
|
||||
def coord_pos(coord):
|
||||
@@ -170,18 +170,20 @@ class MoveTreeCanvas(Widget):
|
||||
|
||||
self.move_xy_pos = {n: xy_pos(x, y) for n, (x, y) in self.move_pos.items()}
|
||||
|
||||
special_nodes = {current_node: YELLOW, self.menu_selected_node: RED}
|
||||
special_nodes = {current_node: Theme.MOVE_TREE_CURRENT, self.menu_selected_node: Theme.MOVE_TREE_SELECTED}
|
||||
|
||||
if insert_node:
|
||||
special_nodes[insert_node.parent] = GREEN
|
||||
special_nodes[insert_node.parent] = Theme.MOVE_TREE_INSERT_NODE_PARENT
|
||||
insert_path = current_node
|
||||
while insert_path != insert_node.parent and insert_path.parent:
|
||||
special_nodes[insert_path] = ORANGE if insert_path == current_node else LIGHT_ORANGE
|
||||
special_nodes[insert_path] = (
|
||||
Theme.MOVE_TREE_INSERT_CURRENT if insert_path == current_node else Theme.MOVE_TREE_INSERT_OTHER
|
||||
)
|
||||
insert_path = insert_path.parent
|
||||
|
||||
with self.canvas:
|
||||
self.canvas.clear()
|
||||
Color(*LIGHTGREY)
|
||||
Color(*Theme.MOVE_TREE_LINE)
|
||||
for node, (x, y) in self.move_xy_pos.items():
|
||||
for ci, c in enumerate(children[node]):
|
||||
cx, cy = self.move_xy_pos[c]
|
||||
@@ -194,10 +196,10 @@ class MoveTreeCanvas(Widget):
|
||||
pos=[c - self.move_size / 2 - spacing / 2 for c in self.move_xy_pos[node]],
|
||||
size=(self.move_size + spacing, self.move_size + spacing),
|
||||
)
|
||||
collapsed_color = LIGHTGREY if node.shortcut_from else None
|
||||
collapsed_color = Theme.MOVE_TREE_COLLAPSED if node.shortcut_from else None
|
||||
draw_stone(pos, node.player, collapsed_color)
|
||||
text = str(node.depth)
|
||||
Color(*STONE_COLORS["W" if node.player == "B" and not node.shortcut_from else "B"])
|
||||
Color(*Theme.STONE_COLORS["W" if node.player == "B" and not node.shortcut_from else "B"])
|
||||
draw_text(pos=pos, text=text, font_size=self.move_size * 1.75 / (1 + 1 * len(text)), font_name="Roboto")
|
||||
|
||||
if current_node in self.move_xy_pos:
|
||||
@@ -245,8 +247,11 @@ class MoveTree(ScrollView, BackgroundMixin):
|
||||
|
||||
Builder.load_string(
|
||||
"""
|
||||
#:import Theme katrain.gui.theme.Theme
|
||||
#:import WHITE katrain.gui.theme.WHITE
|
||||
#:import LIGHT_GREY katrain.gui.theme.LIGHT_GREY
|
||||
<MoveTree>:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
background_color: Theme.BOX_BACKGROUND_COLOR
|
||||
move_tree_canvas: move_tree_canvas
|
||||
scroll_distance: 0 # scroll wheel is for forward/backward
|
||||
MoveTreeCanvas:
|
||||
@@ -261,7 +266,7 @@ Builder.load_string(
|
||||
Line:
|
||||
points: self.x, self.y, self.x, self.y+self.height
|
||||
Color:
|
||||
rgba: LIGHTGREY
|
||||
rgba: LIGHT_GREY
|
||||
Line
|
||||
points: self.x,self.y,self.x+self.width,self.y
|
||||
width: 1
|
||||
@@ -270,27 +275,27 @@ Builder.load_string(
|
||||
katrain: app.gui
|
||||
MoveTreeDropdownItem:
|
||||
text: i18n._("Delete Node")
|
||||
icon: 'img/delete.png'
|
||||
icon: 'delete.png'
|
||||
shortcut: 'Ctrl+Del'
|
||||
on_action: root.katrain.controls.move_tree.delete_selected_node()
|
||||
-background_color: LIGHTER_BACKGROUND_COLOR
|
||||
-background_color: Theme.LIGHTER_BACKGROUND_COLOR
|
||||
-height: dp(45)
|
||||
-width_margin: 1.6
|
||||
MoveTreeDropdownItem:
|
||||
text: i18n._("Make Main Branch")
|
||||
icon: 'img/Branch.png'
|
||||
icon: 'Branch.png'
|
||||
shortcut: 'PgUp'
|
||||
on_action: root.katrain.controls.move_tree.make_selected_node_main_branch()
|
||||
-background_color: LIGHTER_BACKGROUND_COLOR
|
||||
-background_color: Theme.LIGHTER_BACKGROUND_COLOR
|
||||
-height: dp(45)
|
||||
-width_margin: 1.6
|
||||
MoveTreeDropdownItem:
|
||||
text: i18n._("Toggle Collapse Branch")
|
||||
icon: 'img/Collapse.png'
|
||||
icon: 'Collapse.png'
|
||||
shortcut: 'c'
|
||||
on_action: root.katrain.controls.move_tree.toggle_selected_node_collapse()
|
||||
-background_color: LIGHTER_BACKGROUND_COLOR
|
||||
-background_color: Theme.LIGHTER_BACKGROUND_COLOR
|
||||
-height: dp(45)
|
||||
-width_margin: 1.6
|
||||
"""
|
||||
"""
|
||||
)
|
||||
File renamed without changes.
File renamed without changes.
+33
-37
@@ -4,16 +4,12 @@
|
||||
#:import abspath os.path.abspath
|
||||
#:import kivy_version kivy.__version__
|
||||
|
||||
#:set CP_SPACING 6
|
||||
#:set CP_SMALL_SPACING 3
|
||||
#:set CP_PADDING 6
|
||||
#:import Theme katrain.gui.theme.Theme
|
||||
#:import LIGHT_GREY katrain.gui.theme.LIGHT_GREY
|
||||
|
||||
#:set INPUT_FONT_SIZE sp(25)
|
||||
#:set DESC_FONT_SIZE sp(20)
|
||||
|
||||
#:import BACKGROUND_COLOR katrain.gui.style.BACKGROUND_COLOR
|
||||
#:import LIGHTGREY katrain.gui.style.LIGHTGREY
|
||||
#:import TEXT_COLOR katrain.gui.style.TEXT_COLOR
|
||||
#:set CP_SPACING Theme.CP_SPACING
|
||||
#:set CP_SMALL_SPACING Theme.CP_SMALL_SPACING
|
||||
#:set CP_PADDING Theme.CP_PADDING
|
||||
|
||||
#:import TOP_MOVE_OPTIONS katrain.core.constants.TOP_MOVE_OPTIONS
|
||||
|
||||
@@ -22,15 +18,15 @@
|
||||
# hint_text: "Helper text on focus"
|
||||
# helper_text: "This will disappear when you click off"
|
||||
# helper_text_mode: "on_focus"
|
||||
# font_size: INPUT_FONT_SIZE
|
||||
# font_size: Theme.INPUT_FONT_SIZE
|
||||
|
||||
<LabelledTextInput>:
|
||||
font_size: INPUT_FONT_SIZE
|
||||
font_size: Theme.INPUT_FONT_SIZE
|
||||
helper_text_mode: "none"
|
||||
hint_text: ""
|
||||
helper_text: ""
|
||||
color_mode: 'custom'
|
||||
line_color_focus: TEXT_COLOR
|
||||
line_color_focus: Theme.TEXT_COLOR
|
||||
|
||||
<LabelledPathInput>:
|
||||
font_size: sp(16)
|
||||
@@ -39,27 +35,27 @@
|
||||
helper_text: i18n._("file not found")
|
||||
|
||||
<LabelledIntInput>:
|
||||
font_size: INPUT_FONT_SIZE
|
||||
font_size: Theme.INPUT_FONT_SIZE
|
||||
size_hint: 0.5, None
|
||||
|
||||
<LabelledFloatInput>:
|
||||
font_size: INPUT_FONT_SIZE
|
||||
font_size: Theme.INPUT_FONT_SIZE
|
||||
size_hint: 0.5, None
|
||||
|
||||
<LabelledCheckBox>:
|
||||
size: DESC_FONT_SIZE*2,DESC_FONT_SIZE*2
|
||||
size: Theme.DESC_FONT_SIZE*2,Theme.DESC_FONT_SIZE*2
|
||||
size_hint: None,None
|
||||
|
||||
<QuickInputButton@SizedRectangleButton>
|
||||
on_left_press: if self.target: self.target.text = self.text
|
||||
size: DESC_FONT_SIZE * 2, DESC_FONT_SIZE * 2
|
||||
font_size: DESC_FONT_SIZE
|
||||
size: Theme.DESC_FONT_SIZE * 2, Theme.DESC_FONT_SIZE * 2
|
||||
font_size: Theme.DESC_FONT_SIZE
|
||||
|
||||
<I18NPopup>:
|
||||
background_color: BACKGROUND_COLOR
|
||||
background_color: Theme.BACKGROUND_COLOR
|
||||
background: self.background if kivy_version < '2.0' else ''
|
||||
title: i18n._(self.title_key)
|
||||
title_size: DESC_FONT_SIZE
|
||||
title_size: Theme.DESC_FONT_SIZE
|
||||
title_font: self.font_name
|
||||
size_hint: None, None
|
||||
|
||||
@@ -69,14 +65,14 @@
|
||||
padding: 4*CP_PADDING,CP_PADDING, 4*CP_PADDING, CP_PADDING
|
||||
|
||||
<DescriptionLabel>:
|
||||
font_size: DESC_FONT_SIZE
|
||||
font_size: Theme.DESC_FONT_SIZE
|
||||
multiline: True
|
||||
text_size: self.width, None
|
||||
halign: 'center'
|
||||
valign: 'center'
|
||||
|
||||
<SmallDescriptionLabel@DescriptionLabel>
|
||||
font_size: DESC_FONT_SIZE * 0.66
|
||||
font_size: Theme.DESC_FONT_SIZE * 0.66
|
||||
|
||||
<ConfigPopup>:
|
||||
configfile: configfile
|
||||
@@ -88,7 +84,7 @@
|
||||
katago_download_progress_box: katago_download_progress_box
|
||||
DescriptionLabel:
|
||||
text: i18n._('katago settings')
|
||||
font_size: DESC_FONT_SIZE * 1.5
|
||||
font_size: Theme.DESC_FONT_SIZE * 1.5
|
||||
GridLayout:
|
||||
cols: 2
|
||||
rows: 6
|
||||
@@ -123,7 +119,7 @@
|
||||
size_hint_y: 0.7
|
||||
sync_height_frac: 1.0
|
||||
-font_size: self.height * 0.5
|
||||
-background_color: [*[c*255/88 for c in BOX_BACKGROUND_COLOR[:3]], 1] # compensate for texture
|
||||
-background_color: [*[c*255/88 for c in Theme.BOX_BACKGROUND_COLOR[:3]], 1] # compensate for texture
|
||||
DescriptionLabel:
|
||||
text: i18n._("engine:config")
|
||||
size_hint: 0.33, 1
|
||||
@@ -158,7 +154,7 @@
|
||||
size_hint_y: 0.7
|
||||
sync_height_frac: 1.0
|
||||
-font_size: self.height * 0.5
|
||||
-background_color: [*[c*255/88 for c in BOX_BACKGROUND_COLOR[:3]], 1] # compensate for texture
|
||||
-background_color: [*[c*255/88 for c in Theme.BOX_BACKGROUND_COLOR[:3]], 1] # compensate for texture
|
||||
DescriptionLabel:
|
||||
text: i18n._("engine:altcommand")
|
||||
size_hint: 0.33, 1
|
||||
@@ -171,9 +167,9 @@
|
||||
orientation: 'horizontal'
|
||||
DescriptionLabel:
|
||||
text: i18n._('general settings')
|
||||
font_size: DESC_FONT_SIZE * 1.5
|
||||
font_size: Theme.DESC_FONT_SIZE * 1.5
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 1.5
|
||||
font_size: Theme.DESC_FONT_SIZE * 1.5
|
||||
text: i18n._('engine settings')
|
||||
BoxLayout:
|
||||
size_hint: 1,5
|
||||
@@ -206,7 +202,7 @@
|
||||
id: configfile
|
||||
text: app.gui.config_file
|
||||
BackgroundMixin:
|
||||
background_color: LIGHTGREY
|
||||
background_color: LIGHT_GREY
|
||||
size_hint: None, 1
|
||||
width: 2
|
||||
GridLayout:
|
||||
@@ -281,7 +277,7 @@
|
||||
padding: 4
|
||||
size_hint: 0.95, 1
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
font_size: Theme.DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("theme")
|
||||
AnchorLayout:
|
||||
LabelledSpinner:
|
||||
@@ -289,7 +285,7 @@
|
||||
input_property: 'trainer/theme'
|
||||
id: themes_spinner
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
font_size: Theme.DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("stats on top move")
|
||||
AnchorLayout:
|
||||
BoxLayout:
|
||||
@@ -307,19 +303,19 @@
|
||||
value_refs: TOP_MOVE_OPTIONS
|
||||
input_property: "trainer/top_moves_show_secondary"
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
font_size: Theme.DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("show stats if")
|
||||
AnchorLayout:
|
||||
LabelledIntInput:
|
||||
input_property: "trainer/low_visits"
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
font_size: Theme.DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("show ai dots")
|
||||
AnchorLayout:
|
||||
LabelledCheckBox:
|
||||
input_property: "trainer/eval_show_ai"
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE * 0.8
|
||||
font_size: Theme.DESC_FONT_SIZE * 0.8
|
||||
text: i18n._("cache analysis to sgf")
|
||||
AnchorLayout:
|
||||
LabelledCheckBox:
|
||||
@@ -472,7 +468,7 @@
|
||||
LabelledSpinner:
|
||||
size_hint: 0.8,0.8
|
||||
input_property: 'game/rules'
|
||||
font_size: DESC_FONT_SIZE
|
||||
font_size: Theme.DESC_FONT_SIZE
|
||||
id: rules_spinner
|
||||
Label:
|
||||
DescriptionLabel:
|
||||
@@ -509,7 +505,7 @@
|
||||
size_hint: 2.25,1
|
||||
values: root.values
|
||||
on_change: textbox.text = str(slider.value)
|
||||
track_color: LIGHTGREY
|
||||
track_color: LIGHT_GREY
|
||||
thumb_color: (0.6, 0.7, 0.9, 1) if root.key_option else (0.3, 0.4, 0.6, 1)
|
||||
LabelledFloatInput:
|
||||
id: textbox
|
||||
@@ -522,7 +518,7 @@
|
||||
BoxLayout:
|
||||
size_hint: 1,1
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE
|
||||
font_size: Theme.DESC_FONT_SIZE
|
||||
text: i18n._('Select AI')
|
||||
AnchorLayout:
|
||||
I18NSpinner:
|
||||
@@ -531,12 +527,12 @@
|
||||
BoxLayout:
|
||||
size_hint: 1,1
|
||||
DescriptionLabel:
|
||||
font_size: DESC_FONT_SIZE
|
||||
font_size: Theme.DESC_FONT_SIZE
|
||||
size_hint: 1, 1
|
||||
text: i18n._('estimated strength')
|
||||
DescriptionLabel:
|
||||
size_hint: 0.8, 1
|
||||
font_size: DESC_FONT_SIZE
|
||||
font_size: Theme.DESC_FONT_SIZE
|
||||
id: estimated_rank_label
|
||||
text: '?' + i18n._('strength:kyu')
|
||||
SmallDescriptionLabel:
|
||||
|
||||
Reference in new issue
Block a user