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