gui redesign in progress..

This commit is contained in:
Sander Land committed 2020-05-21 19:48:47 +02:00
1 parent 1e5771df59
commit 2fc2cca7e1
9 files changed
+283 -382

No files matched your search

+10
View File
@@ -38,6 +38,16 @@
* If you prefer not to install, run without installing using `python3 -m katrain` * If you prefer not to install, run without installing using `python3 -m katrain`
* A binary for KataGo is included, but if you have compiled your own, point the 'engine/katago' setting to the relevant KataGo v1.4+ binary. * A binary for KataGo is included, but if you have compiled your own, point the 'engine/katago' setting to the relevant KataGo v1.4+ binary.
## Troubleshooting
Older linux machines may have trouble installing, you can try to manually install dependencies to resolve some issues.
* `sudo apt-get install pkg-config libgl-dev opencl-headers ocl-icd-opencl-dev `
* `pip3 install -U cython wheel setuptools`
* `pip3 install kivy==2.0.0rc2 kivymd==1.104.1`
In case KataGo does not start, an alternative is to go [here](https://github.com/lightvector/KataGo) and compile KataGo yourself.
# Configuring the GPU(s) KataGo uses # Configuring the GPU(s) KataGo uses
In most cases KataGo detects your configuration correctly, automatically searching for OpenCL devices and select the highest scoring device. In most cases KataGo detects your configuration correctly, automatically searching for OpenCL devices and select the highest scoring device.
+13 -14
View File
@@ -1,4 +1,6 @@
from kivy.config import Config # isort:skip from kivy.config import Config # isort:skip
from kivy.uix.screenmanager import Screen
ICON = "img/icon.png" ICON = "img/icon.png"
Config.set("kivy", "window_icon", ICON) # isort:skip # set icon Config.set("kivy", "window_icon", ICON) # isort:skip # set icon
Config.set("input", "mouse", "mouse,multitouch_on_demand") # isort:skip # no red dots on right click Config.set("input", "mouse", "mouse,multitouch_on_demand") # isort:skip # no red dots on right click
@@ -32,7 +34,7 @@ from katrain.gui.popups import NewGamePopup, ConfigPopup, LoadSGFPopup
__version__ = "1.0.6" __version__ = "1.0.6"
class KaTrainGui(BoxLayout): class KaTrainGui(Screen):
"""Top level class responsible for tying everything together""" """Top level class responsible for tying everything together"""
zen = BooleanProperty(False) zen = BooleanProperty(False)
@@ -122,26 +124,23 @@ class KaTrainGui(BoxLayout):
# Handle prisoners and next player display # Handle prisoners and next player display
prisoners = self.game.prisoner_count prisoners = self.game.prisoner_count
top, bot = self.board_controls.black_prisoners.__self__, self.board_controls.white_prisoners.__self__ # no weakref top, bot = [w.__self__ for w in self.board_controls.circles] # no weakref
if self.game.next_player == "W": if self.game.next_player == "W":
top, bot = bot, top top, bot = bot, top
self.board_controls.mid_circles_container.clear_widgets() self.board_controls.mid_circles_container.clear_widgets()
self.board_controls.mid_circles_container.add_widget(bot) self.board_controls.mid_circles_container.add_widget(bot)
self.board_controls.mid_circles_container.add_widget(top) self.board_controls.mid_circles_container.add_widget(top)
self.board_controls.black_prisoners.text = str(prisoners["W"]) self.controls.players['W'].captures = prisoners["W"]
self.board_controls.white_prisoners.text = str(prisoners["B"]) self.controls.players['B'].captures = prisoners["B"]
# 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 = self.config("board_ui/engine_down_col") self.controls.engine_status_col = self.config("board_ui/engine_down_col")
elif len(self.engine.queries) >= 4:
self.board_controls.engine_status_col = self.config("board_ui/engine_busy_col")
elif len(self.engine.queries) >= 2:
self.board_controls.engine_status_col = self.config("board_ui/engine_little_busy_col")
elif len(self.engine.queries) == 0: elif len(self.engine.queries) == 0:
self.board_controls.engine_status_col = self.config("board_ui/engine_ready_col") self.controls.engine_status_col = self.config("board_ui/engine_ready_col")
else: else:
self.board_controls.engine_status_col = self.config("board_ui/engine_almost_done_col") self.controls.engine_status_col = self.config("board_ui/engine_busy_col")
# redraw # redraw
if redraw_board: if redraw_board:
Clock.schedule_once(self.board_gui.draw_board, -1) Clock.schedule_once(self.board_gui.draw_board, -1)
@@ -286,7 +285,6 @@ class KaTrainGui(BoxLayout):
return # if in new game or load, don't allow keyboard shortcuts return # if in new game or load, don't allow keyboard shortcuts
shortcuts = { shortcuts = {
"q": self.analysis_controls.show_children,
"w": self.analysis_controls.eval, "w": self.analysis_controls.eval,
"e": self.analysis_controls.hints, "e": self.analysis_controls.hints,
"r": self.analysis_controls.ownership, "r": self.analysis_controls.ownership,
@@ -310,7 +308,7 @@ class KaTrainGui(BoxLayout):
elif keycode[1]== "spacebar": elif keycode[1]== "spacebar":
self.controls.timer.paused = not self.controls.timer.paused self.controls.timer.paused = not self.controls.timer.paused
elif keycode[1] in ["`", "~", "m"]: elif keycode[1] in ["`", "~", "m"]:
self.controls_box.hidden = not self.controls_box.hidden self.zen = not self.zen
elif keycode[1] in ["up", "z"]: elif keycode[1] in ["up", "z"]:
self("undo", 1 + ("shift" in modifiers) * 9 + ("ctrl" in modifiers) * 999) self("undo", 1 + ("shift" in modifiers) * 9 + ("ctrl" in modifiers) * 999)
elif keycode[1] in ["down", "x"]: elif keycode[1] in ["down", "x"]:
@@ -337,7 +335,8 @@ class KaTrainApp(MDApp):
self.gui = KaTrainGui() self.gui = KaTrainGui()
self.title = f"KaTrain v{__version__}" self.title = f"KaTrain v{__version__}"
self.theme_cls.theme_style = "Dark" self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "DeepPurple" self.theme_cls.primary_palette = "Blue"
Window.bind(on_request_close=self.on_request_close) Window.bind(on_request_close=self.on_request_close)
return self.gui return self.gui
+193 -338
View File
@@ -21,24 +21,34 @@
#:set LIGHTBLUE [0.3,0.7,0.9,1] #:set LIGHTBLUE [0.3,0.7,0.9,1]
#:set YELLOW [0.8,0.8,0.1,1] #:set YELLOW [0.8,0.8,0.1,1]
#:set SCORE_COLOR LIGHTBLUE #:set SCORE_COLOR LIGHTBLUE
#:set POINTLOSS_COLOR YELLOW #:set POINTLOSS_COLOR YELLOW
#:set WINRATE_COLOR GREEN #:set WINRATE_COLOR GREEN
#:set BUTTON_DISABLED_COLOR (0.5,0.5,0.5,1)
#:set BACKGROUND_COLOR [36/255,48/255,62/255,1] #:set BACKGROUND_COLOR [36/255,48/255,62/255,1]
#:set BOX_BACKGROUND_COLOR [46/255,65/255,88/255,1] #:set BOX_BACKGROUND_COLOR [46/255,65/255,88/255,1]
#:set TEXT_COLOR WHITE
# mixins # mixins
<OutlineColor>:
canvas.before:
Color:
rgb: root.outline_color
Line:
rectangle: (*self.pos,*self.size)
width: root.outline_width
<BackgroundColor>: <BackgroundColor>:
canvas.before: canvas.before:
Color: Color:
rgb: root.background rgb: root.background_color
Rectangle: Rectangle:
pos: self.pos pos: self.pos
size: self.size size: self.size
<ToolTipBehavior>:
<ToolTipLabel>: <ToolTipLabel>:
size_hint: None, None size_hint: None, None
@@ -58,7 +68,36 @@
width: 1.1 width: 1.1
rectangle: (*self.pos,*self.size) rectangle: (*self.pos,*self.size)
# widgets # new widgets
<SmallMDFlatButton>:
outline_color: root.color
disabled_color: BUTTON_DISABLED_COLOR
text_color: root.color
background_color: BOX_BACKGROUND_COLOR
size: (dp(100),dp(33))
font_size: sp(20)
MDLabel:
id: label
text: root.text
font_size: root.font_size
font_name: root.font_name if root.font_name is not None else self.font_name
size_hint_x: None
text_size: (None, root.height)
height: self.texture_size[1]
theme_text_color: 'Custom'
text_color: root.text_color
valign: 'middle'
halign: 'center'
<SmallMDFlatToggleButton>:
text_color: root.color if self.state=='down' else self.disabled_color
outline_color: root.color if self.state=='down' else self.disabled_color
# -- old widgets
<StyledButton>: <StyledButton>:
color: WHITE color: WHITE
@@ -151,14 +190,11 @@
mipmap: True mipmap: True
<LightLabel>: <LightLabel>:
color: WHITE color: TEXT_COLOR
text_size: self.size # don't overflow these text_size: self.size # don't overflow these
halign: 'center' halign: 'center'
valign: 'center' valign: 'center'
<LargeLabel@LightLabel>:
bold: True
<TimerLabel@Label> <TimerLabel@Label>
color: GREEN color: GREEN
font_size: 0.85*self.size[1] font_size: 0.85*self.size[1]
@@ -169,7 +205,7 @@
font_name: 'img/fonts/digital-7.ttf' font_name: 'img/fonts/digital-7.ttf'
<ScaledLightLabel>: # popups <ScaledLightLabel>: # popups
color: WHITE color: TEXT_COLOR
font_size: 0.45*self.size[1]/self.num_lines font_size: 0.45*self.size[1]/self.num_lines
<LightHelpLabel>: <LightHelpLabel>:
@@ -178,12 +214,6 @@
valign: 'center' valign: 'center'
multiline: True multiline: True
<CheckBoxHintLabel@Label+ToolTipBehavior>:
font_size: 0.4*self.size[1]
color: BLACK
halign: 'center'
valign: 'center'
size: self.texture_size
<ClickableLabel@ButtonBehavior+LightLabel>: <ClickableLabel@ButtonBehavior+LightLabel>:
color: WHITE color: WHITE
@@ -248,13 +278,19 @@
size: self.parent.height, self.parent.height size: self.parent.height, self.parent.height
katrain: app.gui katrain: app.gui
<BoardControlsButton@MDFillRoundFlatIconButton>:
md_bg_color: BOX_BACKGROUND_COLOR
<BadukPanControls>: <BadukPanControls>:
katrain: app.gui katrain: app.gui
black_prisoners: black_prisoners circles: [black_circle,white_circle]
white_prisoners: white_prisoners
mid_circles_container: mid_circles_container mid_circles_container: mid_circles_container
pass_btn: pass_btn pass_btn: pass_btn
engine_status_col: 0.8,0,0,1 hamburger: hamburger
analysis_button: analysis_button
HamburgerButton:
id: hamburger
on_press: root.nav_drawer.set_state("open")
Label: Label:
size_hint: 0.05, 1 size_hint: 0.05, 1
BoxLayout: BoxLayout:
@@ -285,16 +321,18 @@
size_hint: 0.1, 1 size_hint: 0.1, 1
on_press: root.katrain('undo') on_press: root.katrain('undo')
FloatLayout: FloatLayout:
size_hint: 0.2, 1 size_hint: 0.1, 1
id: mid_circles_container id: mid_circles_container
BlackCircleWithText: BlackCircleWithText:
id: black_prisoners id: black_circle
pos: (self.parent.pos[0]-self.height/3,self.parent.pos[1]) if self.parent else (0,0) text: ''
radius: 0.4 pos: (self.parent.pos[0]-self.height/5,self.parent.pos[1]) if self.parent else (0,0)
radius: 0.3
WhiteCircleWithText: WhiteCircleWithText:
id: white_prisoners id: white_circle
pos: (self.parent.pos[0]+self.height/3,self.parent.pos[1]) if self.parent else (0,0) text: ''
radius: 0.4 pos: (self.parent.pos[0]+self.height/5,self.parent.pos[1]) if self.parent else (0,0)
radius: 0.3
BoxLayout: BoxLayout:
size_hint: 0.3, 1 size_hint: 0.3, 1
padding: [0, self.size[1]*0.3] padding: [0, self.size[1]*0.3]
@@ -315,119 +353,73 @@
BoxLayout: BoxLayout:
size_hint: 0.2, 1 size_hint: 0.2, 1
padding: 0.2 * self.size[1] padding: 0.2 * self.size[1]
StyledButton: BoardControlsButton:
text: 'AI Move' id: analysis_button
tooltip_text: '[enter]\nPlay an AI move\nusing the\nselected strategy.' text: 'Analysis'
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("ai-move",None) icon: 'settings'
font_size: 0.6*self.size[1] on_press: root.open_analysis_menu()
ClickableLabel:
size_hint: 0.025, 1
canvas:
Color:
rgba: root.engine_status_col
Ellipse:
pos: self.pos[0] + self.width/2 - self.height/5, self.pos[1] + self.height/2 - self.height/5
size: self.height/2.5,self.height/2.5
Color:
rgba: BLACK
Line:
circle: self.pos[0] + self.width/2, self.pos[1] + self.height/2, self.height/5 - 1
width: 1.1
on_press: root.katrain.controls.set_status("This simply indicates the Engine status, going from green (idle) to orange (processing many queries). It turns red when the engine has crashed or fails to start.")
Label: Label:
size_hint: 0.025, 1 size_hint: 0.025, 1
<HamburgerButton@MDFloatingActionButton>: <HamburgerButton@MDFloatingActionButton>:
icon: 'img/flaticon/hamburger.png' icon: 'menu'
size_hint: None, 1 size_hint: None, 1
width: self.height width: self.height
<AnalysisControls@BoxLayout>:
katrain: app.gui
show_children: show_children
eval: eval
policy: policy
hints: hints
ownership: ownership
analyze_extra: analyze_extra
analyze_equalize: analyze_equalize
analyze_sweep: analyze_sweep
HamburgerButton:
GridLayout:
cols: 5
rows: 2
size_hint: 0.5, 1
CheckBoxHintLabel:
text: 'next\nmoves'
tooltip_text: '[q]\nShow all next moves\nplayed from the current position'
CheckBoxHintLabel:
text: 'all\ndots'
tooltip_text: '[w]\nShow evaluation dots\non stones for all moves'
CheckBoxHintLabel:
text: 'top\nmoves'
tooltip_text: '[e]\nShow top\npredicted moves'
CheckBoxHintLabel:
text: 'show\nowner'
tooltip_text: '[r]\nShow predicted ownership\nof each intersection'
CheckBoxHintLabel:
text: 'NN\npolicy'
tooltip_text: "[t]\nShow Policy top moves\n(i.e. with no 'reading')"
CheckBox:
id: show_children
active: True
on_active: root.katrain.update_state()
CheckBox:
id: eval
on_active: root.katrain.update_state()
CheckBox:
id: hints
on_active: root.katrain.update_state()
CheckBox:
id: ownership
on_active: root.katrain.update_state()
CheckBox:
id: policy
on_active: root.katrain.update_state()
BoxLayout:
spacing:1
padding: 1,2,1,2
size_hint: 0.5, 1
StyledButton:
id: analyze_extra
text: 'Extra'
tooltip_text: '[a]\nExtra analysis\nto increase accuracy\nof top move predictions\nand score difference'
size_hint: 1, 1
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","extra")
StyledButton:
id: analyze_equalize
text: 'Equalize'
tooltip_text: '[s]\nAnalysis of all\npredicted top moves\nwith the same accuracy'
size_hint: 1, 1
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","equalize")
StyledButton:
id: analyze_sweep
text: 'Sweep'
tooltip_text: '[d]\nFast analysis\nof all legal moves'
size_hint: 1, 1
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","sweep")
# ---------- components of right pane ------- # ---------- components of right pane -------
<ControlPanelSection@BoxLayout+BackgroundColor>: <ControlPanelSection@BoxLayout+BackgroundColor>:
background: BOX_BACKGROUND_COLOR background_color: BOX_BACKGROUND_COLOR
<PlayerInfo@BoxLayout>: <PlayerInfo@MDBoxLayout>:
captures: 0
name: 'Player'
description: '...'
BlackCircleWithText: BlackCircleWithText:
text: '0' text: str(root.captures)
size_hint: 0.2, 1 size_hint: 0.2, 1
id: captures radius: 0.75
canvas.before:
Color:
rgb: [1,0,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
MDBoxLayout:
size_hint: 0.8, 1
orientation: 'vertical'
Label: Label:
id: description text: root.name
Label:
text: root.description
<PonderInfo@ControlPanelSection>: <PonderInfo@ControlPanelSection>:
engine_status_col: [1,1,1,1]
MDBoxLayout:
orientation: 'vertical'
LightLabel: LightLabel:
text: 'AI\nBusy' size_hint: 1, 0.5
text: 'AI\nStatus'
font_size: self.height/3
halign: 'center'
valign: 'middle'
ClickableLabel:
size_hint: 1, 0.5
canvas:
Color:
rgba: root.engine_status_col
Ellipse:
pos: self.pos[0] + self.width/2 - self.width/6, self.pos[1] + self.height/2 - self.width/6
size: self.width/3, self.width/3
Color:
rgba: BLACK
Line:
circle: self.pos[0] + self.width/2, self.pos[1] + self.height/2, self.width/6
width: 1
on_press: app.gui.controls.set_status("This simply indicates the Engine status, going from green (idle) to orange (processing queries). It turns red when the engine has crashed or fails to start.")
<PauseButton@MDFloatingActionButton+ToggleButtonBehavior>: <PauseButton@MDFloatingActionButton+ToggleButtonBehavior>:
icon: 'img/flaticon/pause.png' icon: 'img/flaticon/pause.png'
@@ -472,16 +464,11 @@
size: self.texture_size size: self.texture_size
<ScoreGraph>: <ScoreGraph>:
background_color: BOX_BACKGROUND_COLOR
whalf: root.pos[1]+self.height*0.25 whalf: root.pos[1]+self.height*0.25
bhalf: root.pos[1]+self.height*0.75 bhalf: root.pos[1]+self.height*0.75
mid: root.pos[1]+self.height*0.5 mid: root.pos[1]+self.height*0.5
right_edge: root.pos[0] + root.width right_edge: root.pos[0] + root.width
canvas.before:
Color:
rgb: BOX_BACKGROUND_COLOR
Rectangle:
pos: root.pos
size: root.size
canvas: canvas:
Color: Color:
rgba: GRAPH_CENTER_COLOR rgba: GRAPH_CENTER_COLOR
@@ -528,8 +515,9 @@
pos: root.right_edge - self.width-1, root.pos[1] pos: root.right_edge - self.width-1, root.pos[1]
text: 'W+' + str(int(root.y_scale)) text: 'W+' + str(int(root.y_scale))
<StatsBox@BoxLayout> <StatsBox@BoxLayout+BackgroundColor>
orientation: 'vertical' orientation: 'vertical'
background_color: BOX_BACKGROUND_COLOR
score: score score: score
win_rate: win_rate win_rate: win_rate
score_change: score_change score_change: score_change
@@ -540,7 +528,7 @@
color: WINRATE_COLOR color: WINRATE_COLOR
CensorableLabel: CensorableLabel:
id: score id: score
label: 'Score Estimate' label: 'Score'
text: '' text: ''
color: SCORE_COLOR color: SCORE_COLOR
CensorableLabel: CensorableLabel:
@@ -550,22 +538,13 @@
color: POINTLOSS_COLOR color: POINTLOSS_COLOR
<ScrollableLabel>: <ScrollableLabel>:
background_color: BOX_BACKGROUND_COLOR
outline_color: [0,0,0,0]
do_scroll_x: False do_scroll_x: False
scroll_type: ['bars'] scroll_type: ['bars']
bar_width: 5 bar_width: 5
bar_color: BUTTON_COLOR bar_color: BUTTON_COLOR
label: label label: label
canvas.before:
Color:
rgba: root.border_color
Line:
rectangle: [self.pos[0],self.pos[1]+1,self.width-1,self.height-2]
width:1
Color:
rgba: [*[(c+1)/2 for c in root.border_color[:3]], root.border_color[3]]
Line:
rectangle: [self.pos[0]+1,self.pos[1]+2,self.width-3,self.height-3]
width:1
Label: Label:
id: label id: label
markup: root.markup markup: root.markup
@@ -594,7 +573,7 @@
button_controls: app.gui and app.gui.button_controls button_controls: app.gui and app.gui.button_controls
orientation: 'vertical' orientation: 'vertical'
players: {'B':B_player,'W':W_player} players: {'B':B_player,'W':W_player}
ponder: ponder engine_status_col: [1,1,1,1]
timer:timer timer:timer
graph: graph graph: graph
stats: stats stats: stats
@@ -614,6 +593,7 @@
spacing: CP_SPACING spacing: CP_SPACING
PonderInfo: PonderInfo:
id: ponder id: ponder
engine_status_col: root.engine_status_col
size_hint_x: 0.2 size_hint_x: 0.2
Timer: Timer:
id: timer id: timer
@@ -632,6 +612,7 @@
id: status id: status
size_hint: 1, None size_hint: 1, None
height: 50 #min(self.parent.height*0.66,self.label.text_size[1]) height: 50 #min(self.parent.height*0.66,self.label.text_size[1])
outline_color: RED
ScrollableLabel: ScrollableLabel:
id: info id: info
markup: True markup: True
@@ -646,36 +627,15 @@
height: min( (len(self._lines)+0.7) * self.line_height, self.parent.height - status.height - 2.7*self.line_height) height: min( (len(self._lines)+0.7) * self.line_height, self.parent.height - status.height - 2.7*self.line_height)
<RHSButton>: <RHSButton@SmallMDFlatButton>:
size: self.parent.button_size size: self.parent.button_size
on_press: print(self.height, self.parent.height, self.parent.parent.height) font_size: self.height * 0.7
_color: self.color
canvas.before: <RHSToggleButton@SmallMDFlatToggleButton>:
Color: size: self.parent.button_size
rgba: BOX_BACKGROUND_COLOR font_size: self.height * 0.7
Rectangle: on_press: app.gui.controls.check_hide_show()
size: root.size
pos: root.pos
Color:
rgba: root._color
Line:
width: 1
rectangle: (self.x, self.y, self.width, self.height)
MDLabel:
text: root.text
font_size: root.height * 0.7
font_name: root.font_name if root.font_name is not None else self.font_name
size_hint_x: None
text_size: (None, root.height)
height: self.texture_size[1]
theme_text_color: 'Custom'
text_color: root._color
valign: 'middle'
halign: 'center'
#:set RHS_BUTTON_UP_COLOR (0.5,0.5,0.5,1)
<RHSToggleButton@RHSButton+ToggleButtonBehavior>:
_color: root.color if self.state=='down' else RHS_BUTTON_UP_COLOR
<ButtonBox@MDBoxLayout> <ButtonBox@MDBoxLayout>
orientation: 'vertical' orientation: 'vertical'
@@ -691,19 +651,26 @@
<RightButtonControls>: <RightButtonControls>:
orientation: 'vertical' orientation: 'vertical'
button_size: (self.size[1] * 0.15 , self.size[1] * 0.04) button_size: (self.size[1] * 0.08 , self.size[1] * 0.04)
size_hint_x: None size_hint_x: None
width: self.button_size[0] + 2*CP_PADDING width: self.minimum_width # if not self.parent.zen else 1
padding: CP_PADDING, CP_PADDING padding: CP_PADDING, CP_PADDING
spacing: CP_SPACING spacing: CP_SPACING
info: info info: info
note: note note: note
eval: eval
policy: policy
hints: hints
ownership: ownership
analyze_extra: analyze_extra
analyze_equalize: analyze_equalize
analyze_sweep: analyze_sweep
graph: {'winrate': winrate_graph,'score':score_graph,'points':points_graph} graph: {'winrate': winrate_graph,'score':score_graph,'points':points_graph}
ButtonBoxHolder: ButtonBoxHolder:
size_hint_y: PLAYER_BOX_HEIGHT size_hint_y: PLAYER_BOX_HEIGHT
ButtonBox: ButtonBox:
RHSButton: RHSButton:
text: 'PASS' text: 'Pass'
ButtonBoxHolder: ButtonBoxHolder:
size_hint_y: TIMER_BOX_HEIGHT size_hint_y: TIMER_BOX_HEIGHT
ButtonBox: ButtonBox:
@@ -726,7 +693,7 @@
group: 'graph' group: 'graph'
id: score_graph id: score_graph
RHSToggleButton: RHSToggleButton:
text: 'Point Loss' text: 'Loss'
group: 'graph' group: 'graph'
color: POINTLOSS_COLOR color: POINTLOSS_COLOR
id: points_graph id: points_graph
@@ -742,11 +709,11 @@
color: SCORE_COLOR color: SCORE_COLOR
state: "down" state: "down"
RHSToggleButton: RHSToggleButton:
text: 'Point Loss' text: 'Loss'
color: POINTLOSS_COLOR color: POINTLOSS_COLOR
state: "down" state: "down"
ButtonBoxHolder: ButtonBoxHolder:
size_hint_y: INFO_BOX_HEIGHT size_hint_y: INFO_BOX_HEIGHT * 0.25
ButtonBox: ButtonBox:
RHSToggleButton: RHSToggleButton:
id: info id: info
@@ -759,177 +726,58 @@
text: 'Note' text: 'Note'
color: GREEN color: GREEN
group: "text" group: "text"
ButtonBoxHolder:
size_hint_y: INFO_BOX_HEIGHT * 0.75
ButtonBox:
RHSToggleButton:
<OldControls@BoxLayout>
orientation: 'horizontal'
BoxLayout: # ----------- analyze -----------
size_hint: 0,1
id: analyze_tab
padding: [3,3]
opacity: 0
orientation: 'vertical'
GridLayout:
cols: 5
rows: 2
size_hint: 1, 0.3
CheckBoxHintLabel:
text: 'next\nmoves'
tooltip_text: '[q]\nShow all next moves\nplayed from the current position'
CheckBoxHintLabel:
text: 'all\ndots'
tooltip_text: '[w]\nShow evaluation dots\non stones for all moves'
CheckBoxHintLabel:
text: 'top\nmoves'
tooltip_text: '[e]\nShow top\npredicted moves'
CheckBoxHintLabel:
text: 'show\nowner'
tooltip_text: '[r]\nShow predicted ownership\nof each intersection'
CheckBoxHintLabel:
text: 'NN\npolicy'
tooltip_text: "[t]\nShow Policy top moves\n(i.e. with no 'reading')"
CheckBox:
id: show_children
active: True
on_active: root.katrain.update_state()
CheckBox:
id: eval id: eval
on_active: root.katrain.update_state() text: 'Dots'
CheckBox: color: WHITE
id: hints RHSToggleButton:
on_active: root.katrain.update_state()
CheckBox:
id: ownership id: ownership
on_active: root.katrain.update_state() text: 'Territory'
CheckBox: color: WHITE
RHSToggleButton:
id: policy id: policy
on_active: root.katrain.update_state() text: 'Policy'
BoxLayout: color: WHITE
spacing:1 RHSToggleButton:
padding: 1,2,1,2 id: hints
size_hint: 1,0.2 text: 'Top Moves'
LightLabel: color: WHITE
text: 'Analysis' RHSButton:
size_hint: 1, 1
multiline: False
font_size: 0.45*self.size[1]
StyledButton:
id: analyze_extra id: analyze_extra
text: 'Extra' text: 'Extra'
tooltip_text: '[a]\nExtra analysis\nto increase accuracy\nof top move predictions\nand score difference' tooltip_text: '[a]\nExtra analysis\nto increase accuracy\nof top move predictions\nand score difference'
size_hint: 1, 1
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","extra") on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","extra")
StyledButton: RHSButton:
id: analyze_equalize id: analyze_equalize
text: 'Equalize' text: 'Equalize'
tooltip_text: '[s]\nAnalysis of all\npredicted top moves\nwith the same accuracy' tooltip_text: '[s]\nAnalysis of all\npredicted top moves\nwith the same accuracy'
size_hint: 1, 1
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","equalize") on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","equalize")
StyledButton: RHSButton:
id: analyze_sweep id: analyze_sweep
text: 'Sweep' text: 'Sweep'
tooltip_text: '[d]\nFast analysis\nof all legal moves' tooltip_text: '[d]\nFast analysis\nof all legal moves'
size_hint: 1, 1
on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","sweep") on_press: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-extra","sweep")
ScoreGraph:
id: graph
size_hint: 1,0.7 <ContentNavigationDrawer@MDBoxLayout+BackgroundColor>:
BoxLayout:
orientation: 'vertical' orientation: 'vertical'
size_hint: 1,0.3 background_color: BOX_BACKGROUND_COLOR
spacing: 3
BoxLayout: # ----------- play -----------
orientation: 'vertical'
size_hint: 1,1
opacity: 1
id: play_tab
Label: Label:
size_hint: 1,0.02 text: 'sdafs'
GridLayout:
cols: 4
rows: 2
spacing: 1
padding: 1
size_hint: 1,0.125
BlackCircleWithText:
text: 'B'
size_hint: 0.1, 1
ToggleButtonContainer:
size_hint: 0.6, 1
id: B_player_mode
options: PLAYER_MODE_VALUES
labels: PLAYER_MODES
tooltips: PLAYER_TOOLTIPS
on_selection: root.katrain.update_state()
StyledSpinner:
id: B_AI_mode
values: ['Default']
size_hint: 0.3, 1
on_text: if B_player_mode.children: B_player_mode.children[0].trigger_action(duration=0)
Label: Label:
size_hint: None,1 text: 'sdafs'
width: 3 MDFlatButton:
WhiteCircleWithText: text: 'size'
text: 'W' on_press: print(self.size,self.parent.size,self.parent.parent.size,self.parent.parent.parent.size,self.parent.parent.parent.parent.size)
size_hint: 0.1, 1 MDFlatButton:
ToggleButtonContainer: text: 'pos'
size_hint: 0.6, 1 on_press: print(self.pos,self.parent.pos,self.parent.parent.pos,self.parent.parent.parent.pos,self.parent.parent.parent.parent.pos,self.parent.parent.parent.parent)
id: W_player_mode
options: PLAYER_MODE_VALUES
labels: PLAYER_MODES
tooltips: PLAYER_TOOLTIPS
on_selection: root.katrain.update_state()
StyledSpinner:
id: W_AI_mode
size_hint: 0.3, 1
values: ['Default']
on_text: if W_player_mode.children: W_player_mode.children[0].trigger_action(duration=0)
BoxLayout:
size_hint: 1,0.05
padding: 5,0
spacing: 1
StyledButton:
text: 'Configure Teacher'
tooltip_text: "Undos, dots, and\nSGF output settings"
on_release: if not self.last_touch or self.last_touch.button=="left": root.configure_teacher()
size_hint: 1.425, 1
StyledButton:
text: 'Configure AIs'
tooltip_text: "Strength Settings per AI"
on_release: if not self.last_touch or self.last_touch.button=="left": root.configure_ais()
Label:
size_hint: 1,0.1
BoxLayout:
orientation: 'horizontal'
size_hint: 1, None
spacing: 2
padding: 2
height: self.width * 0.25
StyledIconButton:
icon: 'img/flaticon/go-game.png'
tooltip_text: '[Ctrl-N]\nNew Game'
size_hint: 0.25, 1
on_release: if not self.last_touch or self.last_touch.button=="left": root.katrain("new-game-popup")
StyledIconButton:
icon: 'img/flaticon/open-folder.png'
tooltip_text: '[Ctrl-L]\nLoad Game'
size_hint: 0.25, 1
on_release: if not self.last_touch or self.last_touch.button=="left": root.katrain("analyze-sgf-popup")
StyledIconButton:
icon: 'img/flaticon/bar.png'
tooltip_text: '[Ctrl-S]\nSave Game'
size_hint: 0.25, 1
on_release: if not self.last_touch or self.last_touch.button=="left": root.katrain('output-sgf')
StyledIconButton:
icon: 'img/flaticon/gears.png'
tooltip_text: 'General Settings'
size_hint: 0.25, 1
on_release: if not self.last_touch or self.last_touch.button=="left": root.katrain('config-popup')
<GuiContents@MDBoxLayout+BackgroundColor>
background_color: BACKGROUND_COLOR
<KaTrainGui>: <KaTrainGui>:
board_gui: board_gui board_gui: board_gui
@@ -937,33 +785,40 @@
board_controls: board_controls board_controls: board_controls
analysis_controls: analysis_controls analysis_controls: analysis_controls
button_controls: button_controls button_controls: button_controls
analysis_controls: button_controls
zen: False zen: False
canvas.before: NavigationLayout:
Color: ScreenManager:
rgb: BACKGROUND_COLOR Screen:
Rectangle: name: 'gui'
pos: self.pos GuiContents:
size: self.size MDBoxLayout:
BoxLayout:
orientation: 'vertical' orientation: 'vertical'
padding: CP_PADDING, 0 padding: CP_PADDING, 0
AnalysisControls:
id: analysis_controls
size_hint_y: None
height: min(100,self.width / 13.5)
BadukPanWidget: BadukPanWidget:
id: board_gui id: board_gui
BadukPanControls: BadukPanControls:
id: board_controls id: board_controls
nav_drawer: nav_drawer
size_hint_y: None size_hint_y: None
height: min(100,self.width / 13.5) height: max(dp(75),self.width / 13.5)
ControlsPanel: ControlsPanel:
id: controls id: controls
size_hint_x: None size_hint_x: None
width: 0 if root.zen else self.height * 0.4 width: 0 if root.zen else self.height * 0.35
opacity: 0 if root.zen else 1 opacity: 0 if root.zen else 1
RightButtonControls: RightButtonControls:
id: button_controls id: button_controls
MyNavigationDrawer:
id: nav_drawer
state: "close"
width: self.height / 3
y: board_gui.pos[1]+CP_SPACING
swipe_edge_width: 0
ContentNavigationDrawer:
nav_drawer: nav_drawer
<LoadSGFPopup>: <LoadSGFPopup>:
+17 -3
View File
@@ -7,6 +7,8 @@ from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Ellipse, Line, Rectangle from kivy.graphics.vertex_instructions import Ellipse, Line, Rectangle
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget from kivy.uix.widget import Widget
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.menu import MDDropdownMenu
from katrain.core.common import OUTPUT_DEBUG, evaluation_class, PLAYER_AI from katrain.core.common import OUTPUT_DEBUG, evaluation_class, PLAYER_AI
from katrain.core.game import Move from katrain.core.game import Move
@@ -306,7 +308,6 @@ class BadukPanWidget(Widget):
self.active_pv_moves = [] self.active_pv_moves = []
# children of current moves in undo / review # children of current moves in undo / review
if katrain.analysis_controls.show_children.active:
alpha = self.ui_config["ghost_alpha"] alpha = self.ui_config["ghost_alpha"]
for child_node in current_node.children: for child_node in current_node.children:
points_lost = child_node.points_lost points_lost = child_node.points_lost
@@ -393,5 +394,18 @@ class BadukPanWidget(Widget):
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)
class BadukPanControls(BoxLayout): class BadukPanControls(MDBoxLayout):
pass def __init__(self, **kwargs):
super().__init__(**kwargs)
self.analysis_menu = None
Clock.schedule_once(self.init_menus,1)
def init_menus(self,_dt):
menu_items = [{"icon": "git", "text": f"Item {i}"} for i in range(5)]
self.analysis_menu = MDDropdownMenu(
caller=self.analysis_button, items=menu_items, width_mult=4
)
def open_analysis_menu(self):
if self.analysis_menu:
self.analysis_menu.open()
+5
View File
@@ -25,6 +25,11 @@ class ControlsPanel(BoxLayout):
self.periods_used = {"B": 0, "W": 0} self.periods_used = {"B": 0, "W": 0}
Clock.schedule_interval(self.update_timer, 0.07) Clock.schedule_interval(self.update_timer, 0.07)
def check_hide_show(self, *_args):
pass
def set_status(self, msg, at_node=None): def set_status(self, msg, at_node=None):
self.status_msg = msg self.status_msg = msg
self.status_node = at_node or self.katrain and self.katrain.game and self.katrain.game.current_node self.status_node = at_node or self.katrain and self.katrain.game and self.katrain.game.current_node
+39 -22
View File
@@ -7,6 +7,7 @@ from kivy.clock import Clock
from kivy.core.text import Label as CoreLabel from kivy.core.text import Label as CoreLabel
from kivy.core.window import Window from kivy.core.window import Window
from kivy.graphics import * from kivy.graphics import *
from kivy.metrics import dp, sp
from kivy.properties import BooleanProperty, ListProperty, NumericProperty, ObjectProperty, StringProperty from kivy.properties import BooleanProperty, ListProperty, NumericProperty, ObjectProperty, StringProperty
from kivy.uix.behaviors import ToggleButtonBehavior from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
@@ -25,29 +26,44 @@ from kivymd.uix.behaviors import RectangularRippleBehavior
from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDRectangleFlatButton, BaseButton from kivymd.uix.button import MDRectangleFlatButton, BaseButton
from kivymd.uix.label import MDLabel from kivymd.uix.label import MDLabel
from kivymd.uix.navigationdrawer import MDNavigationDrawer
class BackgroundColor(Widget):
background_color = ListProperty([1, 1, 1, 0])
class OutlineColor(Widget):
outline_color = ListProperty([1, 1, 1, 0])
outline_width = NumericProperty(1)
class RightButtonControls(MDBoxLayout): class RightButtonControls(MDBoxLayout):
button_size = ListProperty([100,33]) button_size = ListProperty([100,33])
class RHSButton(RectangularRippleBehavior,BaseButton): class SmallMDFlatButton(RectangularRippleBehavior,BaseButton,BackgroundColor,OutlineColor):
button_label = BooleanProperty(True)
text = StringProperty("") text = StringProperty("")
text_color = ListProperty([1,1,1,1])
color = ListProperty([1, 1, 1, 1]) color = ListProperty([1, 1, 1, 1])
_color = ListProperty([1,1,1,1]) font_size = NumericProperty(sp(20))
class SmallMDFlatToggleButton(SmallMDFlatButton,ToggleButtonBehavior):
@property
def active(self):
return self.state=='down'
class LightLabel(MDLabel): class LightLabel(MDLabel):
pass pass
class BackgroundLabel(MDLabel,BackgroundColor):
pass
class CensorableLabel(MDBoxLayout): class CensorableLabel(MDBoxLayout):
text = StringProperty("") text = StringProperty("")
label = StringProperty("") label = StringProperty("")
color = ListProperty([1, 1, 1, 1]) color = ListProperty([1, 1, 1, 1])
class ScoreGraph(BackgroundLabel):
class ScoreGraph(Label):
nodes = ListProperty([]) nodes = ListProperty([])
score_points = ListProperty([]) score_points = ListProperty([])
winrate_points = ListProperty([]) winrate_points = ListProperty([])
@@ -105,13 +121,11 @@ class ScoreGraph(Label):
self.on_size() self.on_size()
# --- not checked class ToolTipLabel(MDLabel):
class ToolTipLabel(Label):
pass pass
class ToolTipBehavior(Widget): class ToolTipBehavior(object):
tooltip_text = StringProperty("") tooltip_text = StringProperty("")
def __init__(self, **kwargs): def __init__(self, **kwargs):
@@ -145,30 +159,36 @@ class ToolTipBehavior(Widget):
self.tooltip.text = self.tooltip_text self.tooltip.text = self.tooltip_text
Window.add_widget(self.tooltip) Window.add_widget(self.tooltip)
class MyNavigationDrawer(MDNavigationDrawer):
def on_touch_up(self, touch):
if self.status == "opened" and self.close_on_click and not self.collide_point(touch.ox, touch.oy):
self.set_state("close", animation=True)
return True
return super().on_touch_up(touch)
class BaseCircleWithText(LightLabel):
radius = NumericProperty(0.48)
class ScaledLightLabel(LightLabel, ToolTipBehavior): class ScaledLightLabel(LightLabel, ToolTipBehavior):
num_lines = NumericProperty(1) num_lines = NumericProperty(1)
# --- not checked
class LightHelpLabel(ScaledLightLabel): class LightHelpLabel(ScaledLightLabel):
pass pass
class BackgroundColor(Widget):
background = ListProperty([1, 1, 1, 0])
class ScrollableLabel(ScrollView,BackgroundColor,OutlineColor):
class BackgroundLabel(Label, BackgroundColor):
pass
class ScrollableLabel(ScrollView):
__events__ = ["on_ref_press"] __events__ = ["on_ref_press"]
text = StringProperty("") text = StringProperty("")
markup = BooleanProperty(False) markup = BooleanProperty(False)
border_color = ListProperty([0, 0, 0, 1])
def on_ref_press(self, ref): def on_ref_press(self, ref):
pass pass
@@ -265,9 +285,6 @@ class ToggleButtonContainer(GridLayout):
return self.options[0] return self.options[0]
class BaseCircleWithText(LightLabel):
radius = NumericProperty(0.48)
class LabelledTextInput(TextInput): class LabelledTextInput(TextInput):
input_property = StringProperty("") input_property = StringProperty("")
+1 -1
View File
@@ -269,7 +269,7 @@ class ConfigTeacherPopup(QuickConfigGui):
for i, (thr, undos, color) in enumerate(zip(thresholds, undos, colors)): for i, (thr, undos, color) in enumerate(zip(thresholds, undos, colors)):
thrbox.add_widget(LabelledFloatInput(text=str(thr), input_property=f"eval_thresholds::{i}")) thrbox.add_widget(LabelledFloatInput(text=str(thr), input_property=f"eval_thresholds::{i}"))
thrbox.add_widget(LabelledFloatInput(text=str(undos), input_property=f"num_undo_prompts::{i}")) thrbox.add_widget(LabelledFloatInput(text=str(undos), input_property=f"num_undo_prompts::{i}"))
thrbox.add_widget(BackgroundLabel(background=color[:3])) thrbox.add_widget(BackgroundLabel(background_color=color[:3]))
thrbox.add_widget(LabelledCheckBox(text=str(color[3] == 1), input_property=f"alpha::{i}")) thrbox.add_widget(LabelledCheckBox(text=str(color[3] == 1), input_property=f"alpha::{i}"))
thrbox.add_widget(LabelledCheckBox(size_hint=(0.5, 1), text=str(self.sgf_settings["save_feedback"][i]), input_property=f"save_feedback::{i}")) thrbox.add_widget(LabelledCheckBox(size_hint=(0.5, 1), text=str(self.sgf_settings["save_feedback"][i]), input_property=f"save_feedback::{i}"))
self.add_widget(thrbox) self.add_widget(thrbox)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

+5 -4
View File
@@ -39,11 +39,12 @@ setup(
"wheel", "setuptools", "wheel", "setuptools",
"importlib_resources ;python_version<'3.7'", "importlib_resources ;python_version<'3.7'",
"cython>=0.24,<=0.29.14,!=0.27,!=0.27.2", # kivy wants this "cython>=0.24,<=0.29.14,!=0.27,!=0.27.2", # kivy wants this
"kivy>=2.0.0rc2", "kivy_deps.glew;platform_system=='Windows'",
"kivy_deps.sdl2;platform_system=='Windows'",
"kivy_deps.gstreamer;platform_system=='Windows'",
"kivy>=1.11 ;python_version<'3.8'",
"kivy>=2.0.0rc2 ;python_version>='3.8'",
"kivymd>=0.104.0", "kivymd>=0.104.0",
# "kivy_deps.glew;platform_system=='Windows'",
# "kivy_deps.sdl2;platform_system=='Windows'",
# "kivy_deps.gstreamer;platform_system=='Windows'",
], ],
python_requires=">=3.6, <4", python_requires=">=3.6, <4",
entry_points={"console_scripts": ["katrain=katrain.__main__:run_app"]}, entry_points={"console_scripts": ["katrain=katrain.__main__:run_app"]},