Merge branch '1.7' of github.com:sanderland/katrain into 1.7

This commit is contained in:
Sander Land committed 2020-12-08 14:14:43 +01:00
commit 587109ae27
4 files changed
+52 -24

No files matched your search

+4 -4
View File
@@ -176,12 +176,12 @@ Keyboard shortcuts are shown with **[key]**.
In addition to shortcuts mentioned above and those shown in the main menu: In addition to shortcuts mentioned above and those shown in the main menu:
* **[Shift]**: Open the main menu. * **[Alt]**: Open the main menu.
* **[~]** or **[ ` ]** or **[f12]**: Cycles through more minimalistic UI modes. * **[~]** or **[ ` ]** or **[F12]**: Cycles through more minimalistic UI modes.
* **[p]**: Pass * **[p]**: Pass
* **[pause]**: Pause/Resume timer * **[pause]**: Pause/Resume timer
* **[arrow left]** or **[z]**: Undo move. Hold alt for 10 moves at a time, or ctrl to skip to the start. * **[arrow left]** or **[z]**: Undo move. Hold shift for 10 moves at a time, or ctrl to skip to the start.
* **[arrow right]** or **[x]**: Redo move. Hold alt for 10 moves at a time, or ctrl to skip to the end. * **[arrow right]** or **[x]**: Redo move. Hold shift for 10 moves at a time, or ctrl to skip to the end.
* **[arrow up/down]** Switch branch, as would be expected from the move tree. * **[arrow up/down]** Switch branch, as would be expected from the move tree.
* **[home/end]** Go to the beginning/end of the game. * **[home/end]** Go to the beginning/end of the game.
* **[pageup]** Make the currently selected node the main branch * **[pageup]** Make the currently selected node the main branch
+18 -4
View File
@@ -537,12 +537,11 @@ class KaTrainGui(Screen, KaTrainBase):
else: else:
return return
ctrl_pressed = "ctrl" in modifiers ctrl_pressed = "ctrl" in modifiers
alt_pressed = "alt" in modifiers
shift_pressed = "shift" in modifiers shift_pressed = "shift" in modifiers
shortcuts = self.shortcuts shortcuts = self.shortcuts
if keycode[1] == "tab": if keycode[1] == "tab":
self.play_mode.switch_ui_mode() self.play_mode.switch_ui_mode()
elif keycode[1] == "shift": elif keycode[1] == "alt":
self.nav_drawer.set_state("toggle") self.nav_drawer.set_state("toggle")
elif keycode[1] == "spacebar": elif keycode[1] == "spacebar":
self.toggle_continuous_analysis() self.toggle_continuous_analysis()
@@ -551,9 +550,9 @@ class KaTrainGui(Screen, KaTrainBase):
elif keycode[1] in ["`", "~", "f12"]: elif keycode[1] in ["`", "~", "f12"]:
self.zen = (self.zen + 1) % 3 self.zen = (self.zen + 1) % 3
elif keycode[1] in ["left", "z"]: elif keycode[1] in ["left", "z"]:
self("undo", 1 + (alt_pressed or shift_pressed) * 9 + (ctrl_pressed and not alt_pressed) * 999) self("undo", 1 + shift_pressed * 9 + ctrl_pressed * 999)
elif keycode[1] in ["right", "x"]: elif keycode[1] in ["right", "x"]:
self("redo", 1 + (alt_pressed or shift_pressed) * 9 + (ctrl_pressed and not alt_pressed) * 999) self("redo", 1 + shift_pressed * 9 + ctrl_pressed * 999)
elif keycode[1] == "home": elif keycode[1] == "home":
self("undo", 999) self("undo", 999)
elif keycode[1] == "end": elif keycode[1] == "end":
@@ -583,6 +582,19 @@ class KaTrainGui(Screen, KaTrainBase):
shortcut.trigger_action(duration=0) shortcut.trigger_action(duration=0)
else: else:
self(*shortcut) self(*shortcut)
elif keycode[1] == "f9" and self.debug_level >= OUTPUT_EXTRA_DEBUG:
import yappi
yappi.set_clock_type("cpu")
yappi.start()
self.log("starting profiler", OUTPUT_ERROR)
elif keycode[1] == "f10" and self.debug_level >= OUTPUT_EXTRA_DEBUG:
import yappi, time
stats = yappi.get_func_stats()
filename = f"callgrind.{int(time.time())}.prof"
stats.save(filename, type="callgrind")
self.log(f"wrote profiling results to {filename}", OUTPUT_ERROR)
return True return True
@@ -594,6 +606,7 @@ 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}"
@@ -604,6 +617,7 @@ 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"])
DEFAULT_FONT = resource_find(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)
+17 -16
View File
@@ -33,7 +33,7 @@ from katrain.core.constants import (
from katrain.core.game import Move from katrain.core.game import Move
from katrain.core.lang import i18n 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 BackgroundMixin, draw_circle, draw_text from katrain.gui.kivyutils import BackgroundMixin, 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.style import *
@@ -55,8 +55,9 @@ class BadukPanWidget(Widget):
self.animating_pv = None self.animating_pv = None
self.last_mouse_pos = (0, 0) self.last_mouse_pos = (0, 0)
Window.bind(mouse_pos=self.on_mouse_pos) Window.bind(mouse_pos=self.on_mouse_pos)
self.redraw_board_contents_trigger = Clock.create_trigger(self.draw_board_contents) self.redraw_board_contents_trigger = Clock.create_trigger(self.draw_board_contents, 0.05)
self.redraw_trigger = Clock.create_trigger(self.redraw) self.redraw_trigger = Clock.create_trigger(self.redraw, 0.05)
self.redraw_hover_contents_trigger = Clock.create_trigger(self.draw_hover_contents, 0.01)
self.bind(size=self.redraw_trigger, pos=self.redraw_trigger) self.bind(size=self.redraw_trigger, pos=self.redraw_trigger)
Clock.schedule_interval(self.animate_pv, 0.1) Clock.schedule_interval(self.animate_pv, 0.1)
@@ -81,7 +82,7 @@ class BadukPanWidget(Widget):
else: else:
self.ghost_stone = None self.ghost_stone = None
if prev_ghost != self.ghost_stone: if prev_ghost != self.ghost_stone:
self.draw_hover_contents() self.redraw_hover_contents_trigger()
def update_box_selection(self, touch, second_point=True): def update_box_selection(self, touch, second_point=True):
if not self.gridpos_x: if not self.gridpos_x:
@@ -93,7 +94,7 @@ class BadukPanWidget(Widget):
self.region_of_interest[3] = yp self.region_of_interest[3] = yp
else: else:
self.region_of_interest = [xp, xp, yp, yp] self.region_of_interest = [xp, xp, yp, yp]
self.draw_hover_contents() self.redraw_hover_contents_trigger()
def on_touch_down(self, touch): def on_touch_down(self, touch):
self.set_animating_pv(None, None) # any click kills PV from label/move self.set_animating_pv(None, None) # any click kills PV from label/move
@@ -186,7 +187,7 @@ class BadukPanWidget(Widget):
self.set_animating_pv(nodes_here[-1].parent.candidate_moves[0]["pv"], nodes_here[-1].parent) self.set_animating_pv(nodes_here[-1].parent.candidate_moves[0]["pv"], nodes_here[-1].parent)
self.ghost_stone = None self.ghost_stone = None
self.draw_hover_contents() # remove ghost self.redraw_hover_contents_trigger() # remove ghost
# drawing functions # drawing functions
def redraw(self, *_args): def redraw(self, *_args):
@@ -199,7 +200,7 @@ 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),
source=f"img/{player}_stone.png", texture=cached_texture(f"img/{player}_stone.png"),
) )
if evalcol: if evalcol:
eval_radius = math.sqrt(evalscale) # scale area by evalscale eval_radius = math.sqrt(evalscale) # scale area by evalscale
@@ -208,7 +209,7 @@ class BadukPanWidget(Widget):
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),
source=f"img/dot.png", texture=cached_texture(f"img/dot.png"),
) )
if innercol: if innercol:
Color(*innercol) Color(*innercol)
@@ -216,7 +217,7 @@ 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),
source=f"img/inner.png", texture=cached_texture(f"img/inner.png"),
) )
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]]:
@@ -261,7 +262,7 @@ class BadukPanWidget(Widget):
Rectangle( Rectangle(
pos=(self.gridpos_x[0] - self.grid_size * 1.5, self.gridpos_y[0] - self.grid_size * 1.5), pos=(self.gridpos_x[0] - self.grid_size * 1.5, self.gridpos_y[0] - self.grid_size * 1.5),
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),
source="img/board.png", texture=cached_texture("img/board.png"),
) )
Color(*LINE_COLOR) Color(*LINE_COLOR)
@@ -455,7 +456,7 @@ class BadukPanWidget(Widget):
pos=center, text=text, font_size=size * 0.25, halign="center", outline_color=[0.95, 0.95, 0.95] pos=center, text=text, font_size=size * 0.25, halign="center", outline_color=[0.95, 0.95, 0.95]
) )
self.draw_hover_contents() 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
@@ -547,9 +548,9 @@ class BadukPanWidget(Widget):
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),
source="img/topmove.png", texture=cached_texture("img/topmove.png"),
) )
if text_on and top_moves_show: 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}
player_sign = current_node.player_sign(current_node.next_player) player_sign = current_node.player_sign(current_node.next_player)
if len(top_moves_show) == 1: if len(top_moves_show) == 1:
@@ -649,7 +650,7 @@ class BadukPanWidget(Widget):
def animate_pv(self, _dt): def animate_pv(self, _dt):
if self.animating_pv: if self.animating_pv:
self.draw_hover_contents() self.redraw_hover_contents_trigger()
def draw_pv(self, pv, node, up_to_move): def draw_pv(self, pv, node, up_to_move):
katrain = self.katrain katrain = self.katrain
@@ -684,7 +685,7 @@ 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),
source=f"img/{move_player}_stone.png", texture=cached_texture(f"img/{move_player}_stone.png"),
) )
Color(*STONE_TEXT_COLORS[move_player]) Color(*STONE_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")
@@ -696,7 +697,7 @@ class BadukPanWidget(Widget):
not self.animating_pv or not (self.animating_pv[0] == pv and self.animating_pv[1] == node) not self.animating_pv or not (self.animating_pv[0] == pv and self.animating_pv[1] == node)
): ):
self.animating_pv = (pv, node, time.time(), self.last_mouse_pos) self.animating_pv = (pv, node, time.time(), self.last_mouse_pos)
self.draw_hover_contents() self.redraw_hover_contents_trigger()
def show_pv_from_comments(self, pv_str): def show_pv_from_comments(self, pv_str):
self.set_animating_pv(pv_str[1:].split(" "), self.katrain.controls.active_comment_node.parent) self.set_animating_pv(pv_str[1:].split(" "), self.katrain.controls.active_comment_node.parent)
+13
View File
@@ -1,4 +1,8 @@
import functools
from kivy.cache import Cache
from kivy.clock import Clock from kivy.clock import Clock
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
@@ -11,6 +15,7 @@ from kivy.properties import (
OptionProperty, OptionProperty,
StringProperty, StringProperty,
) )
from kivy.resources import resource_find
from kivy.uix.behaviors import ButtonBehavior, FocusBehavior, ToggleButtonBehavior from kivy.uix.behaviors import ButtonBehavior, FocusBehavior, ToggleButtonBehavior
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button from kivy.uix.button import Button
@@ -623,3 +628,11 @@ def draw_text(pos, text, font_name=None, markup=False, **kw):
def draw_circle(pos, r, col): def draw_circle(pos, r, col):
Color(*col) Color(*col)
Ellipse(pos=(pos[0] - r, pos[1] - r), size=(2 * r, 2 * r)) Ellipse(pos=(pos[0] - r, pos[1] - r), size=(2 * r, 2 * r))
# direct cache to texture, bypassing resource_find
def cached_texture(path,_cache={}):
tex = _cache.get(path)
if not tex:
tex = _cache[path] = Image(resource_find(path)).texture
return tex