remove dev, fix setup

This commit is contained in:
Sander Land committed 2020-05-30 20:55:16 +02:00
1 parent 21e53b86df
commit 0de50719cf
13 files changed
+393 -1748

No files matched your search

-257
View File
@@ -1,257 +0,0 @@
import kivy
from kivy.app import App
from kivy.core.text import Label as CoreLabel
from kivy.lang import Builder
from kivy.properties import (
BooleanProperty,
ListProperty,
NumericProperty,
ObjectProperty,
OptionProperty,
StringProperty,
)
from kivy.uix.behaviors import ButtonBehavior, ToggleButtonBehavior
from kivy.uix.button import Button
from kivy.uix.checkbox import CheckBox
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.widget import Widget
from kivymd.app import MDApp
from kivymd.uix.behaviors import CircularRippleBehavior, RectangularRippleBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import BaseFlatButton, BasePressedButton
from kivymd.uix.navigationdrawer import MDNavigationDrawer
WHITE = [1, 1, 1, 1]
class TestBox(GridLayout):
pass
class BackgroundMixin(Widget):
background_color = ListProperty([0, 0, 0, 0])
background_radius = NumericProperty(0)
outline_color = ListProperty([0, 0, 0, 0])
outline_width = NumericProperty(1)
class LeftButtonBehavior(ButtonBehavior): # stops buttons etc activating on right click
def __init__(self, **kwargs):
self.register_event_type("on_left_release")
self.register_event_type("on_left_press")
super().__init__(**kwargs)
def on_touch_down(self, touch):
return super().on_touch_down(touch)
def on_release(self):
if not self.last_touch or self.last_touch.button == "left":
self.dispatch("on_left_release")
return super().on_release()
def on_press(self):
if not self.last_touch or self.last_touch.button == "left":
self.dispatch("on_left_press")
return super().on_press()
def on_left_release(self):
pass
def on_left_press(self):
pass
# -- resizeable buttons
class SizedButton(LeftButtonBehavior, RectangularRippleBehavior, BasePressedButton, BaseFlatButton, BackgroundMixin): # avoid baserectangular for sizing
text = StringProperty("")
text_color = ListProperty(WHITE)
text_size = ListProperty([100, 100])
halign = OptionProperty("center", options=["left", "center", "right", "justify", "auto"])
label = ObjectProperty(None)
padding_x = NumericProperty(6)
padding_y = NumericProperty(0)
fsz = NumericProperty(None)
class AutoSizedButton(SizedButton):
pass
class ToggleButtonMixin(ToggleButtonBehavior):
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 SizedRectangleButton(SizedButton):
pass
class SizedRectangleToggleButton(ToggleButtonMixin, SizedRectangleButton):
pass
class AutoSizedRectangleButton(AutoSizedButton):
pass
class AutoSizedRectangleToggleButton(ToggleButtonMixin, AutoSizedRectangleButton):
pass
class TransparentIconButton(CircularRippleBehavior, Button):
icon_size = ListProperty([25, 25])
icon = StringProperty("")
KV = """
#:set LIGHTGREY [0.7,0.7,0.7,1]
#:set WHITE [1,1,1,1]
#:set BUTTON_INACTIVE_COLOR LIGHTGREY
#:set BACKGROUND_COLOR [16/255,18/255,32/255,1]
#:set BOX_BACKGROUND_COLOR [46/255,65/255,88/255,1]
#:set TEXT_COLOR WHITE
<Label>:
canvas.before:
Color:
rgba: [1,0,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
# mixins
<BackgroundMixin>:
canvas.before:
Color:
rgba: root.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [root.background_radius, ]
Color:
rgba: root.outline_color
Line:
rounded_rectangle: (*self.pos,self.width,self.height,root.background_radius)
width: root.outline_width
<SizedButton>:
ripple_duration_in_slow: 0.6
text_color: WHITE
background_color: BOX_BACKGROUND_COLOR
label: label
text_size: root.size
onlytext: ''
on_press: print('size: {}\\ntexture_size: {}\\ntext_size: {} - font {} - {} - {} ?\\npos: {} - halign {}'.format(label.size,label.texture_size,label.text_size,label.font_size,root.font_size,0.6 * self.height / len(self.label.text.split('\\n')),label.pos,label.halign),self.label.text.split('\\n'))
Label:
id: label
padding: [root.padding_x,root.padding_y]
color: root.text_color
font_size: 0.6 * self.height / len(self.text.split('\\n')) if root.fsz is None else root.fsz
on_font_size: print(args,self.font_size,self.text)
halign: root.halign
text: 'size: {}\\ntexture_size: {}\\ntext_size: {}\\npos: {}halign {}\\n{}'.format(self.size,self.texture_size,self.text_size,self.pos,self.halign,root.text) if not root.onlytext else root.onlytext
<AutoSizedButton>:
width: root.label.texture_size[0]
<SizedToggleButton>
inactive_background_color: BACKGROUND_COLOR
active_background_color: BOX_BACKGROUND_COLOR
background_color: self.active_background_color if self.state=='down' else self.inactive_background_color
outline_color: self.active_outline_color if self.state=='down' else self.inactive_outline_color
<SizedRectangleButton>:
outline_color: WHITE
text_color: self.outline_color
<SizedRectangleToggleButton>:
inactive_outline_color: BUTTON_INACTIVE_COLOR
active_outline_color: WHITE
text_color: self.outline_color
<AutoSizedRectangleButton>: # only wants height
outline_color: WHITE
text_color: self.outline_color
<AutoSizedRoundedRectangleButton@AutoSizedRectangleButton>:
background_radius: self.height/3.5
halign: 'left'
<PassBtn@AutoSizedRoundedRectangleButton>:
id: pass_btn
onlytext: 'Pass'
background_radius: 10
height: 50
<BGBoxLayout@BoxLayout+BackgroundMixin>
background_color: BACKGROUND_COLOR
padding: 100
<TransparentIconButton>:
background_normal: ''
background_color: (0,0,0,0)
image: image
Image:
id: image
size: root.icon_size
pos: [root.pos[i] + (root.size[i] - root.icon_size[i])/2 for i in [0,1]]
source: root.icon
mipmap: True
<TestBox>:
canvas.before:
Color:
rgba: [0,1,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
cols: 2
rows: 3
BGBoxLayout:
SizedButton:
text: 'SizedButton'
height: 125
width: 300
BGBoxLayout:
AutoSizedRectangleButton:
text: 'AutoSizedRectangleButton'
size_hint_y: None
height: 150
BGBoxLayout:
SizedRectangleButton:
text: 'SizedRectangleButton'
height: 125
width: 300
halign: 'left'
background_radius: 25
BGBoxLayout:
AutoSizedRoundedRectangleButton:
text: 'AutoSizedRectangleButton'
halign: 'left'
size_hint_y: None
height: 150
BGBoxLayout:
PassBtn:
"""
Builder.load_string(KV)
class MyApp(MDApp):
def __init__(self):
super().__init__()
def build(self):
layout = TestBox()
return layout
MyApp().run()
-67
View File
@@ -1,67 +0,0 @@
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()
-492
View File
@@ -1,492 +0,0 @@
# Adapted from https://github.com/kivy-garden/filebrowser
"""
FileBrowser
===========
The :class:`FileBrowser` widget is an advanced file browser. You use it
similarly to FileChooser usage.
It provides a shortcut bar with links to special and system directories.
When touching next to a shortcut in the links bar, it'll expand and show
all the directories within that directory. It also facilitates specifying
custom paths to be added to the shortcuts list.
It provides a icon and list view to choose files from. And it also accepts
filter and filename inputs.
To create a FileBrowser which prints the currently selected file as well as
the current text in the filename field when 'Select' is pressed, with
a shortcut to the Documents directory added to the favorites bar::
import os
from kivy.app import App
class TestApp(App):
def build(self):
user_path = os.path.join(get_home_directory(), 'Documents')
browser = FileBrowser(select_string='Select',
favorites=[(user_path, 'Documents')])
browser.bind(on_success=self._fbrowser_success,
on_submit=self._fbrowser_submit)
return browser
def _fbrowser_success(self, instance):
print(instance.selection)
def _fbrowser_submit(self, instance):
print(instance.selection)
TestApp().run()
:Events:
`on_success`:
Fired when the `Select` buttons `on_release` event is called.
`on_submit`:
Fired when a file has been selected with a double-tap.
.. image:: _static/filebrowser.png
:align: right
"""
from kivy.resources import resource_add_path
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.treeview import TreeViewLabel, TreeView
from kivy.uix.filechooser import FileChooserListView, FileChooserListLayout
from kivy.properties import ObjectProperty, StringProperty, OptionProperty, ListProperty, BooleanProperty
from kivy.lang import Builder
from kivy.utils import platform
from kivy.clock import Clock
import string
from os.path import sep, dirname, expanduser, isdir, join
from os import walk
from functools import partial
from katrain.core.utils import i18n
if platform == "win":
from ctypes import windll, create_unicode_buffer
resource_add_path("katrain/")
def last_modified_first(files, filesystem):
return sorted(f for f in files if filesystem.is_dir(f)) + sorted([f for f in files if not filesystem.is_dir(f)], key=lambda f: -os.path.getmtime(f))
def get_home_directory():
if platform == "win":
user_path = expanduser("~")
if not isdir(join(user_path, "Desktop")):
user_path = dirname(user_path)
else:
user_path = expanduser("~")
return user_path
def get_drives():
drives = []
if platform == "win":
bitmask = windll.kernel32.GetLogicalDrives()
GetVolumeInformationW = windll.kernel32.GetVolumeInformationW
for letter in string.ascii_uppercase:
if bitmask & 1:
name = create_unicode_buffer(64)
# get name of the drive
drive = letter + u":"
res = GetVolumeInformationW(drive + sep, name, 64, None, None, None, None, 0)
if isdir(drive):
drives.append((drive, name.value))
bitmask >>= 1
elif platform == "linux":
drives.append((sep, sep))
drives.append((expanduser(u"~"), "~/"))
places = (sep + u"mnt", sep + u"media")
for place in places:
if isdir(place):
for directory in next(walk(place))[1]:
drives.append((place + sep + directory, directory))
elif platform == "macosx" or platform == "ios":
drives.append((expanduser(u"~"), "~/"))
vol = sep + u"Volume"
if isdir(vol):
for drive in next(walk(vol))[1]:
drives.append((vol + sep + drive, drive))
return drives
class I18NFileChooserListView(FileChooserListView):
font_name = StringProperty("")
class I18NFileChooserListLayout(FileChooserListLayout):
_ENTRY_TEMPLATE = "I18NFileListEntry"
Builder.load_string(
"""
#:kivy 1.0
[I18NFileListEntry@FloatLayout+TreeViewNode]:
locked: False
entries: []
path: ctx.path
is_selected: self.path in ctx.controller().selection
orientation: 'horizontal'
size_hint_y: None
height: '24dp' # '48dp' if dp(1) > 1 else '24dp'
# Don't allow expansion of the ../ node
is_leaf: not ctx.isdir or ctx.name.endswith('..' + ctx.sep) or self.locked
on_touch_down: self.collide_point(*args[1].pos) and ctx.controller().entry_touched(self, args[1])
on_touch_up: self.collide_point(*args[1].pos) and ctx.controller().entry_released(self, args[1])
BoxLayout:
pos: root.pos
size_hint_x: None
width: root.width - dp(10)
Label:
id: filename
text_size: self.width, None
halign: 'left'
shorten: True
text: ctx.name
font_name: ctx.controller().font_name
Label:
text_size: self.width, None
size_hint_x: None
halign: 'right'
text: '{}'.format(ctx.get_nice_size())
<I18NFileChooserListView>:
layout: layout
I18NFileChooserListLayout:
id: layout
controller: root
"""
)
Builder.load_string(
"""
#:kivy 1.2.0
#:import metrics kivy.metrics
#:import abspath os.path.abspath
#:import i18n katrain.core.utils.i18n
<Button>:
track_lang: i18n._('')
<TreeLabel>:
on_touch_down:
self.parent.browser.path = self.path if self.collide_point(*args[1].pos) and self.path else self.parent.browser.path
on_is_open: self.is_open and self.parent.trigger_populate(self)
<FileBrowser>:
orientation: 'vertical'
spacing: 5
padding: [6, 6, 6, 6]
select_state: select_button.state
filename: file_text.text
browser: list_view
on_favorites: link_tree.reload_favs(self.favorites)
BoxLayout:
orientation: 'horizontal'
spacing: 5
Splitter:
sizable_from: 'right'
min_size: '153sp'
size_hint: (.2, 1)
id: splitter
ScrollView:
LinkTree:
id: link_tree
browser: root.browser
size_hint_y: None
height: self.minimum_height
on_parent: self.fill_tree(root.favorites)
root_options: {'text': 'Locations', 'no_selection':True}
BoxLayout:
size_hint_x: .8
orientation: 'vertical'
Label:
size_hint_y: None
height: '22dp'
text_size: self.size
padding_x: '10dp'
text: abspath(root.path)
track_lang: i18n._('')
valign: 'middle'
I18NFileChooserListView:
id: list_view
path: root.path
sort_func: root.sort_func
filters: root.filters
filter_dirs: root.filter_dirs
show_hidden: root.show_hidden
multiselect: root.multiselect
dirselect: root.dirselect
rootpath: root.rootpath
on_submit: root.dispatch('on_submit')
track_lang: i18n._('')
GridLayout:
size_hint: (1, None)
height: file_text.line_height * 2
cols: 2
rows: 2
spacing: [5]
TextInput:
id: file_text
text: (root.selection and (root._shorten_filenames(root.selection) if root.multiselect else root.selection[0])) or ''
hint_text: 'Filename'
multiline: False
Button:
id: select_button
size_hint_x: None
width: metrics.dp(100)
text: root.select_string
on_release: root.dispatch('on_success')
"""
)
class TreeLabel(TreeViewLabel):
path = StringProperty("")
"""Full path to the location this node points to.
:class:`~kivy.properties.StringProperty`, defaults to ''
"""
class LinkTree(TreeView):
# link to the favorites section of link bar
_favs = ObjectProperty(None)
_computer_node = None
def fill_tree(self, fav_list):
user_path = get_home_directory()
self._favs = self.add_node(TreeLabel(text="Favorites", is_open=True, no_selection=True))
self.reload_favs(fav_list)
libs = self.add_node(TreeLabel(text="Libraries", is_open=True, no_selection=True))
places = ("Documents", "Music", "Pictures", "Videos")
for place in places:
if isdir(join(user_path, place)):
self.add_node(TreeLabel(text=place, path=join(user_path, place)), libs)
self._computer_node = self.add_node(TreeLabel(text="Computer", is_open=True, no_selection=True))
self._computer_node.bind(on_touch_down=self._drives_touch)
self.reload_drives()
def _drives_touch(self, obj, touch):
if obj.collide_point(*touch.pos):
self.reload_drives()
def reload_drives(self):
nodes = [(node, node.text + node.path) for node in self._computer_node.nodes if isinstance(node, TreeLabel)]
sigs = [s[1] for s in nodes]
nodes_new = []
sig_new = []
for path, name in get_drives():
if platform == "win":
text = u"{}({})".format((name + " ") if name else "", path)
else:
text = name
nodes_new.append((text, path))
sig_new.append(text + path + sep)
for node, sig in nodes:
if sig not in sig_new:
self.remove_node(node)
for text, path in nodes_new:
if text + path + sep not in sigs:
self.add_node(TreeLabel(text=text, path=path + sep), self._computer_node)
def reload_favs(self, fav_list):
user_path = get_home_directory()
favs = self._favs
remove = []
for node in self.iterate_all_nodes(favs):
if node != favs:
remove.append(node)
for node in remove:
self.remove_node(node)
places = ("Desktop", "Downloads")
for place in places:
if isdir(join(user_path, place)):
self.add_node(TreeLabel(text=place, path=join(user_path, place)), favs)
for path, name in fav_list:
if isdir(path):
self.add_node(TreeLabel(text=name, path=path), favs)
def trigger_populate(self, node):
if not node.path or node.nodes:
return
parent = node.path
_next = next(walk(parent))
if _next:
for path in _next[1]:
self.add_node(TreeLabel(text=path, path=parent + sep + path), node)
class FileBrowser(BoxLayout):
"""FileBrowser class, see module documentation for more information.
"""
__events__ = ("on_success", "on_submit")
select_state = OptionProperty("normal", options=("normal", "down"))
"""State of the 'select' button, must be one of 'normal' or 'down'.
The state is 'down' only when the button is currently touched/clicked,
otherwise 'normal'. This button functions as the typical Ok/Select/Save
button.
:data:`select_state` is an :class:`~kivy.properties.OptionProperty`.
"""
select_string = StringProperty("Ok")
"""Label of the 'select' button.
:data:`select_string` is an :class:`~kivy.properties.StringProperty`,
defaults to 'Ok'.
"""
filename = StringProperty("")
"""The current text in the filename field. Read only. When multiselect is
True, the list of selected filenames is shortened. If shortened, filename
will contain an ellipsis.
:data:`filename` is an :class:`~kivy.properties.StringProperty`,
defaults to ''.
.. versionchanged:: 1.1
"""
selection = ListProperty([])
"""Read-only :class:`~kivy.properties.ListProperty`.
Contains the list of files that are currently selected in the current tab.
See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.selection`.
.. versionchanged:: 1.1
"""
path = StringProperty(u"/")
"""
:class:`~kivy.properties.StringProperty`, defaults to the current working
directory as a unicode string. It specifies the path on the filesystem that
browser should refer to.
See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.path`.
.. versionadded:: 1.1
"""
filters = ListProperty([])
""":class:`~kivy.properties.ListProperty`, defaults to [], equal to
``'*'``.
Specifies the filters to be applied to the files in the directory.
See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.filters`.
Filering keywords that the user types into the filter field as a comma
separated list will be reflected here.
.. versionadded:: 1.1
"""
filter_dirs = BooleanProperty(False)
"""
:class:`~kivy.properties.BooleanProperty`, defaults to False.
Indicates whether filters should also apply to directories.
See
:kivy_fchooser:`kivy.uix.filechooser.FileChooserController.filter_dirs`.
.. versionadded:: 1.1
"""
show_hidden = BooleanProperty(False)
"""
:class:`~kivy.properties.BooleanProperty`, defaults to False.
Determines whether hidden files and folders should be shown.
See
:kivy_fchooser:`kivy.uix.filechooser.FileChooserController.show_hidden`.
.. versionadded:: 1.1
"""
multiselect = BooleanProperty(False)
"""
:class:`~kivy.properties.BooleanProperty`, defaults to False.
Determines whether the user is able to select multiple files or not.
See
:kivy_fchooser:`kivy.uix.filechooser.FileChooserController.multiselect`.
.. versionadded:: 1.1
"""
dirselect = BooleanProperty(False)
"""
:class:`~kivy.properties.BooleanProperty`, defaults to False.
Determines whether directories are valid selections or not.
See
:kivy_fchooser:`kivy.uix.filechooser.FileChooserController.dirselect`.
.. versionadded:: 1.1
"""
rootpath = StringProperty(None, allownone=True)
"""
Root path to use instead of the system root path. If set, it will not show
a ".." directory to go up to the root path. For example, if you set
rootpath to /users/foo, the user will be unable to go to /users or to any
other directory not starting with /users/foo.
:class:`~kivy.properties.StringProperty`, defaults to None.
See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.rootpath`.
.. versionadded:: 1.1
"""
favorites = ListProperty([])
"""A list of the paths added to the favorites link bar. Each element
is a tuple where the first element is a string containing the full path
to the location, while the second element is a string with the name of
path to be displayed.
:data:`favorites` is an :class:`~kivy.properties.ListProperty`,
defaults to '[]'.
"""
sort_func = ObjectProperty(last_modified_first)
"""
Provides a function to be called with a list of filenames as the first
argument and the filesystem implementation as the second argument. It
returns a list of filenames sorted for display in the view."""
def on_success(self):
pass
def on_submit(self):
pass
def __init__(self, **kwargs):
super(FileBrowser, self).__init__(**kwargs)
Clock.schedule_once(self._post_init)
def _post_init(self, *largs):
self.ids.list_view.bind(
selection=partial(self._attr_callback, "selection"),
path=partial(self._attr_callback, "path"),
filters=partial(self._attr_callback, "filters"),
filter_dirs=partial(self._attr_callback, "filter_dirs"),
show_hidden=partial(self._attr_callback, "show_hidden"),
multiselect=partial(self._attr_callback, "multiselect"),
dirselect=partial(self._attr_callback, "dirselect"),
rootpath=partial(self._attr_callback, "rootpath"),
)
def _shorten_filenames(self, filenames):
if not len(filenames):
return ""
elif len(filenames) == 1:
return filenames[0]
elif len(filenames) == 2:
return filenames[0] + ", " + filenames[1]
else:
return filenames[0] + ", _..._, " + filenames[-1]
def _attr_callback(self, attr, obj, value):
setattr(self, attr, getattr(obj, attr))
if __name__ == "__main__":
import os
from kivy.app import App
class TestApp(App):
def build(self):
user_path = os.path.join(get_home_directory(), "Documents")
browser = FileBrowser(select_string="Select", favorites=[(user_path, "Documents")])
browser.bind(on_success=self._fbrowser_success, on_submit=self._fbrowser_submit)
box = BoxLayout(orientation="vertical")
box.add_widget(browser)
box.add_widget(Button(text="한국어 할 수 있나요?", on_press=lambda *_: i18n.switch_lang("ko"), size_hint=(1, 0.2)))
return box
def _fbrowser_success(self, instance):
print(instance.selection)
def _fbrowser_submit(self, instance):
print(instance.selection)
TestApp().run()
-40
View File
@@ -1,40 +0,0 @@
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
class TestBox(BoxLayout):
pass
KV = """
<TestBox>:
canvas.before:
Color:
rgba: [0,1,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
FileChooserListView:
id: filesel
multiselect: False
filters: ["*.sgf"]
path: "."
size_hint: 1,0.5
"""
Builder.load_string(KV)
class MyApp(App):
def build(self):
layout = TestBox()
return layout
MyApp().run()
-64
View File
@@ -1,64 +0,0 @@
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
class TestBox(GridLayout):
pass
KV = """
<Label>:
valign: 'top'
halign: 'right'
xtext: ''
text: 'size: {}\\ntexture_size: {}\\ntext_size: {}\\npos: {}\\n{}'.format(self.size,self.texture_size,self.text_size,self.pos,root.xtext)
canvas.before:
Color:
rgba: [1,0,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
<TestBox>:
canvas.before:
Color:
rgba: [0,1,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
cols: 2
rows: 2
Label:
xtext: 'size=texturesize'
size: self.texture_size
Label:
xtext: 'texturesize=size'
texture_size: self.size
Label:
xtext: 'textsize=size'
text_size: self.size
Label:
xtext: 'texturesize=textsize=size'
texture_size: self.size
text_size: self.size
"""
Builder.load_string(KV)
class MyApp(App):
def build(self):
layout = TestBox()
return layout
MyApp().run()
-170
View File
@@ -1,170 +0,0 @@
import kivy
from kivy.app import App
from kivy.core.text import Label as CoreLabel
from kivy.lang import Builder
from kivy.properties import (
BooleanProperty,
ListProperty,
NumericProperty,
ObjectProperty,
OptionProperty,
StringProperty,
)
from kivy.uix.behaviors import ButtonBehavior, ToggleButtonBehavior
from kivy.uix.button import Button
from kivy.uix.checkbox import CheckBox
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.widget import Widget
from kivymd.app import MDApp
from kivymd.uix.behaviors import CircularRippleBehavior, RectangularRippleBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import BaseFlatButton, BasePressedButton
from kivymd.uix.navigationdrawer import MDNavigationDrawer
WHITE = [1, 1, 1, 1]
class TestBox(GridLayout):
pass
class BackgroundMixin(Widget):
background_color = ListProperty([0, 0, 0, 0])
background_radius = NumericProperty(0)
outline_color = ListProperty([0, 0, 0, 0])
outline_width = NumericProperty(1)
class LeftButtonBehavior(ButtonBehavior): # stops buttons etc activating on right click
def __init__(self, **kwargs):
self.register_event_type("on_left_release")
self.register_event_type("on_left_press")
super().__init__(**kwargs)
def on_touch_down(self, touch):
return super().on_touch_down(touch)
def on_release(self):
if not self.last_touch or self.last_touch.button == "left":
self.dispatch("on_left_release")
return super().on_release()
def on_press(self):
if not self.last_touch or self.last_touch.button == "left":
self.dispatch("on_left_press")
return super().on_press()
def on_left_release(self):
pass
def on_left_press(self):
pass
class PauseButton(LeftButtonBehavior, Widget):
active = BooleanProperty(True)
active_line_color = WHITE
inactive_line_color = WHITE
active_fill_color = ListProperty([0.5, 0.5, 0.5, 1])
inactive_fill_color = ListProperty([1, 1, 1, 0])
line_width = NumericProperty(5)
fill_color = ListProperty([0.5, 0.5, 0.5, 1])
line_color = ListProperty([0.5, 0.5, 0.5, 1])
min_size = NumericProperty(100)
def on_left_press(self):
self.active = not self.active
KV = """
#:set LIGHTGREY [0.7,0.7,0.7,1]
#:set WHITE [1,1,1,1]
#:set BACKGROUND_COLOR [16/255,18/255,32/255,1]
#:set BOX_BACKGROUND_COLOR [46/255,65/255,88/255,1]
<BackgroundMixin>:
canvas.before:
Color:
rgba: root.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [root.background_radius, ]
Color:
rgba: root.outline_color
Line:
rounded_rectangle: (*self.pos,self.width,self.height,root.background_radius)
width: root.outline_width
<PauseButton>:
min_size: min(self.height,self.width)
line_color: root.active_line_color if self.active else root.inactive_line_color
fill_color: root.active_fill_color if self.active else root.inactive_fill_color
canvas:
Color:
rgba: root.fill_color
Ellipse:
pos: root.x + root.width/2 - root.min_size/2, root.y + root.height/2 - root.min_size/2
size: root.min_size,root.min_size
Color:
rgba: root.line_color
Line:
circle: root.x + root.width/2, root.y + root.height/2, root.min_size/2 - root.line_width/2
width: root.line_width
Line:
points: root.x + root.width/2 - root.min_size/8, root.y + root.height/2 - root.min_size/6, root.x + root.width/2 - root.min_size/8, root.y + root.height/2 + root.min_size/6
width: root.line_width
Line:
points: root.x + root.width/2 + root.min_size/8, root.y + root.height/2 - root.min_size/6, root.x + root.width/2 + root.min_size/8, root.y + root.height/2 + root.min_size/6
width: root.line_width
<BGBoxLayout@BoxLayout+BackgroundMixin>
background_color: BACKGROUND_COLOR
padding: 100
<TestBox>:
canvas.before:
Color:
rgba: [0,1,0,1]
Line:
rectangle: (*self.pos,*self.size)
width: 1
cols: 2
rows: 2
BGBoxLayout:
PauseButton:
size_hint: None, None
width: 100
height: 200
active: False
BGBoxLayout:
PauseButton:
size_hint: None, None
width: 200
height: 100
BGBoxLayout:
PauseButton:
size_hint: 0.5,0.5
"""
Builder.load_string(KV)
class MyApp(MDApp):
def __init__(self):
super().__init__()
def build(self):
layout = TestBox()
return layout
MyApp().run()
-13
View File
@@ -1,13 +0,0 @@
from datetime import datetime
import yappi
from katrain.__main__ import run_app
yappi.set_clock_type("cpu")
yappi.start()
try:
run_app()
except:
pass
yappi.get_func_stats().save("callgrind.out." + datetime.now().isoformat(), "CALLGRIND")
-115
View File
@@ -1,115 +0,0 @@
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()
-45
View File
@@ -1,45 +0,0 @@
from kivy.clock import Clock
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.textfield import MDTextField
class MyMDTextField(MDTextField):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(lambda dt: self.check_error(self.text), 0)
def check_error(self, text):
self.error = text != "correct"
print("checking error for", text, "->", self.error)
def on_text(self, widget, text):
self.check_error(text)
return super().on_text(widget, text)
KV = """
BoxLayout:
padding: "10dp"
MyMDTextField:
id: text_field_error
text: 'incorrect'
hint_text: "Helper text on error (press 'Enter')"
helper_text: "There will always be a mistake"
helper_text_mode: "on_error"
pos_hint: {"center_y": .5}
"""
class Test(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_string(KV)
def build(self):
return self.screen
Test().run()
+5 -7
View File
@@ -48,6 +48,7 @@ import string
from os.path import sep, dirname, expanduser, isdir, join, getmtime from os.path import sep, dirname, expanduser, isdir, join, getmtime
from os import walk from os import walk
from functools import partial from functools import partial
import warnings
from katrain.gui.style import DEFAULT_FONT from katrain.gui.style import DEFAULT_FONT
@@ -112,9 +113,9 @@ class I18NFileChooserListLayout(FileChooserListLayout):
_ENTRY_TEMPLATE = "I18NFileListEntry" _ENTRY_TEMPLATE = "I18NFileListEntry"
Builder.load_string( with warnings.catch_warnings():
""" warnings.simplefilter("ignore")
#:kivy 1.0 Builder.load_string("""
[I18NFileListEntry@FloatLayout+TreeViewNode]: [I18NFileListEntry@FloatLayout+TreeViewNode]:
locked: False locked: False
entries: [] entries: []
@@ -149,13 +150,10 @@ Builder.load_string(
I18NFileChooserListLayout: I18NFileChooserListLayout:
id: layout id: layout
controller: root controller: root
""" """)
)
Builder.load_string( Builder.load_string(
""" """
#:kivy 1.2.0
#:import metrics kivy.metrics #:import metrics kivy.metrics
#:import abspath os.path.abspath #:import abspath os.path.abspath
#:import i18n katrain.core.utils.i18n #:import i18n katrain.core.utils.i18n
Binary file not shown.
+386 -478
View File
@@ -1,14 +1,124 @@
# KaTrain i18n file # KaTrain localization file
msgid "" msgid ""
msgstr "" msgstr ""
"Language: Korean\n" "Language: English\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#. main hamburger menu
msgid "menu:playersetup"
msgstr "플레이어 설정"
msgid "menu:newgame"
msgstr "새로운 게임"
msgid "menu:save"
msgstr "SGF 파일 저장하기"
msgid "menu:load"
msgstr "SGF 파일 로드하기"
#. Engine as in the AI program powering the analysis
msgid "menu:settings"
msgstr "General & Engine Settings"
msgid "menu:clocksettings"
msgstr "시계 설정"
msgid "menu:teachsettings"
msgstr "Teaching Game 설정"
msgid "menu:aisettings"
msgstr "인공지능 설정"
msgid "menu:lang"
msgstr "언어"
#. as in help me
msgid "menu:support"
msgstr "Support"
msgid "menu:manual"
msgstr "설명서"
#. player options in the setup and on the right
msgid "player:type"
msgstr "Player"
msgid "player:human"
msgstr "Human"
msgid "player:ai"
msgstr "AI"
msgid "aistrategy"
msgstr "AI Strategy"
msgid "gametype"
msgstr "Game Type"
msgid "game:normal"
msgstr "Normal Game"
msgid "game:teach"
msgstr "Teaching Game"
#. buttons at the top - should all include a line break
msgid "analysis:nextmoves"
msgstr ""
"Next\n"
"Moves"
msgid "analysis:dots"
msgstr ""
"Show\n"
"Dots"
msgid "analysis:topmoves"
msgstr ""
"Top\n"
"Moves"
#. policy is really hard to translate - refering to (AlphaGo's) policy
#. network.
msgid "analysis:policy"
msgstr ""
"Policy\n"
"Moves"
msgid "analysis:territory"
msgstr ""
"Expected\n"
"Territory"
#. analysis menu items
msgid "analysis:extra"
msgstr "더 분석하기"
msgid "analysis:equalize"
msgstr "Equalize visits of potential moves"
msgid "analysis:sweep"
msgstr "다 수를 발리 분석하기"
msgid "analysis:aimove"
msgstr "Force AI Move"
#. right panel buttons and below board
msgid "pass-button-text" msgid "pass-button-text"
msgstr "패스" msgstr "패스"
msgid "ai-ponder"
msgstr ""
"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."
#. undo button on the right
msgid "undo-button-text"
msgstr "Undo"
#. tabs and labels on the right panel #. tabs and labels on the right panel
msgid "tab:score" msgid "tab:score"
msgstr "점수" msgstr "점수"
@@ -28,15 +138,19 @@ msgstr "Notes"
msgid "closedlabel:scoregraph" msgid "closedlabel:scoregraph"
msgstr "점수/확률 그래프" msgstr "점수/확률 그래프"
#. on the graph
msgid "Jigo"
msgstr "무승부"
msgid "closedlabel:movestats" msgid "closedlabel:movestats"
msgstr "수의 통계" msgstr "Move Stats"
msgid "closedlabel:info&notes" msgid "closedlabel:info&notes"
msgstr "수의 정보 & 메모" msgstr "Move Info & Notes"
#. on board in circle #. on the board after passing once/twice
msgid "board-pass" msgid "board-pass"
msgstr "패스" msgstr "pass"
msgid "board-game-end" msgid "board-game-end"
msgstr "" msgstr ""
@@ -50,6 +164,9 @@ msgstr "게임하기"
msgid "btn:Analysis" msgid "btn:Analysis"
msgstr "분석하기" msgstr "분석하기"
msgid "btn:Analyze"
msgstr "분석 옵션"
msgid "stats:winrate" msgid "stats:winrate"
msgstr "승리 확률" msgstr "승리 확률"
@@ -78,12 +195,17 @@ msgstr "승리 확률: {winrate}"
msgid "Info:point loss" msgid "Info:point loss"
msgstr "Estimated point loss: {points_lost:.1f}" msgstr "Estimated point loss: {points_lost:.1f}"
#. as in 'Move 125: B5'
msgid "move"
msgstr "Move"
msgid "Info:top move" msgid "Info:top move"
msgstr "Predicted top move was {top_move} ({score})." msgstr "Predicted top move was {top_move} ({score})."
msgid "Info:best move" msgid "Info:best move"
msgstr "Move was predicted best move" msgstr "Move was predicted best move"
#. Principal Variation (expected best sequence)
msgid "Info:PV" msgid "Info:PV"
msgstr "PV: {pv}" msgstr "PV: {pv}"
@@ -111,7 +233,204 @@ msgstr "Analyzing move..."
msgid "SGF Notes Hint" msgid "SGF Notes Hint"
msgstr "Your SGF notes for this position here." msgstr "Your SGF notes for this position here."
# sgf load popup
msgid "load sgf title"
msgstr "Load SGF File to Analyze"
msgid "load sgf fast analysis"
msgstr "Use fast analysis"
msgid "load sgf rewind"
msgstr "Rewind to start"
# timer settings from here
msgid "timer settings"
msgstr "Adjust Timer Settings"
msgid "byoyomi length"
msgstr "Time per Byo-yomi Period"
msgid "byoyomi periods"
msgstr "Number of Periods"
#. submit button
msgid "update timer"
msgstr "Update Timer"
# new game settings from here
msgid "New Game title"
msgstr "Setup New Game"
msgid "board size"
msgstr "Board size"
msgid "handicap"
msgstr "Handicap"
msgid "komi"
msgstr "Komi"
msgid "ruleset"
msgstr "Rules"
#. ruleset names
msgid "japanese"
msgstr "Japanese"
msgid "chinese"
msgstr "Chinese"
msgid "korean"
msgstr "Korean"
msgid "aga"
msgstr "AGA"
msgid "clear cache"
msgstr "Clear Cache"
#. clear cache help
msgid "avoids replaying"
msgstr ""
"Avoids replaying\n"
"identical games"
#. hints on new game
msgid "non square board hint"
msgstr "Use x:y (e.g. 19:9) for non-square size"
#. submit new game
msgid "new game"
msgstr "Start New Game"
# teacher settings from here
msgid "teacher settings"
msgstr "Edit Teacher Settings"
msgid "point loss threshold"
msgstr "Point loss greater than"
msgid "num undos"
msgstr "Number of undos per mistake"
msgid "num undos"
msgstr "Number of undos"
msgid "dot color"
msgstr "Colour (fixed)"
msgid "show dots"
msgstr "Show dots"
msgid "save dots"
msgstr "Save in SGF"
msgid "show last n dots"
msgstr ""
"Show dots for the last\n"
"<this many> moves"
msgid "show ai dots"
msgstr ""
"Show dots/SGF comments\n"
" for AI players"
msgid "lock ai when playing"
msgstr ""
"Disable analysis\n"
" while in play mode"
#. submit button
msgid "update teacher"
msgstr "Update Feedback Settings"
# main config settings
msgid "restarting engine"
msgstr "Restarting Engine after Settings Change."
# title
msgid "general settings title"
msgstr "General and Engine Settings"
msgid "file not found"
msgstr "Path does not exist"
msgid "general settings"
msgstr "General Settings"
msgid "engine settings"
msgstr "KataGo Engine Settings"
msgid "engine:katago"
msgstr "Path to KataGo executable"
msgid "engine:katago:hint"
msgstr "Leave blank to use included executable"
msgid "engine:model"
msgstr "Path to KataGo model file"
msgid "engine:config"
msgstr "Path to KataGo config file"
msgid "engine:config"
msgstr "Path to KataGo config file"
msgid "engine:max_visits"
msgstr "Maximum number of visits in analysis"
msgid "engine:fast_visits"
msgstr "Maximum number of visits in fast analysis"
msgid "engine:max_time"
msgstr "Maximum time for analysis"
msgid "engine:wide_root_noise"
msgstr "Wide root noise (increases variety of moves considered)"
msgid "engine:wide_root_noise:hint"
msgstr ""
"Use 0.02-0.1 to show\n"
"more possible moves"
msgid "engine:time:hint"
msgstr "Time in seconds"
msgid "general:sgf_load"
msgstr "Path for loading SGF files"
msgid "general:sgf_save"
msgstr "Path for saving SGF files"
msgid "general:anim_pv_time"
msgstr "Time between moves when animating a sequence"
msgid "general:debug_level"
msgstr "Debug level in the console"
msgid "general:debug_level:hint"
msgstr "Set to 1 when reporting errors"
msgid "update settings"
msgstr "Update Settings"
# ai settings from here
msgid "ai settings"
msgstr "Advanced AI Settings"
msgid "Select AI"
msgstr "Select AI strategy to configure"
msgid "update ai settings"
msgstr "Update AI Settings"
#. misc errors and info messages #. misc errors and info messages
msgid "sgf written"
msgstr "SGF with analysis written to {file_name}"
msgid "wait-before-equalize"
msgstr "Wait for initial analysis to complete before requesting a refinement."
msgid "Copied SGF to clipboard." msgid "Copied SGF to clipboard."
msgstr "Copied SGF to clipboard." msgstr "Copied SGF to clipboard."
@@ -131,7 +450,7 @@ msgstr ""
msgid "Starting Kata failed" msgid "Starting Kata failed"
msgstr "" msgstr ""
"Starting kata with command '{command}' failed with error {error}. Please " "Starting KataGo with command '{command}' failed with error {error}. Please "
"make sure the 'katago' value under 'engine' in settings points to the " "make sure the 'katago' value under 'engine' in settings points to the "
"correct KataGo executable." "correct KataGo executable."
@@ -140,260 +459,58 @@ msgstr ""
"Engine died unexpectedly without sending output, possibly due to out of " "Engine died unexpectedly without sending output, possibly due to out of "
"memory: {error}" "memory: {error}"
#. TODO #. AI names, help etc
msgid "analysis:territory" msgid "strength:kyu"
msgstr "k"
msgid "strength:dan"
msgstr "d"
msgid "ai:default"
msgstr "KataGo"
msgid "aihelp:default"
msgstr "" msgstr ""
"Expected\n" "Full strength KataGo AI. Strength is affected by `max_visits` and `model` "
"Territory" "in the general settings `engine` section and engine configuration file. No "
"options are available here."
#. TODO msgid "ai:jigo"
msgid "analysis:topmoves"
msgstr ""
"Top\n"
"Moves"
#. TODO
msgid "analysis:dots"
msgstr ""
"Show\n"
"Dots"
#. TODO
msgid "analysis:nextmoves"
msgstr ""
"다음 수\n"
"보기"
#. TODO
msgid "analysis:policy"
msgstr ""
"Policy\n"
"Moves"
#. TODO
msgid "ai-ponder"
msgstr ""
"이것은 Engine status이에요, going from green (idle) to orange (processing "
"queries). It turns red when the engine has crashed or fails to start."
#. TODO
msgid "menu:newgame"
msgstr "New Game"
#. TODO
msgid "menu:load"
msgstr "Load Game"
#. TODO
msgid "menu:save"
msgstr "Save Game"
#. TODO
msgid "menu:lang"
msgstr "Language"
#. TODO
msgid "menu:settings"
msgstr "General Settings"
#. TODO
msgid "menu:playersetup"
msgstr "Player Setup"
#. TODO
msgid "analysis:sweep"
msgstr "Fast analysis of all mㅇves"
#. 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 "undo-button-text"
msgstr "Undo"
#. TODO
msgid "menu:support"
msgstr "Support or Contribute"
#. TODO
msgid "wait-before-equalize"
msgstr "Wait for initial analysis to complete before requesting a refinement."
#. TODO
msgid "game:teaching"
msgstr "Teaching Game"
#. TODO
msgid "aistrategy"
msgstr "AI Strategy"
msgid "game:normal"
msgstr "일반 게임"
msgid "player:human"
msgstr "인간"
msgid "player:type"
msgstr "인간/인곡지능"
msgid "gametype"
msgstr "게임 종류"
msgid "player:ai"
msgstr "인곡지능"
msgid "game:teach"
msgstr "교직 게임"
#. TODO
msgid "menu:clocksettings"
msgstr "Timer Settings"
#. TODO
msgid "menu:teachsettings"
msgstr "Teaching Game Settings"
#. TODO
msgid "menu:aisettings"
msgstr "AI Settings"
#. TODO
msgid "timer settings"
msgstr "Adjust Timer Settings"
#. TODO
msgid "update timer"
msgstr "Update Timer Settings"
#. TODO
msgid "byoyomi length"
msgstr "Time per 뵤요미 Period"
#. TODO
msgid "byoyomi periods"
msgstr "Number of 뵤요미"
#. TODO
msgid "japanese"
msgstr "Japanese Rules"
#. TODO
msgid "aga"
msgstr "American Go Association Rules"
#. TODO
msgid "new game"
msgstr "Start New Game"
#. TODO
msgid "board size"
msgstr "Board size"
#. TODO
msgid "ruleset"
msgstr "Rules"
#. TODO
msgid "komi"
msgstr "Komi"
#. TODO
msgid "avoids replaying"
msgstr ""
"'avoids replaying\n"
"identical games"
#. TODO
msgid "clear cache"
msgstr "Clear Cache"
#. TODO
msgid "korean"
msgstr "Korean Rules"
#. TODO
msgid "chinese"
msgstr "Chinese Rules"
#. TODO
msgid "non square board hint"
msgstr "Use x:y (e.g. 19:9) to play on a non-square board."
#. TODO
msgid "handicap"
msgstr "Handicap"
#. TODO
msgid "handicap hint"
msgstr "Note that handicaps above 9 are not supported on non-square boards."
#. TODO
msgid "New Game title"
msgstr "Setup New Game"
#. TODO
msgid "sgf written"
msgstr "SGF with analysis written to {file_name}"
#. TODO
msgid "ainame:jigo"
msgstr "KataJigo" msgstr "KataJigo"
#. TODO msgid "aihelp:jigo"
msgstr ""
"Will try to win by a set amount of points (default 0.5), without further "
"restrictions."
msgid "ai:jigo"
msgstr "KataJigo"
msgid "aihelp:jigo"
msgstr ""
"Will try to win by a set amount of points (default 0.5), without further "
"restrictions."
msgid "ai:scoreloss"
msgstr "Score Loss"
msgid "aihelp:scoreloss"
msgstr ""
"Plays moves that lead to more points lost with lower probability. Likely to "
"play more varied/weaker with higher visits settings."
msgid "ai:policy"
msgstr "Policy"
msgid "aihelp:policy" msgid "aihelp:policy"
msgstr "" msgstr ""
"Plays the top move from the policy network, without any reading. Strength is" "Plays the top move from the policy network, without any reading. Strength is"
" mainly affected by `model` in engine settings. The opening moves setting " " mainly affected by `model` in engine settings. The opening moves setting "
"affects how many moves in the opening are more random." "affects how many moves in the opening are more random."
#. TODO msgid "ai:p:weighted"
msgid "ainame:policy" msgstr "Policy Weighted"
msgstr "Policy"
#. TODO
msgid "ainame:scoreloss"
msgstr "Score Loss"
#. TODO
msgid "aihelp:default"
msgstr ""
"Full strength KataGo AI. Strength is mainly affected by `max_visits` and "
"`model` in the general settings `engine` section."
#. TODO
msgid "aihelp:jigo"
msgstr ""
"Will try to win by a set amount of points (default 0.5), without further "
"restrictions."
#. TODO
msgid "aihelp:scoreloss"
msgstr ""
"Plays moves that lead to more points lost with lower probability. Likely to "
"play more varied/weaker with higher visits settings."
#. TODO
msgid "ainame:default"
msgstr "KataGo"
#. TODO
msgid "strength:kyu"
msgstr "k"
#. TODO
msgid "strength:dan"
msgstr "d"
#. TODO
msgid "aihelp:p:weighted" msgid "aihelp:p:weighted"
msgstr "" msgstr ""
"Plays moves according to policy probability, with `weaken_fac` influencing " "Plays moves according to policy probability, with `weaken_fac` influencing "
@@ -402,257 +519,48 @@ msgstr ""
"without randomness, and `lower_bound` determines the lower bound policy " "without randomness, and `lower_bound` determines the lower bound policy "
"value that is allowed." "value that is allowed."
#. TODO msgid "ai:p:pick"
msgstr "Blinded Policy"
msgid "aihelp:p:pick" msgid "aihelp:p:pick"
msgstr "" msgstr ""
"Picks `pick_n + pick_frac * <number of legal moves>` at random and plays the" "Picks `pick_n + pick_frac * <number of legal moves>` at random and plays the"
" best one. For `pick_frac=1` plays like the `Policy` AI. Plays top move if " " best one. For `pick_frac=1` plays like the `Policy` AI. Plays top move if "
"policy value is above `pick_override` to avoid obvious mistakes." "policy value is above `pick_override` to avoid obvious mistakes."
#. TODO
msgid "ai:p:influence"
msgstr "Influential Style"
#. TODO
msgid "ai:p:local" msgid "ai:p:local"
msgstr "Respond Locally" msgstr "Local Style"
msgid "aihelp:p:local"
msgstr ""
"Picks `pick_n + pick_frac * <number of legal moves>` weighted towards the "
"last move and plays the best one. Plays top move if policy value is above "
"`pick_override` to avoid obvious mistakes."
msgid "ai:p:tenuki"
msgstr "Tenuki Style"
#. TODO
msgid "aihelp:p:tenuki" msgid "aihelp:p:tenuki"
msgstr "" msgstr ""
"Picks `pick_n + pick_frac * <number of legal moves>` weighted away from the " "Picks `pick_n + pick_frac * <number of legal moves>` weighted away from the "
"last move and plays the best one. Plays top move if policy value is above " "last move and plays the best one. Plays top move if policy value is above "
"`pick_override` to avoid obvious mistakes." "`pick_override` to avoid obvious mistakes. A higher `stddev` makes it play "
"further away."
#. TODO msgid "ai:p:influence"
msgid "ai:scoreloss" msgstr "Influential Style"
msgstr "Score Loss"
#. TODO
msgid "aihelp:p:influence" msgid "aihelp:p:influence"
msgstr "" msgstr ""
"Picks moves biased above the `threshold` line and plays the best " "Picks moves biased above the `threshold` line and plays the best "
"one.Increase `line_weight` to penalize moves near the edge more. Stops " "one.Increase `line_weight` to penalize moves near the edge more. Stops "
"strategy after the 'endgame' fraction of the board is filled." "strategy after the 'endgame' fraction of the board is filled."
#. TODO msgid "ai:p:territory"
msgid "ai:default" msgstr "Territorial Style"
msgstr "KataGo"
#. TODO
msgid "ai:p:tenuki"
msgstr "Tenuki Style"
#. TODO
msgid "ai:p:pick"
msgstr "Blinded Policy"
#. TODO
msgid "ai:p:weighted"
msgstr "Policy Weighted"
#. TODO
msgid "ai:policy"
msgstr "Policy"
#. TODO
msgid "ai:jigo"
msgstr "KataJigo"
#. TODO
msgid "aihelp:p:local"
msgstr ""
"Picks moves biased below the `threshold` line and plays the best "
"one.Increase `line_weight` to penalize moves near the center more. Stops "
"strategy after the 'endgame' fraction of the board is filled."
#. TODO
msgid "aihelp:p:territory" msgid "aihelp:p:territory"
msgstr "" msgstr ""
"Picks moves biased below the `threshold` line and plays the best " "Picks moves biased below the `threshold` line and plays the best "
"one.Increase `line_weight` to penalize moves near the center more. Stops " "one.Increase `line_weight` to penalize moves near the center more. Stops "
"strategy after the 'endgame' fraction of the board is filled." "strategy after the 'endgame' fraction of the board is filled."
#. TODO
msgid "ai:p:territory"
msgstr "Respond Locally"
#. TODO
msgid "save dots"
msgstr "Save in SGF"
#. TODO
msgid "num undos"
msgstr "Number of undos"
#. TODO
msgid "teacher settings"
msgstr "Edit Teacher Settings"
#. TODO
msgid "show dots"
msgstr "Show dots"
#. TODO
msgid "point loss threshold"
msgstr "Point loss greater than"
#. TODO
msgid "dot color"
msgstr "Colour (fixed)"
#. TODO
msgid "show ai dots"
msgstr "Show dots/SGF comments for AI players"
#. TODO
msgid "restarting engine"
msgstr "Restarting Engine after Settings Change."
#. TODO
msgid "lock ai when teaching"
msgstr "Disable analysis while in teach mode"
#. TODO
msgid "show last n dots"
msgstr "Show dots for the last <this many> moves"
#. TODO
msgid "update teacher"
msgstr "Update Teaching Game Settings"
#. TODO
msgid "engine:max_visits"
msgstr "Maximum number of visits in analysis"
#. TODO
msgid "general settings"
msgstr "General Settings"
#. TODO
msgid "update settings"
msgstr "Update Settings"
#. TODO
msgid "engine:max_time"
msgstr "Maximum time for analysis"
#. TODO
msgid "engine:fast_visits"
msgstr "Maximum number of visits in fast analysis"
#. TODO
msgid "engine:config"
msgstr "Path to KataGo config file"
#. TODO
msgid "general:sgf_save"
msgstr "Path for saving SGF files"
#. TODO
msgid "general:sgf_load"
msgstr "Path for loading SGF files"
#. TODO
msgid "general:debug_level"
msgstr "Debug level in the console"
#. TODO
msgid "general settings title"
msgstr "General and Engine Settings"
#. TODO
msgid "engine settings"
msgstr "KataGo Engine Settings"
#. TODO
msgid "engine:model"
msgstr "Path to KataGo model file"
#. TODO
msgid "general:anim_pv_time"
msgstr "Time between moves when animating a sequence"
#. TODO
msgid "engine:katago"
msgstr "Path to KataGo executable"
#. TODO
msgid "general:debug_level:hint"
msgstr "Use 0 for little output, 1 for getting details when reporting errors"
#. TODO
msgid "engine:max_time:hint"
msgstr "Time in seconds"
#. TODO
msgid "engine:time:hint"
msgstr "Time in seconds"
#. TODO
msgid "engine:katago:hint"
msgstr "Leave blank to use included executable"
#. TODO
msgid "file not found"
msgstr "Path does not exist"
#. TODO
msgid "engine:wide_root_noise:hint"
msgstr ""
"Use a value of 0.02-0.1 to show more possible moves, at the cost of "
"weakening analysis."
#. TODO
msgid "engine:wide_root_noise"
msgstr "Wide root noise (increases variety of moves considered)"
#. TODO
msgid "lock ai when playing"
msgstr ""
"Disable analysis\n"
" while in play mode"
#. TODO
msgid "update ai settings"
msgstr "Update AI Settings"
#. TODO
msgid "Select AI"
msgstr "Select AI strategy to configure"
#. TODO
msgid "load sgf rewind"
msgstr "Rewind to start"
#. TODO
msgid "load sgf fast analysis"
msgstr "Use fast analysis"
#. TODO
msgid "load sgf title"
msgstr "Load SGF File to Analyze"
#. TODO
msgid "btn:Analyze"
msgstr "Analyze"
#. TODO
msgid "menu:homepage"
msgstr "Homepage"
#. TODO
msgid "menu:manual"
msgstr "Manual"
#. TODO
msgid "ai settings"
msgstr "Advanced AI Settings"
#. TODO
msgid "move"
msgstr "Move"
#. TODO
msgid "Jigo"
msgstr "Jigo"
+2
View File
@@ -18,8 +18,10 @@ def include_data_files(directory):
include_data_files("katrain/KataGo") include_data_files("katrain/KataGo")
include_data_files("katrain/models") include_data_files("katrain/models")
include_data_files("katrain/fonts")
include_data_files("katrain/img/") include_data_files("katrain/img/")
include_data_files("katrain/img/flaticon") include_data_files("katrain/img/flaticon")
include_data_files("katrain/i18n")
print(packages, package_data) print(packages, package_data)