why you crash
This commit is contained in:
1 parent
7e655aa744
commit
b541bbb1ca
16 files changed
+335
-41
No files matched your search
@@ -6,5 +6,8 @@ Many thanks to these additional authors:
|
||||
|
||||
Additional thanks to:
|
||||
"Dontbtme" for detailed feedback and early testing of v1.0.
|
||||
"Seventeen" for explanatory youtube videos and help on the Korean translation.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
from kivy.lang import Builder
|
||||
from kivy.metrics import sp
|
||||
from kivy.properties import ObjectProperty, NumericProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivymd.app import MDApp
|
||||
from kivymd.uix.menu import MDDropdownMenu, RightContent
|
||||
|
||||
|
||||
class AnalysisDropdownMenuRightContent(RightContent):
|
||||
pass
|
||||
|
||||
|
||||
class AnalysisDropdownMenu(MDDropdownMenu):
|
||||
pass
|
||||
|
||||
|
||||
ANALYSIS_ICONS = ["git", "git", "git"]
|
||||
ANALYSIS_OPTIONS = ["aaa", "bbb", "ccc"]
|
||||
ANALYSIS_SHORTCUTS = ["a", "s", "d"]
|
||||
|
||||
|
||||
class MenuOpener(BoxLayout):
|
||||
analysis_button = ObjectProperty(None)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
menu_items = [
|
||||
{"icon": icon, "text": text, "right_content_cls": AnalysisDropdownMenuRightContent(text=shortcut)}
|
||||
for icon, text, shortcut in zip(ANALYSIS_ICONS, ANALYSIS_OPTIONS, ANALYSIS_SHORTCUTS)
|
||||
]
|
||||
self.analysis_menu = AnalysisDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=6, use_icon_item=False, callback=lambda _: print(_))
|
||||
|
||||
def open_analysis_menu(self):
|
||||
self.analysis_menu.open()
|
||||
|
||||
|
||||
KV = """
|
||||
|
||||
<AnalysisDropdownMenuRightContent>:
|
||||
Label:
|
||||
width: dp(30)
|
||||
text: root.text
|
||||
color: [1,0,1,1]
|
||||
|
||||
<MenuOpener>:
|
||||
analysis_button:analysis_button
|
||||
Button:
|
||||
id: analysis_button
|
||||
text:'open!'
|
||||
on_press: root.open_analysis_menu()
|
||||
Label:
|
||||
text: 'text'
|
||||
"""
|
||||
|
||||
|
||||
Builder.load_string(KV)
|
||||
|
||||
|
||||
class MenuApp(MDApp):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def build(self):
|
||||
return MenuOpener()
|
||||
|
||||
|
||||
MenuApp().run()
|
||||
+14
-11
@@ -3,8 +3,8 @@ from kivy.config import Config # isort:skip
|
||||
ICON = "img/icon.png" # 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('graphics', 'width', 1400)
|
||||
Config.set('graphics', 'height', 1000)
|
||||
Config.set("graphics", "width", 1400)
|
||||
Config.set("graphics", "height", 1000)
|
||||
|
||||
import os
|
||||
import signal
|
||||
@@ -24,7 +24,7 @@ from kivy.uix.screenmanager import Screen
|
||||
from kivymd.app import MDApp
|
||||
|
||||
from katrain.core.ai import ai_move
|
||||
from katrain.core.utils import LANGUAGE, OUTPUT_DEBUG, OUTPUT_ERROR, OUTPUT_EXTRA_DEBUG, OUTPUT_INFO, OUTPUT_KATAGO_STDERR, find_package_resource, i18n
|
||||
from katrain.core.utils import LANGUAGE, OUTPUT_DEBUG, OUTPUT_ERROR, OUTPUT_EXTRA_DEBUG, OUTPUT_INFO, OUTPUT_KATAGO_STDERR, find_package_resource, i18n, MODE_PLAY
|
||||
from katrain.core.engine import KataGoEngine
|
||||
from katrain.core.game import Game, IllegalMoveException, KaTrainSGF
|
||||
from katrain.core.sgf_parser import Move, ParseError
|
||||
@@ -103,6 +103,9 @@ class KaTrainGui(Screen):
|
||||
except KeyError:
|
||||
self.log(f"Missing configuration option {setting}", OUTPUT_ERROR)
|
||||
|
||||
def play_analyze_mode(self):
|
||||
return self.play_mode.play_analyze_mode
|
||||
|
||||
def start(self):
|
||||
if self.engine:
|
||||
return
|
||||
@@ -114,7 +117,7 @@ class KaTrainGui(Screen):
|
||||
def update_state(self, redraw_board=False): # is called after every message and on receiving analyses and config changes
|
||||
# AI and Trainer/auto-undo handlers
|
||||
cn = self.game.current_node
|
||||
if self.controls.play_analyze_mode == "play":
|
||||
if self.play_analyze_mode == MODE_PLAY:
|
||||
auto_undo = cn.player and "undo" in self.controls.player_mode(cn.player)
|
||||
if auto_undo and cn.analysis_ready and cn.parent and cn.parent.analysis_ready and not cn.children and not self.game.ended:
|
||||
self.game.analyze_undo(cn, self.config("trainer")) # not via message loop
|
||||
@@ -132,11 +135,11 @@ class KaTrainGui(Screen):
|
||||
top, bot = [w.__self__ for w in self.board_controls.circles] # no weakref
|
||||
if self.game.next_player.player == "W":
|
||||
top, bot = bot, top
|
||||
self.controls.players['W'].active = True
|
||||
self.controls.players['B'].active = False
|
||||
self.controls.players["W"].active = True
|
||||
self.controls.players["B"].active = False
|
||||
else:
|
||||
self.controls.players['W'].active = False
|
||||
self.controls.players['B'].active = True
|
||||
self.controls.players["W"].active = False
|
||||
self.controls.players["B"].active = True
|
||||
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(top)
|
||||
@@ -180,9 +183,9 @@ class KaTrainGui(Screen):
|
||||
self.message_queue.put([self.game.game_id, message, *args])
|
||||
|
||||
def update_players(self):
|
||||
for player in 'BW':
|
||||
for player in "BW":
|
||||
self.controls.players[player].player_type = self.game.players[player].player_type
|
||||
self.game.players[player].player_subtype = self.game.players[player].player_subtype
|
||||
self.game.players[player].player_subtype = self.game.players[player].player_subtype
|
||||
|
||||
def _do_new_game(self, move_tree=None, analyze_fast=False):
|
||||
self.board_gui.animating_pv = None
|
||||
@@ -320,7 +323,7 @@ class KaTrainGui(Screen):
|
||||
else:
|
||||
self(*shortcut)
|
||||
elif keycode[1] == "tab":
|
||||
self.controls.switch_mode()
|
||||
self.play_mode.switch_mode()
|
||||
elif keycode[1] == "spacebar":
|
||||
self.controls.timer.paused = not self.controls.timer.paused
|
||||
elif keycode[1] in ["`", "~", "m"]:
|
||||
|
||||
@@ -93,6 +93,10 @@ class Lang(Observable):
|
||||
except ReferenceError:
|
||||
pass # proxy no longer exists
|
||||
|
||||
@property
|
||||
def font(self):
|
||||
return self._("LANG_FONT")
|
||||
|
||||
|
||||
LANGUAGE = "en"
|
||||
i18n = Lang(LANGUAGE)
|
||||
|
||||
+14
-3
@@ -33,7 +33,7 @@
|
||||
#:set NOTES_FONT_SIZE dp(18)
|
||||
|
||||
<I18NLabel>:
|
||||
font_name: i18n._('Roboto')
|
||||
font_name: i18n._('LANG_FONT')
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: RED
|
||||
@@ -42,7 +42,7 @@
|
||||
width: 1
|
||||
|
||||
<I18NTextInput>:
|
||||
font_name: i18n._('Roboto')
|
||||
font_name: i18n._('LANG_FONT')
|
||||
|
||||
# mixins
|
||||
<OutlineColor>:
|
||||
@@ -692,7 +692,18 @@
|
||||
on_active: if app.gui: app.gui.update_state()
|
||||
|
||||
<AnalysisDropdownMenu>:
|
||||
background_color: BOX_BACKGROUND_COLOR
|
||||
opening_time: 0.1
|
||||
width_mult: 1.25
|
||||
|
||||
<AnalysisDropdownMenuRightContent>:
|
||||
width: 0
|
||||
I18NLabel:
|
||||
id: label
|
||||
size: dp(30)
|
||||
font_size: root.font_size
|
||||
text: root.text
|
||||
color: LIGHTGREY
|
||||
|
||||
|
||||
<AnalysisControls>:
|
||||
@@ -845,7 +856,7 @@
|
||||
group: 'play_analyze'
|
||||
allow_no_selection: False
|
||||
|
||||
<PlayAnalyzeSelect@MDFloatLayout>
|
||||
<PlayAnalyzeSelect>:
|
||||
OutlineBox:
|
||||
outline_color: WHITE
|
||||
size_hint: 0.7,0.7
|
||||
|
||||
+31
-8
@@ -5,16 +5,17 @@ import time
|
||||
from kivy.clock import Clock
|
||||
from kivy.graphics.context_instructions import Color
|
||||
from kivy.graphics.vertex_instructions import Ellipse, Line, Rectangle
|
||||
from kivy.properties import ListProperty
|
||||
from kivy.metrics import sp
|
||||
from kivy.properties import ListProperty, StringProperty, NumericProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.widget import Widget
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.floatlayout import MDFloatLayout
|
||||
from kivymd.uix.menu import MDDropdownMenu
|
||||
from kivymd.uix.menu import MDDropdownMenu, RightContent
|
||||
|
||||
from katrain.core.utils import OUTPUT_DEBUG, evaluation_class, i18n, MODE_PLAY
|
||||
from katrain.core.game import Move
|
||||
from katrain.gui.kivyutils import draw_circle, draw_text, AnalysisDropdownMenu
|
||||
from katrain.gui.kivyutils import draw_circle, draw_text, BackgroundColor
|
||||
from katrain.core.utils import var_to_grid
|
||||
from kivy.core.window import Window
|
||||
|
||||
@@ -32,7 +33,8 @@ from katrain.gui.style import (
|
||||
BOARD_COLOR,
|
||||
STARPOINT_SIZE,
|
||||
STONE_SIZE,
|
||||
VISITS_FRAC_SMALL, ENGINE_DOWN_COL,
|
||||
VISITS_FRAC_SMALL,
|
||||
ENGINE_DOWN_COL,
|
||||
)
|
||||
|
||||
|
||||
@@ -410,9 +412,18 @@ class BadukPanWidget(Widget):
|
||||
self.set_animating_pv(pv_str[1:].split(" "), self.katrain.controls.active_comment_node.parent)
|
||||
|
||||
|
||||
class AnalysisDropdownMenuRightContent(RightContent):
|
||||
font_size = NumericProperty(sp(16))
|
||||
|
||||
|
||||
class AnalysisDropdownMenu(MDDropdownMenu):
|
||||
pass
|
||||
|
||||
|
||||
class AnalysisControls(MDFloatLayout):
|
||||
ANALYSIS_ICONS = ["git","git","git","git" ]
|
||||
ANALYSIS_OPTIONS = ['analysis:extra','analysis:equalize','analysis:sweep','analysis:aimove']
|
||||
ANALYSIS_ICONS = ["img/icons/prev.png", "git", "git", "git"]
|
||||
ANALYSIS_OPTIONS = ["analysis:extra", "analysis:equalize", "analysis:sweep", "analysis:aimove"]
|
||||
ANALYSIS_SHORTCUTS = ["a", "s", "d", "Enter"]
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@@ -420,10 +431,22 @@ class AnalysisControls(MDFloatLayout):
|
||||
Clock.schedule_once(self.build_menu, 0)
|
||||
|
||||
def build_menu(self, _dt):
|
||||
menu_items = [{"icon": icon, "text": i18n._(text)} for text,icon in zip(self.ANALYSIS_ICONS,self.ANALYSIS_OPTIONS)]
|
||||
self.analysis_menu = AnalysisDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=4)
|
||||
menu_items = [
|
||||
{"icon": icon, "text": i18n._(text)} # , "right_content_cls": AnalysisDropdownMenuRightContent(text=shortcut)}
|
||||
for icon, text, shortcut in zip(self.ANALYSIS_ICONS, self.ANALYSIS_OPTIONS, self.ANALYSIS_SHORTCUTS)
|
||||
]
|
||||
self.analysis_menu = AnalysisDropdownMenu(
|
||||
caller=self.analysis_button,
|
||||
items=menu_items,
|
||||
width_mult=5,
|
||||
use_icon_item=False,
|
||||
callback=lambda item: print(item, item.icon, item.text, item.children[-1].children, item.ids),
|
||||
)
|
||||
print(self.analysis_menu.use_icon_item)
|
||||
|
||||
def open_analysis_menu(self):
|
||||
while not self.analysis_menu:
|
||||
time.sleep(0.01)
|
||||
self.analysis_menu.open()
|
||||
|
||||
|
||||
|
||||
@@ -5,12 +5,28 @@ from kivy.properties import ObjectProperty, ListProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.popup import Popup
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.floatlayout import MDFloatLayout
|
||||
|
||||
from katrain.core.utils import MODE_PLAY, MODE_ANALYZE
|
||||
from katrain.gui.popups import ConfigTeacherPopup, ConfigTimerPopup
|
||||
from katrain.gui.ai_settings import ConfigAIPopupContents
|
||||
|
||||
|
||||
class PlayAnalyzeSelect(MDFloatLayout):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@property
|
||||
def play_analyze_mode(self):
|
||||
return MODE_PLAY if self.play_mode.play.status == "down" else MODE_ANALYZE
|
||||
|
||||
def switch_mode(self): # TODO: load settings
|
||||
if self.play_analyze_mode == MODE_PLAY:
|
||||
self.play.trigger_action(duration=0)
|
||||
else:
|
||||
self.analyze.trigger_action(duration=0)
|
||||
|
||||
|
||||
class ControlsPanel(BoxLayout):
|
||||
katrain = ObjectProperty(None)
|
||||
button_controls = ObjectProperty(None)
|
||||
@@ -35,10 +51,6 @@ class ControlsPanel(BoxLayout):
|
||||
self.status.text = msg
|
||||
self.update_evaluation()
|
||||
|
||||
@property
|
||||
def play_analyze_mode(self):
|
||||
return MODE_ANALYZE # ??
|
||||
|
||||
# handles showing completed analysis and score graph
|
||||
def update_evaluation(self):
|
||||
katrain = self.katrain
|
||||
@@ -54,7 +66,7 @@ class ControlsPanel(BoxLayout):
|
||||
last_player_was_ai_playing_human = game.last_player.ai and game.next_player.human
|
||||
|
||||
self.active_comment_node = current_node
|
||||
if self.play_analyze_mode == MODE_PLAY and last_player_was_ai_playing_human:
|
||||
if katrain.play_analyze_mode == MODE_PLAY and last_player_was_ai_playing_human:
|
||||
if game.next_player.being_taught and current_node.children and current_node.children.auto_undo:
|
||||
self.active_comment_node = current_node.children[-1]
|
||||
elif current_node.parent:
|
||||
|
||||
+18
-11
@@ -76,21 +76,26 @@ class SizedMDButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedBu
|
||||
label = ObjectProperty(None)
|
||||
height = NumericProperty(33)
|
||||
|
||||
|
||||
class SizedMDToggleButton(ToggleButtonBehavior, SizedMDButton):
|
||||
inactive_outline_color = ListProperty([0.5, 0.5, 0.5, 0])
|
||||
active_outline_color = ListProperty([1, 1, 1, 0])
|
||||
inactive_background_color = ListProperty([0.5, 0.5, 0.5, 1])
|
||||
active_background_color = ListProperty([1, 1, 1, 1])
|
||||
|
||||
|
||||
class SizedMDRectangleButton(SizedMDButton):
|
||||
pass
|
||||
|
||||
|
||||
class SizedMDRectangleToggleButton(SizedMDToggleButton):
|
||||
pass
|
||||
|
||||
|
||||
class AutoSizedMDRectangleButton(SizedMDRectangleButton):
|
||||
hor_padding = NumericProperty(6)
|
||||
|
||||
|
||||
class AutoSizedMDRectangleToggleButton(SizedMDRectangleToggleButton):
|
||||
hor_padding = NumericProperty(6)
|
||||
|
||||
@@ -131,22 +136,21 @@ class CircleWithText(Widget):
|
||||
|
||||
# -- new gui elements
|
||||
|
||||
class PlayerInfo(MDBoxLayout,BackgroundColor,OutlineColor):
|
||||
|
||||
class PlayerInfo(MDBoxLayout, BackgroundColor, OutlineColor):
|
||||
captures = NumericProperty(0)
|
||||
player = OptionProperty("Black", options=["Black", "White"])
|
||||
player_type= StringProperty('Player')
|
||||
player_subtype = StringProperty('')
|
||||
player_type = StringProperty("Player")
|
||||
player_subtype = StringProperty("")
|
||||
active = BooleanProperty(True)
|
||||
|
||||
class AnalysisDropdownMenu(MDDropdownMenu):
|
||||
pass
|
||||
|
||||
|
||||
class AnalysisToggle(MDBoxLayout):
|
||||
text = StringProperty('')
|
||||
text = StringProperty("")
|
||||
active = BooleanProperty(False)
|
||||
|
||||
class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout,BackgroundColor):
|
||||
|
||||
class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout, BackgroundColor):
|
||||
__events__ = ["on_action"]
|
||||
icon = StringProperty("")
|
||||
text = StringProperty("")
|
||||
@@ -160,12 +164,15 @@ class MainMenuItem(RectangularRippleBehavior, LeftButtonBehavior, MDBoxLayout,Ba
|
||||
def on_action(self):
|
||||
pass
|
||||
|
||||
|
||||
class CollapsablePanelHeader(MDBoxLayout):
|
||||
pass
|
||||
|
||||
|
||||
class CollapsablePanelTab(AutoSizedMDRectangleToggleButton):
|
||||
pass
|
||||
|
||||
|
||||
class CollapsablePanel(MDBoxLayout):
|
||||
__events__ = ["on_option_state"]
|
||||
|
||||
@@ -200,7 +207,7 @@ class CollapsablePanel(MDBoxLayout):
|
||||
self.build_options()
|
||||
|
||||
def build_options(self, *args, **kwargs):
|
||||
self.header = CollapsablePanelHeader(height=self.options_height, size_hint_y=None, spacing=self.options_spacing)
|
||||
self.header = CollapsablePanelHeader(height=self.options_height, size_hint_y=None, spacing=self.options_spacing, padding=[1, 0, 0, 0])
|
||||
self.option_buttons = []
|
||||
option_labels = self.option_labels or [i18n._(f"tab:{opt}") for opt in self.options]
|
||||
for lbl, opt_col, active in zip(option_labels, self.option_colors, self.option_default_active):
|
||||
@@ -318,7 +325,7 @@ class ScaledLightLabel(LightLabel, ToolTipBehavior):
|
||||
num_lines = NumericProperty(1)
|
||||
|
||||
|
||||
class ClickableLabel(LeftButtonBehavior,I18NLabel):
|
||||
class ClickableLabel(LeftButtonBehavior, I18NLabel):
|
||||
pass
|
||||
|
||||
|
||||
@@ -328,7 +335,7 @@ class LightHelpLabel(ScaledLightLabel):
|
||||
|
||||
class ScrollableLabel(ScrollView, BackgroundColor):
|
||||
__events__ = ["on_ref_press"]
|
||||
outline_color = ListProperty([0, 0, 0, 0]) # mixin not working for some reason
|
||||
outline_color = ListProperty([0, 0, 0, 0]) # mixin not working for some reason
|
||||
text = StringProperty("")
|
||||
markup = BooleanProperty(False)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ def to_hexcol(kivycol):
|
||||
|
||||
# basic color definitions
|
||||
RED = [0.8, 0.1, 0.1, 1]
|
||||
WHITE = [0.95,0.95,0.95,1]
|
||||
WHITE = [0.95, 0.95, 0.95, 1]
|
||||
|
||||
# eval dots
|
||||
EVAL_COLORS = [
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. This is the font used, files ONLY relative to 'katrain' directory
|
||||
msgid "Roboto"
|
||||
msgid "LANG_FONT"
|
||||
msgstr "fonts/NotoSans-Regular.ttf"
|
||||
|
||||
#. main hamburger menu
|
||||
@@ -55,6 +55,19 @@ msgstr ""
|
||||
"Expected\n"
|
||||
"Territory"
|
||||
|
||||
#. analysis menu items
|
||||
msgid "analysis:extra"
|
||||
msgstr "Deeper analysis"
|
||||
|
||||
msgid "analysis:equalize"
|
||||
msgstr "Equalize visits of potential moves"
|
||||
|
||||
msgid "analysis:sweep"
|
||||
msgstr "Fast analysis of all moves"
|
||||
|
||||
msgid "analysis:aimove"
|
||||
msgstr "Force AI Move"
|
||||
|
||||
#. right panel buttons and below board
|
||||
msgid "pass-button-text"
|
||||
msgstr "Pass"
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. This is the font used, files ONLY relative to 'katrain' directory
|
||||
msgid "Roboto"
|
||||
msgid "LANG_FONT"
|
||||
msgstr "fonts/NotoSansKR-Regular.otf"
|
||||
|
||||
msgid "English"
|
||||
@@ -213,3 +213,19 @@ msgstr "General Settings"
|
||||
#. TODO
|
||||
msgid "menu:playersetup"
|
||||
msgstr "Player Setup"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:sweep"
|
||||
msgstr "Fast analysis of all moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:equalize"
|
||||
msgstr "Equalize visits of potential moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:aimove"
|
||||
msgstr "Force AI Move"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:extra"
|
||||
msgstr "Deeper analysis"
|
||||
Binary file not shown.
@@ -244,3 +244,23 @@ msgstr "General Settings"
|
||||
#. TODO
|
||||
msgid "menu:playersetup"
|
||||
msgstr "Player Setup"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:sweep"
|
||||
msgstr "Fast analysis of all moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:equalize"
|
||||
msgstr "Equalize visits of potential moves"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:aimove"
|
||||
msgstr "Force AI Move"
|
||||
|
||||
#. TODO
|
||||
msgid "analysis:extra"
|
||||
msgstr "Deeper analysis"
|
||||
|
||||
#. TODO
|
||||
msgid "LANG_FONT"
|
||||
msgstr "fonts/NotoSans-Regular.ttf"
|
||||
@@ -0,0 +1,115 @@
|
||||
from kivy.lang import Builder
|
||||
from kivy.metrics import sp
|
||||
from kivy.properties import ObjectProperty, NumericProperty
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivymd.app import MDApp
|
||||
from kivymd.uix.menu import MDDropdownMenu, RightContent
|
||||
|
||||
|
||||
class AnalysisDropdownMenuRightContent(RightContent):
|
||||
font_size = NumericProperty(sp(16))
|
||||
|
||||
|
||||
class AnalysisDropdownMenu(MDDropdownMenu):
|
||||
pass
|
||||
|
||||
|
||||
ANALYSIS_ICONS = ["git", "git", "git", "git"]
|
||||
ANALYSIS_OPTIONS = ["analysis:extra", "analysis:equalize", "analysis:sweep", "analysis:aimove"]
|
||||
ANALYSIS_SHORTCUTS = ["a", "s", "d", "Enter"]
|
||||
|
||||
|
||||
class MenuOpener(BoxLayout):
|
||||
analysis_button = ObjectProperty(None)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
menu_items = [
|
||||
{"icon": icon, "text": text, "right_content_cls": AnalysisDropdownMenuRightContent(text=shortcut)}
|
||||
for icon, text, shortcut in zip(ANALYSIS_ICONS, ANALYSIS_OPTIONS, ANALYSIS_SHORTCUTS)
|
||||
]
|
||||
self.analysis_menu = AnalysisDropdownMenu(caller=self.analysis_button, items=menu_items, width_mult=6, use_icon_item=False, callback=lambda _: print(_))
|
||||
|
||||
# self.analysis_menu.create_menu_items()
|
||||
# for item in self.analysis_menu.menu.ids.box.children:
|
||||
# item.ids._right_container.padding = [100,0,0,0]
|
||||
|
||||
def open_analysis_menu(self):
|
||||
self.analysis_menu.open()
|
||||
|
||||
|
||||
KV = """
|
||||
<Label>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: [1,0,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
|
||||
<AnalysisDropdownMenu>:
|
||||
|
||||
|
||||
<MDMenuItem>:
|
||||
canvas.after:
|
||||
Color:
|
||||
rgba: [0,1,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
|
||||
<MDMenuItemIcon>:
|
||||
canvas.after:
|
||||
Color:
|
||||
rgba: [1,1,0,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
|
||||
<AnalysisDropdownMenuRightContent>:
|
||||
width: 0
|
||||
adaptive_width: False
|
||||
canvas.after:
|
||||
Color:
|
||||
rgba: [0,0,1,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
Label:
|
||||
pos_hint: {'right':0}
|
||||
width: dp(30)
|
||||
id: label
|
||||
size: self.texture_size
|
||||
font_size: root.font_size
|
||||
text: root.text
|
||||
color: [1,0,1,1]
|
||||
canvas.after:
|
||||
Color:
|
||||
rgba: [0,1,1,1]
|
||||
Line:
|
||||
rectangle: (*self.pos,*self.size)
|
||||
width: 1
|
||||
|
||||
<MenuOpener>:
|
||||
analysis_button:analysis_button
|
||||
Button:
|
||||
id: analysis_button
|
||||
text:'open!'
|
||||
on_press: root.open_analysis_menu()
|
||||
Label:
|
||||
text: 'text'
|
||||
"""
|
||||
|
||||
|
||||
Builder.load_string(KV)
|
||||
|
||||
|
||||
class MenuApp(MDApp):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def build(self):
|
||||
return MenuOpener()
|
||||
|
||||
|
||||
MenuApp().run()
|
||||
Reference in new issue
Block a user