Merge pull request #114 from sanderland/pixels
Minor UI rescaling/fixing + player name/rank
This commit is contained in:
9 files changed
+91
-57
No files matched your search
@@ -61,6 +61,8 @@ from katrain.core.constants import (
|
||||
VERSION,
|
||||
STATUS_ERROR,
|
||||
STATUS_INFO,
|
||||
PLAYING_NORMAL,
|
||||
PLAYER_HUMAN,
|
||||
)
|
||||
from katrain.gui.popups import ConfigTeacherPopup, ConfigTimerPopup, I18NPopup
|
||||
from katrain.core.base_katrain import KaTrainBase
|
||||
@@ -243,6 +245,14 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
self.board_gui.animating_pv = None
|
||||
self.engine.on_new_game() # clear queries
|
||||
self.game = Game(self, self.engine, move_tree=move_tree, analyze_fast=analyze_fast)
|
||||
if move_tree:
|
||||
for bw, player_info in self.players_info.items():
|
||||
player_info.player_type = PLAYER_HUMAN
|
||||
player_info.player_subtype = PLAYING_NORMAL
|
||||
player_info.sgf_rank = move_tree.root.get_property(bw + "R")
|
||||
player_info.calculated_rank = None
|
||||
player_info.name = move_tree.root.get_property("P" + bw)
|
||||
self.update_player(bw)
|
||||
self.controls.graph.initialize_from_game(self.game.root)
|
||||
self.update_state(redraw_board=True)
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ from katrain.core.utils import find_package_resource
|
||||
class Player:
|
||||
def __init__(self, player="B", player_type=PLAYER_HUMAN, player_subtype=PLAYING_NORMAL, periods_used=0):
|
||||
self.player = player
|
||||
self.sgf_rank = None
|
||||
self.calculated_rank = None
|
||||
self.name = ""
|
||||
self.update(player_type, player_subtype)
|
||||
self.periods_used = periods_used
|
||||
|
||||
|
||||
+55
-35
@@ -4,6 +4,8 @@
|
||||
#:import PLAYER_TYPES katrain.core.constants.PLAYER_TYPES
|
||||
#:import PLAYER_HUMAN katrain.core.constants.PLAYER_HUMAN
|
||||
#:import PLAYER_AI katrain.core.constants.PLAYER_AI
|
||||
#:import PLAYING_NORMAL katrain.core.constants.PLAYING_NORMAL
|
||||
#:import PLAYING_TEACHING katrain.core.constants.PLAYING_TEACHING
|
||||
#:import MODE_PLAY katrain.core.constants.MODE_PLAY
|
||||
#:import MODE_ANALYZE katrain.core.constants.MODE_ANALYZE
|
||||
#:import STATUS_INFO katrain.core.constants.STATUS_INFO
|
||||
@@ -32,6 +34,8 @@
|
||||
#:set CP_PADDING dp(6)
|
||||
#:set NOTES_FONT_SIZE dp(18)
|
||||
|
||||
#:set EPSILON 1e-9
|
||||
|
||||
# for sizing help
|
||||
#<Label>:
|
||||
# canvas.before:
|
||||
@@ -53,7 +57,7 @@
|
||||
Color:
|
||||
rgba: root.outline_color
|
||||
Line:
|
||||
rounded_rectangle: (*self.pos,self.width,self.height,root.background_radius,root.background_radius,root.background_radius,root.background_radius,max(1,root.height))
|
||||
rounded_rectangle: (self.x + root.outline_width, self.y + root.outline_width, self.width - 2 * root.outline_width, self.height - 2*root.outline_width, root.background_radius,root.background_radius,root.background_radius,root.background_radius,max(1,root.height))
|
||||
width: root.outline_width or 1
|
||||
|
||||
|
||||
@@ -272,20 +276,29 @@
|
||||
CircleWithText:
|
||||
player: root.player
|
||||
text: str(root.captures)
|
||||
size_hint: 0.25, 1
|
||||
MDBoxLayout:
|
||||
size_hint: 0.32, 1
|
||||
BoxLayout:
|
||||
size_hint: 0.75, 1
|
||||
pos_hint: {'x':0,'y':0}
|
||||
size_hint: 1,1
|
||||
orientation: 'vertical'
|
||||
spacing: CP_SPACING
|
||||
Label:
|
||||
text: i18n._(root.player_type)
|
||||
size_hint: 1,0.55
|
||||
size_hint: 1,0.6
|
||||
text: i18n._(root.player_type)
|
||||
font_size: 0.8 * self.height
|
||||
size: self.texture_size
|
||||
max_lines: 1
|
||||
halign: 'center'
|
||||
valign: 'middle'
|
||||
Label:
|
||||
text: i18n._(root.player_subtype)
|
||||
size_hint: 1,0.45
|
||||
text: (root.name if root.name and root.player_type==PLAYER_HUMAN and root.player_subtype == PLAYING_NORMAL else i18n._(root.player_subtype) ) + (" ({})".format(root.rank) if root.rank and root.player_subtype != PLAYING_TEACHING else "")
|
||||
size_hint: 1,0.4
|
||||
font_size: 0.7 * self.height
|
||||
|
||||
text_size: self.size
|
||||
halign: 'center'
|
||||
valign: 'middle'
|
||||
shorten: True
|
||||
shorten_from: 'right'
|
||||
|
||||
<PauseButton>:
|
||||
height: self.width
|
||||
@@ -327,7 +340,7 @@
|
||||
timeout: False
|
||||
color: ORANGE if self.timeout else GREEN
|
||||
markup: True
|
||||
multiline: False
|
||||
max_lines: 1
|
||||
font_name: 'fonts/digital-7 (mono).ttf'
|
||||
|
||||
<Timer>:
|
||||
@@ -370,7 +383,7 @@
|
||||
valign: 'top'
|
||||
id: periods
|
||||
text: str(root.state[1])
|
||||
multiline: False
|
||||
max_lines: 1
|
||||
timeout: root.timeout
|
||||
MDBoxLayout:
|
||||
size_hint: 0.2,1
|
||||
@@ -391,28 +404,30 @@
|
||||
|
||||
|
||||
<StatsLabel>:
|
||||
value : value
|
||||
orientation: 'horizontal'
|
||||
size_hint_y: EPSILON if root.hidden else 1
|
||||
opacity: 0 if root.hidden else 1
|
||||
Label:
|
||||
size_hint: 0.6,1
|
||||
id: desc
|
||||
text: root.label if not root.hidden else ''
|
||||
font_size: self.height * 0.7
|
||||
font_name: root.font_name
|
||||
text_size: self.size
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
text: root.label
|
||||
max_lines: 1
|
||||
Label:
|
||||
size_hint: 0.4,1
|
||||
text: root.text if not root.hidden else ''
|
||||
color: root.color
|
||||
font_size: desc.font_size
|
||||
font_name: root.font_name
|
||||
text_size: self.size
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
id: value
|
||||
bold: True
|
||||
text: root.text
|
||||
max_lines: 1
|
||||
|
||||
<StatsBox>
|
||||
orientation: 'vertical'
|
||||
@@ -475,7 +490,7 @@
|
||||
rgba: BOX_BACKGROUND_COLOR
|
||||
Line:
|
||||
width: 1
|
||||
points: (*self.pos,self.x+self.width,self.y)
|
||||
points: (self.x,self.y+1,self.x+self.width,self.y+1)
|
||||
|
||||
|
||||
<ControlsPanel>:
|
||||
@@ -492,13 +507,14 @@
|
||||
status: status
|
||||
timer_or_movetree: timer_or_movetree
|
||||
move_tree: move_tree
|
||||
padding: CP_PADDING
|
||||
padding: CP_PADDING,CP_PADDING,CP_PADDING,0
|
||||
spacing: CP_SPACING
|
||||
player_box_height: max(50, 0.075 * root.height)
|
||||
timer_box_height: max(50, 0.1 * root.height)
|
||||
graph_height: max(75, 0.2 * root.height - 25)
|
||||
stats_box_height: max(50, 0.15 * root.height)
|
||||
tab_option_height: max(15,root.height / 30)
|
||||
available_height: root.height - (3 * self.tab_option_height + 2*CP_PADDING - 4*CP_SPACING) # minus tabs fixed, spacing etc
|
||||
player_box_height: max(50, 0.08 * root.available_height)
|
||||
timer_box_height: max(50, 0.11 * root.available_height)
|
||||
graph_height: max(75, 0.17 * root.height)
|
||||
stat_height: max(20, 0.035 * root.height)
|
||||
BoxLayout: # -- Players
|
||||
size_hint_y: None
|
||||
height: root.player_box_height
|
||||
@@ -513,7 +529,7 @@
|
||||
size_hint_y: None
|
||||
height: root.timer_box_height
|
||||
BoxLayout:
|
||||
size_hint_x: 0.0001 if self.parent.mode != MODE_PLAY else 1
|
||||
size_hint_x: EPSILON if self.parent.mode != MODE_PLAY else 1
|
||||
opacity: 0 if self.parent.mode != MODE_PLAY else 1
|
||||
spacing: CP_SPACING
|
||||
Timer:
|
||||
@@ -534,16 +550,16 @@
|
||||
on_left_release: root.katrain("undo","smart")
|
||||
MoveTree:
|
||||
id: move_tree
|
||||
size_hint_x: 0.0001 if self.parent.mode == MODE_PLAY else 1
|
||||
size_hint_x: EPSILON if self.parent.mode == MODE_PLAY else 1
|
||||
opacity: 0 if self.parent.mode == MODE_PLAY else 1
|
||||
CollapsablePanel:
|
||||
id: graph_panel
|
||||
height_open: self.header.height + graph.height + rank_graph.height
|
||||
content_height: graph.height + rank_graph.height
|
||||
options_height: root.tab_option_height
|
||||
closed_label: 'closedlabel:scoregraph'
|
||||
options: ['score','winrate','rank_est']
|
||||
option_colors: [SCORE_COLOR,WINRATE_COLOR,POINTLOSS_COLOR]
|
||||
option_active: [True,False,False]
|
||||
options_height: root.tab_option_height
|
||||
on_option_state:
|
||||
graph.show_graphs(args[1])
|
||||
graph.hidden = not (args[1]['score'] or args[1]['winrate'])
|
||||
@@ -553,21 +569,24 @@
|
||||
id: graph
|
||||
opacity: 0 if self.hidden else 1
|
||||
size_hint_y: None
|
||||
height: 0.0001 if self.hidden else root.graph_height
|
||||
height: EPSILON if self.hidden else root.graph_height
|
||||
RankGraph:
|
||||
id: rank_graph
|
||||
opacity: 0 if self.hidden else 1
|
||||
size_hint_y: None
|
||||
height: 0.0001 if self.hidden else root.graph_height
|
||||
height: EPSILON if self.hidden else root.graph_height
|
||||
CollapsablePanel:
|
||||
id: stats_panel
|
||||
height_open: root.stats_box_height
|
||||
num_active: 3
|
||||
content_height: self.num_active * root.stat_height + EPSILON
|
||||
options_height: root.tab_option_height
|
||||
closed_label: 'closedlabel:movestats'
|
||||
options: ['score','winrate','points']
|
||||
option_colors: [SCORE_COLOR,WINRATE_COLOR,POINTLOSS_COLOR]
|
||||
option_active: [True,True,True]
|
||||
options_height: root.tab_option_height
|
||||
on_option_state: for k, v in args[1].items(): stats.labels[k].hidden = not v
|
||||
on_option_state:
|
||||
for k, v in args[1].items(): stats.labels[k].hidden = not v
|
||||
self.num_active = sum(args[1].values(),0)
|
||||
StatsBox:
|
||||
id: stats
|
||||
CollapsablePanel:
|
||||
@@ -590,10 +609,11 @@
|
||||
orientation: 'vertical'
|
||||
ScrollableLabel:
|
||||
id: status
|
||||
error: False
|
||||
size_hint: 1, None
|
||||
height: min(self.parent.height*0.66,self.label.texture_size[1])
|
||||
outline_color: RED
|
||||
background_color: DARKRED
|
||||
outline_color: RED if self.error else WHITE
|
||||
background_color: LIGHTER_BACKGROUND_COLOR # DARKRED
|
||||
ScrollableLabel:
|
||||
id: info
|
||||
detailed: False
|
||||
@@ -803,7 +823,7 @@
|
||||
icon_size: self.height * 0.75, self.height * 0.75
|
||||
|
||||
|
||||
<MenuLabel@Label+BackgroundMixin>:
|
||||
<MenuLabel@BackgroundMixin+Label>:
|
||||
background_color: BACKGROUND_COLOR
|
||||
font_size: self.height * 0.5
|
||||
height: self.parent.item_height or 50
|
||||
@@ -844,7 +864,7 @@
|
||||
MDBoxLayout:
|
||||
orientation: 'vertical'
|
||||
spacing: CP_SPACING
|
||||
size_hint_x: 1 if root.mode != PLAYER_AI else 0.0001
|
||||
size_hint_x: 1 if root.mode != PLAYER_AI else EPSILON
|
||||
opacity:1 if root.mode != PLAYER_AI else 0
|
||||
Label:
|
||||
text: i18n._("gametype")
|
||||
@@ -857,7 +877,7 @@
|
||||
MDBoxLayout:
|
||||
orientation: 'vertical'
|
||||
spacing: CP_SPACING
|
||||
size_hint_x: 1 if root.mode == PLAYER_AI else 0.0001
|
||||
size_hint_x: 1 if root.mode == PLAYER_AI else EPSILON
|
||||
opacity: 1 if root.mode == PLAYER_AI else 0
|
||||
Label:
|
||||
text: i18n._("aistrategy")
|
||||
|
||||
@@ -8,7 +8,7 @@ from kivy.core.window import Window
|
||||
from kivy.graphics.context_instructions import Color
|
||||
from kivy.graphics.vertex_instructions import Ellipse, Line, Rectangle
|
||||
from kivy.metrics import dp
|
||||
from kivy.properties import ListProperty, ObjectProperty, BooleanProperty
|
||||
from kivy.properties import BooleanProperty, ListProperty, ObjectProperty
|
||||
from kivy.uix.dropdown import DropDown
|
||||
from kivy.uix.widget import Widget
|
||||
from kivymd.app import MDApp
|
||||
@@ -19,7 +19,7 @@ from katrain.core.constants import MODE_PLAY, OUTPUT_DEBUG
|
||||
from katrain.core.game import Move
|
||||
from katrain.core.lang import i18n
|
||||
from katrain.core.utils import evaluation_class, var_to_grid
|
||||
from katrain.gui.kivyutils import draw_circle, draw_text, BackgroundMixin
|
||||
from katrain.gui.kivyutils import BackgroundMixin, draw_circle, draw_text
|
||||
from katrain.gui.popups import I18NPopup, ReAnalyzeGamePopup
|
||||
from katrain.gui.style import *
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ import time
|
||||
|
||||
from kivy.clock import Clock
|
||||
from kivy.core.audio import SoundLoader
|
||||
from kivy.properties import ObjectProperty, OptionProperty
|
||||
from kivy.properties import ObjectProperty, OptionProperty, NumericProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivymd.uix.floatlayout import MDFloatLayout
|
||||
|
||||
from katrain.core.constants import MODE_PLAY, MODE_ANALYZE, STATUS_ERROR, STATUS_ANALYSIS
|
||||
from katrain.core.constants import MODE_PLAY, MODE_ANALYZE, STATUS_ERROR, STATUS_ANALYSIS, PLAYER_HUMAN
|
||||
from katrain.gui.kivyutils import AnalysisToggle, CollapsablePanel
|
||||
|
||||
|
||||
@@ -79,12 +79,15 @@ class ControlsPanel(BoxLayout):
|
||||
for bw, player_info in self.katrain.players_info.items():
|
||||
self.players[bw].player_type = player_info.player_type
|
||||
self.players[bw].player_subtype = player_info.player_subtype
|
||||
self.players[bw].name = player_info.name
|
||||
self.players[bw].rank = player_info.sgf_rank if player_info.player_type == PLAYER_HUMAN else player_info.calculated_rank
|
||||
|
||||
def set_status(self, msg, status_type, at_node=None):
|
||||
at_node = at_node or self.katrain and self.katrain.game and self.katrain.game.current_node
|
||||
if at_node != self.status_state[2] or int(status_type) >= int(self.status_state[1]):
|
||||
if at_node != self.status_state[2] or int(status_type) >= int(self.status_state[1]) or msg == "":
|
||||
self.status_state = (msg, status_type, at_node)
|
||||
self.status.text = msg
|
||||
self.status.error = status_type == STATUS_ERROR
|
||||
Clock.schedule_once(self.update_evaluation, 0)
|
||||
|
||||
# handles showing completed analysis and score graph
|
||||
|
||||
@@ -22,7 +22,7 @@ from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.button import BaseFlatButton, BasePressedButton
|
||||
from kivymd.uix.navigationdrawer import MDNavigationDrawer
|
||||
|
||||
from katrain.core.constants import AI_STRATEGIES_RECOMMENDED_ORDER, GAME_TYPES, PLAYER_AI, MODE_PLAY
|
||||
from katrain.core.constants import AI_STRATEGIES_RECOMMENDED_ORDER, GAME_TYPES, MODE_PLAY, PLAYER_AI
|
||||
from katrain.core.lang import i18n
|
||||
from katrain.gui.style import DEFAULT_FONT, WHITE
|
||||
|
||||
@@ -297,6 +297,8 @@ class PlayerInfo(MDBoxLayout, BackgroundMixin):
|
||||
player = OptionProperty("B", options=["B", "W"])
|
||||
player_type = StringProperty("Player")
|
||||
player_subtype = StringProperty("")
|
||||
name = StringProperty("", allownone=True)
|
||||
rank = StringProperty("", allownone=True)
|
||||
active = BooleanProperty(True)
|
||||
|
||||
|
||||
@@ -358,6 +360,8 @@ class CollapsablePanel(MDBoxLayout):
|
||||
|
||||
options = ListProperty([])
|
||||
options_height = NumericProperty(25)
|
||||
content_height = NumericProperty(100)
|
||||
size_hint_y_open = NumericProperty(None) # total height inc tabs, overrides content_height
|
||||
options_spacing = NumericProperty(6)
|
||||
option_labels = ListProperty([])
|
||||
option_active = ListProperty([])
|
||||
@@ -367,9 +371,6 @@ class CollapsablePanel(MDBoxLayout):
|
||||
|
||||
closed_label = StringProperty("Closed Panel")
|
||||
|
||||
size_hint_y_open = NumericProperty(1)
|
||||
height_open = NumericProperty(None)
|
||||
|
||||
state = OptionProperty("open", options=["open", "close"])
|
||||
close_icon = "img/Previous-5.png"
|
||||
open_icon = "img/Next-5.png"
|
||||
@@ -386,7 +387,7 @@ class CollapsablePanel(MDBoxLayout):
|
||||
option_active=self.build_options,
|
||||
options_spacing=self.build_options,
|
||||
)
|
||||
self.bind(state=self._on_state, size_hint_y_open=self._on_size, height_open=self._on_size)
|
||||
self.bind(state=self._on_state, content_height=self._on_size, options_height=self._on_size)
|
||||
MDApp.get_running_app().bind(language=lambda *_: Clock.schedule_once(self.build_options, 0))
|
||||
self.build_options()
|
||||
|
||||
@@ -397,10 +398,10 @@ class CollapsablePanel(MDBoxLayout):
|
||||
def _on_size(self, *_args):
|
||||
height, size_hint_y = 1, None
|
||||
if self.state == "open" and self.contents:
|
||||
if self.height_open:
|
||||
height = self.height_open
|
||||
else:
|
||||
if self.size_hint_y_open is not None:
|
||||
size_hint_y = self.size_hint_y_open
|
||||
else:
|
||||
height = self.content_height + self.options_height
|
||||
else:
|
||||
height = self.header.height
|
||||
self.height, self.size_hint_y = height, size_hint_y
|
||||
|
||||
@@ -4,8 +4,8 @@ import re
|
||||
from typing import Any, Dict, List, Tuple, Union
|
||||
|
||||
from kivy.clock import Clock
|
||||
from kivy.properties import BooleanProperty, NumericProperty, StringProperty, ListProperty, ObjectProperty
|
||||
from kivy.metrics import dp
|
||||
from kivy.properties import BooleanProperty, ListProperty, NumericProperty, ObjectProperty, StringProperty
|
||||
from kivy.uix.anchorlayout import AnchorLayout
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.label import Label
|
||||
@@ -19,11 +19,11 @@ from katrain.core.ai import ai_rank_estimation
|
||||
from katrain.core.constants import (
|
||||
AI_CONFIG_DEFAULT,
|
||||
AI_DEFAULT,
|
||||
AI_OPTION_VALUES,
|
||||
AI_STRATEGIES_RECOMMENDED_ORDER,
|
||||
OUTPUT_DEBUG,
|
||||
OUTPUT_ERROR,
|
||||
OUTPUT_INFO,
|
||||
AI_OPTION_VALUES,
|
||||
STATUS_INFO,
|
||||
)
|
||||
from katrain.core.engine import KataGoEngine
|
||||
@@ -447,6 +447,7 @@ class ConfigPopup(QuickConfigGui):
|
||||
if detected_restart:
|
||||
|
||||
def restart_engine(_dt):
|
||||
self.katrain.controls.set_status("", STATUS_INFO)
|
||||
self.katrain.log(f"Restarting Engine after {detected_restart} settings change")
|
||||
self.katrain.controls.set_status(i18n._("restarting engine"), STATUS_INFO)
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import math
|
||||
import threading
|
||||
|
||||
from kivy.lang import Builder
|
||||
from kivy.metrics import dp
|
||||
from kivy.properties import BooleanProperty, ListProperty, NumericProperty, Clock, StringProperty
|
||||
from kivy.properties import BooleanProperty, Clock, ListProperty, NumericProperty, StringProperty
|
||||
from kivymd.app import MDApp
|
||||
|
||||
from katrain.core.constants import OUTPUT_ERROR
|
||||
from katrain.core.lang import i18n
|
||||
from katrain.gui.kivyutils import BackgroundMixin
|
||||
import threading
|
||||
|
||||
|
||||
class Graph(BackgroundMixin):
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
from kivy.lang import Builder
|
||||
from kivy.properties import BooleanProperty, ListProperty, NumericProperty
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.properties import (
|
||||
NumericProperty,
|
||||
ListProperty,
|
||||
BooleanProperty,
|
||||
)
|
||||
from kivymd.uix.label import MDLabel
|
||||
from kivymd.uix.selectioncontrol import Thumb
|
||||
|
||||
|
||||
Reference in new issue
Block a user