1341 lines
42 KiB
Plaintext
1341 lines
42 KiB
Plaintext
|
#:kivy 1.0
|
||
|
|
||
|
<Label>:
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: 1, 1, 1, 1
|
||
|
Rectangle:
|
||
|
texture: self.texture
|
||
|
size: self.texture_size
|
||
|
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
|
||
|
|
||
|
<-Button,-ToggleButton>:
|
||
|
state_image: self.background_normal if self.state == 'normal' else self.background_down
|
||
|
disabled_image: self.background_disabled_normal if self.state == 'normal' else self.background_disabled_down
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.background_color
|
||
|
BorderImage:
|
||
|
border: self.border
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
source: self.disabled_image if self.disabled else self.state_image
|
||
|
Color:
|
||
|
rgba: 1, 1, 1, 1
|
||
|
Rectangle:
|
||
|
texture: self.texture
|
||
|
size: self.texture_size
|
||
|
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
|
||
|
|
||
|
<BubbleContent>
|
||
|
opacity: .7 if self.disabled else 1
|
||
|
orientation: "horizontal"
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.background_color
|
||
|
BorderImage:
|
||
|
border: self.border
|
||
|
source: self.background_image
|
||
|
size: self.size
|
||
|
pos: self.pos
|
||
|
auto_scale: self.border_auto_scale
|
||
|
|
||
|
<BubbleButton>:
|
||
|
background_normal: 'atlas://data/images/defaulttheme/bubble_btn'
|
||
|
background_down: 'atlas://data/images/defaulttheme/bubble_btn_pressed'
|
||
|
background_disabled_normal: 'atlas://data/images/defaulttheme/bubble_btn'
|
||
|
background_disabled_down: 'atlas://data/images/defaulttheme/bubble_btn_pressed'
|
||
|
border: (0, 0, 0, 0)
|
||
|
|
||
|
<Slider>:
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgb: 1, 1, 1
|
||
|
BorderImage:
|
||
|
border: self.border_horizontal if self.orientation == 'horizontal' else self.border_vertical
|
||
|
pos: (self.x + self.padding, self.center_y - self.background_width / 2) if self.orientation == 'horizontal' else (self.center_x - self.background_width / 2, self.y + self.padding)
|
||
|
size: (self.width - self.padding * 2, self.background_width) if self.orientation == 'horizontal' else (self.background_width, self.height - self.padding * 2)
|
||
|
source: (self.background_disabled_horizontal if self.orientation == 'horizontal' else self.background_disabled_vertical) if self.disabled else (self.background_horizontal if self.orientation == 'horizontal' else self.background_vertical)
|
||
|
Color:
|
||
|
rgba: root.value_track_color if self.value_track and self.orientation == 'horizontal' else [1, 1, 1, 0]
|
||
|
Line:
|
||
|
width: self.value_track_width
|
||
|
points: self.x + self.padding, self.center_y, self.value_pos[0], self.center_y
|
||
|
Color:
|
||
|
rgba: root.value_track_color if self.value_track and self.orientation == 'vertical' else [1, 1, 1, 0]
|
||
|
Line:
|
||
|
width: self.value_track_width
|
||
|
points: self.center_x, self.y + self.padding, self.center_x, self.value_pos[1]
|
||
|
Color:
|
||
|
rgb: 1, 1, 1
|
||
|
Image:
|
||
|
pos: (root.value_pos[0] - root.cursor_width / 2, root.center_y - root.cursor_height / 2) if root.orientation == 'horizontal' else (root.center_x - root.cursor_width / 2, root.value_pos[1] - root.cursor_height / 2)
|
||
|
size: root.cursor_size
|
||
|
source: root.cursor_disabled_image if root.disabled else root.cursor_image
|
||
|
fit_mode: "fill"
|
||
|
|
||
|
<ProgressBar>:
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgb: 1, 1, 1
|
||
|
BorderImage:
|
||
|
border: (12, 12, 12, 12)
|
||
|
pos: self.x, self.center_y - 12
|
||
|
size: self.width, 24
|
||
|
source: 'atlas://data/images/defaulttheme/progressbar_background'
|
||
|
BorderImage:
|
||
|
border: [int(min(self.width * (self.value / float(self.max)) if self.max else 0, 12))] * 4
|
||
|
pos: self.x, self.center_y - 12
|
||
|
size: self.width * (self.value / float(self.max)) if self.max else 0, 24
|
||
|
source: 'atlas://data/images/defaulttheme/progressbar'
|
||
|
|
||
|
<SplitterStrip>:
|
||
|
border: self.parent.border if self.parent else (3, 3, 3, 3)
|
||
|
horizontal: '_h' if self.parent and self.parent.sizable_from[0] in ('t', 'b') else ''
|
||
|
background_normal: 'atlas://data/images/defaulttheme/splitter{}{}'.format('_disabled' if self.disabled else '', self.horizontal)
|
||
|
background_down: 'atlas://data/images/defaulttheme/splitter_down{}{}'.format('_disabled' if self.disabled else '', self.horizontal)
|
||
|
Image:
|
||
|
pos: root.pos
|
||
|
size: root.size
|
||
|
fit_mode: "contain"
|
||
|
source: 'atlas://data/images/defaulttheme/splitter_grip' + root.horizontal
|
||
|
|
||
|
<Scatter>:
|
||
|
canvas.before:
|
||
|
PushMatrix
|
||
|
MatrixInstruction:
|
||
|
matrix: self.transform
|
||
|
canvas.after:
|
||
|
PopMatrix
|
||
|
|
||
|
|
||
|
<RelativeLayout>:
|
||
|
canvas.before:
|
||
|
PushMatrix
|
||
|
Translate:
|
||
|
xy: self.pos
|
||
|
canvas.after:
|
||
|
PopMatrix
|
||
|
|
||
|
<Image,AsyncImage>:
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.color
|
||
|
StencilPush
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
StencilUse
|
||
|
Rectangle:
|
||
|
texture: self.texture
|
||
|
size: self.norm_image_size
|
||
|
pos: self.center_x - self.norm_image_size[0] / 2., self.center_y - self.norm_image_size[1] / 2.
|
||
|
StencilUnUse
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
StencilPop
|
||
|
|
||
|
<EffectWidget>:
|
||
|
canvas.before:
|
||
|
Translate:
|
||
|
xy: -self.x, -self.y
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: 1, 1, 1, 1
|
||
|
Rectangle:
|
||
|
texture: self.texture
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
|
||
|
<TabbedPanelContent>
|
||
|
rows: 1
|
||
|
padding: 3
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.parent.background_color if self.parent else (1, 1, 1, 1)
|
||
|
BorderImage:
|
||
|
border: self.parent.border if self.parent else (16, 16, 16, 16)
|
||
|
source: (root.parent.background_disabled_image if self.disabled else root.parent.background_image) if root.parent else None
|
||
|
size: self.size
|
||
|
pos: self.pos
|
||
|
|
||
|
<TabbedPanelStrip>
|
||
|
rows: 1
|
||
|
|
||
|
<StripLayout>
|
||
|
padding: '2dp', '2dp', '2dp', '2dp'
|
||
|
canvas.before:
|
||
|
BorderImage:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
border: root.border
|
||
|
source: root.background_image
|
||
|
|
||
|
<TabbedPanelHeader>:
|
||
|
halign: 'center'
|
||
|
valign: 'middle'
|
||
|
background_normal: 'atlas://data/images/defaulttheme/tab_btn'
|
||
|
background_disabled_normal: 'atlas://data/images/defaulttheme/tab_btn_disabled'
|
||
|
background_down: 'atlas://data/images/defaulttheme/tab_btn_pressed'
|
||
|
background_disabled_down: 'atlas://data/images/defaulttheme/tab_btn_pressed'
|
||
|
border: (8, 8, 8, 8)
|
||
|
font_size: '15sp'
|
||
|
|
||
|
<Selector>
|
||
|
color: 148. / 255, 208 / 255., 230 / 255., 1
|
||
|
fit_mode: "contain"
|
||
|
|
||
|
<TextInput>:
|
||
|
canvas.before:
|
||
|
Color:
|
||
|
rgba: self.background_color
|
||
|
BorderImage:
|
||
|
border: self.border
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
source: self.background_active if self.focus else (self.background_disabled_normal if self.disabled else self.background_normal)
|
||
|
Color:
|
||
|
rgba:
|
||
|
(self.cursor_color
|
||
|
if self.focus and not self._cursor_blink
|
||
|
and int(self.x + self.padding[0]) <= self._cursor_visual_pos[0] <= int(self.x + self.width - self.padding[2])
|
||
|
else (0, 0, 0, 0))
|
||
|
Rectangle:
|
||
|
pos: self._cursor_visual_pos
|
||
|
size: root.cursor_width, -self._cursor_visual_height
|
||
|
Color:
|
||
|
rgba: self.disabled_foreground_color if self.disabled else (self.hint_text_color if not self.text else self.foreground_color)
|
||
|
|
||
|
<TextInputCutCopyPaste>:
|
||
|
content: content.__self__
|
||
|
but_cut: cut.__self__
|
||
|
but_copy: copy.__self__
|
||
|
but_paste: paste.__self__
|
||
|
but_selectall: selectall.__self__
|
||
|
|
||
|
size_hint: None, None
|
||
|
size: '150sp', '50sp'
|
||
|
BubbleContent:
|
||
|
id: content
|
||
|
BubbleButton:
|
||
|
id: cut
|
||
|
text: 'Cut'
|
||
|
on_release: root.do('cut')
|
||
|
BubbleButton:
|
||
|
id: copy
|
||
|
text: 'Copy'
|
||
|
on_release: root.do('copy')
|
||
|
BubbleButton:
|
||
|
id: paste
|
||
|
text: 'Paste'
|
||
|
on_release: root.do('paste')
|
||
|
BubbleButton:
|
||
|
id: selectall
|
||
|
text: 'Select All'
|
||
|
on_release: root.do('selectall')
|
||
|
|
||
|
<CodeInput>:
|
||
|
font_name: 'data/fonts/RobotoMono-Regular.ttf'
|
||
|
|
||
|
|
||
|
<TreeViewNode>:
|
||
|
canvas.before:
|
||
|
Color:
|
||
|
rgba: self.color_selected if self.is_selected else self.odd_color if self.odd else self.even_color
|
||
|
Rectangle:
|
||
|
pos: [self.parent.x, self.y] if self.parent else [0, 0]
|
||
|
size: [self.parent.width, self.height] if self.parent else [1, 1]
|
||
|
Color:
|
||
|
rgba: 1, 1, 1, int(not self.is_leaf)
|
||
|
Rectangle:
|
||
|
source: 'atlas://data/images/defaulttheme/tree_%s' % ('opened' if self.is_open else 'closed')
|
||
|
size: self.height / (3. if dp(1) > 1 else 2.), self.height / (3. if dp(1) > 1 else 2.)
|
||
|
pos: self.x - dp(20), int(self.center_y - (self.height / (3. if dp(1) > 1 else 2.)) * .5)
|
||
|
canvas.after:
|
||
|
Color:
|
||
|
rgba: .5, .5, .5, .2
|
||
|
Line:
|
||
|
points: [self.parent.x, self.y, self.parent.right, self.y] if self.parent else []
|
||
|
|
||
|
|
||
|
<TreeViewLabel>:
|
||
|
width: self.texture_size[0]
|
||
|
height: max(self.texture_size[1] + dp(10), dp(24))
|
||
|
text_size: self.width, None
|
||
|
|
||
|
|
||
|
<StencilView>:
|
||
|
canvas.before:
|
||
|
StencilPush
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
StencilUse
|
||
|
|
||
|
canvas.after:
|
||
|
StencilUnUse
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
StencilPop
|
||
|
|
||
|
|
||
|
<FileChooserListLayout>:
|
||
|
on_entry_added: treeview.add_node(args[1])
|
||
|
on_entries_cleared: treeview.root.nodes = []
|
||
|
on_subentry_to_entry: not args[2].locked and treeview.add_node(args[1], args[2])
|
||
|
on_remove_subentry: args[2].nodes = []
|
||
|
BoxLayout:
|
||
|
pos: root.pos
|
||
|
size: root.size
|
||
|
size_hint: None, None
|
||
|
orientation: 'vertical'
|
||
|
BoxLayout:
|
||
|
size_hint_y: None
|
||
|
height: '30dp'
|
||
|
orientation: 'horizontal'
|
||
|
Widget:
|
||
|
# Just for spacing
|
||
|
width: '10dp'
|
||
|
size_hint_x: None
|
||
|
Label:
|
||
|
text: 'Name'
|
||
|
text_size: self.size
|
||
|
halign: 'left'
|
||
|
bold: True
|
||
|
Label:
|
||
|
text: 'Size'
|
||
|
text_size: self.size
|
||
|
size_hint_x: None
|
||
|
halign: 'right'
|
||
|
bold: True
|
||
|
Widget:
|
||
|
# Just for spacing
|
||
|
width: '10dp'
|
||
|
size_hint_x: None
|
||
|
ScrollView:
|
||
|
id: scrollview
|
||
|
do_scroll_x: False
|
||
|
Scatter:
|
||
|
do_rotation: False
|
||
|
do_scale: False
|
||
|
do_translation: False
|
||
|
size: treeview.size
|
||
|
size_hint_y: None
|
||
|
TreeView:
|
||
|
id: treeview
|
||
|
hide_root: True
|
||
|
size_hint_y: None
|
||
|
width: scrollview.width
|
||
|
height: self.minimum_height
|
||
|
on_node_expand: root.controller.entry_subselect(args[1])
|
||
|
on_node_collapse: root.controller.close_subselection(args[1])
|
||
|
|
||
|
<FileChooserListView>:
|
||
|
layout: layout
|
||
|
FileChooserListLayout:
|
||
|
id: layout
|
||
|
controller: root
|
||
|
|
||
|
[FileListEntry@FloatLayout+TreeViewNode]:
|
||
|
locked: False
|
||
|
entries: []
|
||
|
path: ctx.path
|
||
|
# FIXME: is_selected is actually a read_only treeview property. In this
|
||
|
# case, however, we're doing this because treeview only has single-selection
|
||
|
# hardcoded in it. The fix to this would be to update treeview to allow
|
||
|
# multiple selection.
|
||
|
is_selected: self.path in ctx.controller().selection
|
||
|
|
||
|
orientation: 'horizontal'
|
||
|
size_hint_y: None
|
||
|
height: '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())
|
||
|
font_name: ctx.controller().font_name
|
||
|
|
||
|
<FileChooserIconLayout>:
|
||
|
on_entry_added: stacklayout.add_widget(args[1])
|
||
|
on_entries_cleared: stacklayout.clear_widgets()
|
||
|
ScrollView:
|
||
|
id: scrollview
|
||
|
pos: root.pos
|
||
|
size: root.size
|
||
|
size_hint: None, None
|
||
|
do_scroll_x: False
|
||
|
Scatter:
|
||
|
do_rotation: False
|
||
|
do_scale: False
|
||
|
do_translation: False
|
||
|
size_hint_y: None
|
||
|
height: stacklayout.height
|
||
|
StackLayout:
|
||
|
id: stacklayout
|
||
|
width: scrollview.width
|
||
|
size_hint_y: None
|
||
|
height: self.minimum_height
|
||
|
spacing: '10dp'
|
||
|
padding: '10dp'
|
||
|
|
||
|
<FileChooserIconView>:
|
||
|
layout: layout
|
||
|
FileChooserIconLayout:
|
||
|
id: layout
|
||
|
controller: root
|
||
|
|
||
|
[FileIconEntry@Widget]:
|
||
|
locked: False
|
||
|
path: ctx.path
|
||
|
selected: self.path in ctx.controller().selection
|
||
|
size_hint: None, None
|
||
|
|
||
|
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])
|
||
|
size: '100dp', '100dp'
|
||
|
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: 1, 1, 1, 1 if self.selected else 0
|
||
|
BorderImage:
|
||
|
border: 8, 8, 8, 8
|
||
|
pos: root.pos
|
||
|
size: root.size
|
||
|
source: 'atlas://data/images/defaulttheme/filechooser_selected'
|
||
|
|
||
|
Image:
|
||
|
size: '48dp', '48dp'
|
||
|
source: 'atlas://data/images/defaulttheme/filechooser_%s' % ('folder' if ctx.isdir else 'file')
|
||
|
pos: root.x + dp(24), root.y + dp(40)
|
||
|
Label:
|
||
|
text: ctx.name
|
||
|
font_name: ctx.controller().font_name
|
||
|
text_size: (root.width, self.height)
|
||
|
halign: 'center'
|
||
|
shorten: True
|
||
|
size: '100dp', '16dp'
|
||
|
pos: root.x, root.y + dp(16)
|
||
|
Label:
|
||
|
text: '{}'.format(ctx.get_nice_size())
|
||
|
font_name: ctx.controller().font_name
|
||
|
font_size: '11sp'
|
||
|
color: .8, .8, .8, 1
|
||
|
size: '100dp', '16sp'
|
||
|
pos: root.pos
|
||
|
halign: 'center'
|
||
|
|
||
|
<FileChooserProgress>:
|
||
|
pos_hint: {'x': 0, 'y': 0}
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: 0, 0, 0, .8
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
Label:
|
||
|
pos_hint: {'x': .2, 'y': .6}
|
||
|
size_hint: .6, .2
|
||
|
text: 'Opening %s' % root.path
|
||
|
text_size: self.size
|
||
|
halign: 'center'
|
||
|
valign: 'middle'
|
||
|
FloatLayout:
|
||
|
pos_hint: {'x': .2, 'y': .4}
|
||
|
size_hint: .6, .2
|
||
|
ProgressBar:
|
||
|
id: pb
|
||
|
pos_hint: {'x': 0, 'center_y': .5}
|
||
|
max: root.total
|
||
|
value: root.index
|
||
|
Label:
|
||
|
pos_hint: {'x': 0}
|
||
|
text: '%d / %d' % (root.index, root.total)
|
||
|
size_hint_y: None
|
||
|
height: self.texture_size[1]
|
||
|
y: pb.center_y - self.height - 8
|
||
|
font_size: '13sp'
|
||
|
color: (.8, .8, .8, .8)
|
||
|
|
||
|
AnchorLayout:
|
||
|
pos_hint: {'x': .2, 'y': .2}
|
||
|
size_hint: .6, .2
|
||
|
|
||
|
Button:
|
||
|
text: 'Cancel'
|
||
|
size_hint: None, None
|
||
|
size: 150, 44
|
||
|
on_release: root.cancel()
|
||
|
|
||
|
|
||
|
|
||
|
# Switch widget
|
||
|
<Switch>:
|
||
|
active_norm_pos: max(0., min(1., (int(self.active) + self.touch_distance / sp(41))))
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgb: 1, 1, 1
|
||
|
Rectangle:
|
||
|
source: 'atlas://data/images/defaulttheme/switch-background{}'.format('_disabled' if self.disabled else '')
|
||
|
size: sp(83), sp(32)
|
||
|
pos: int(self.center_x - sp(41)), int(self.center_y - sp(16))
|
||
|
canvas.after:
|
||
|
Color:
|
||
|
rgb: 1, 1, 1
|
||
|
Rectangle:
|
||
|
source: 'atlas://data/images/defaulttheme/switch-button{}'.format('_disabled' if self.disabled else '')
|
||
|
size: sp(43), sp(32)
|
||
|
pos: int(self.center_x - sp(41) + self.active_norm_pos * sp(41)), int(self.center_y - sp(16))
|
||
|
|
||
|
|
||
|
# ModalView widget
|
||
|
<ModalView>:
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: root.overlay_color[:3] + [root.overlay_color[-1] * self._anim_alpha]
|
||
|
Rectangle:
|
||
|
size: self._window.size if self._window else (0, 0)
|
||
|
|
||
|
Color:
|
||
|
rgba: root.background_color
|
||
|
BorderImage:
|
||
|
source: root.background
|
||
|
border: root.border
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
|
||
|
|
||
|
# Popup widget
|
||
|
<Popup>:
|
||
|
_container: container
|
||
|
GridLayout:
|
||
|
padding: '12dp'
|
||
|
cols: 1
|
||
|
size_hint: None, None
|
||
|
pos: root.pos
|
||
|
size: root.size
|
||
|
|
||
|
Label:
|
||
|
text: root.title
|
||
|
color: root.title_color
|
||
|
size_hint_y: None
|
||
|
height: self.texture_size[1] + dp(16)
|
||
|
text_size: self.width - dp(16), None
|
||
|
font_size: root.title_size
|
||
|
font_name: root.title_font
|
||
|
halign: root.title_align
|
||
|
|
||
|
Widget:
|
||
|
size_hint_y: None
|
||
|
height: dp(4)
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: root.separator_color
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y + root.separator_height / 2.
|
||
|
size: self.width, root.separator_height
|
||
|
|
||
|
BoxLayout:
|
||
|
id: container
|
||
|
|
||
|
# =============================================================================
|
||
|
# Spinner widget
|
||
|
# =============================================================================
|
||
|
|
||
|
<SpinnerOption>:
|
||
|
size_hint_y: None
|
||
|
height: '48dp'
|
||
|
|
||
|
<Spinner>:
|
||
|
background_normal: 'atlas://data/images/defaulttheme/spinner'
|
||
|
background_disabled_normal: 'atlas://data/images/defaulttheme/spinner_disabled'
|
||
|
background_down: 'atlas://data/images/defaulttheme/spinner_pressed'
|
||
|
|
||
|
# =============================================================================
|
||
|
# ActionBar widget
|
||
|
# =============================================================================
|
||
|
|
||
|
<ActionBar>:
|
||
|
height: '48dp'
|
||
|
size_hint_y: None
|
||
|
spacing: '4dp'
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.background_color
|
||
|
BorderImage:
|
||
|
border: root.border
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
source: self.background_image
|
||
|
|
||
|
<ActionView>:
|
||
|
orientation: 'horizontal'
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.background_color
|
||
|
BorderImage:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
source: self.background_image
|
||
|
|
||
|
<ActionSeparator>:
|
||
|
size_hint_x: None
|
||
|
minimum_width: '2sp'
|
||
|
width: self.minimum_width
|
||
|
canvas:
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y + sp(4)
|
||
|
size: self.width, self.height - sp(8)
|
||
|
source: self.background_image
|
||
|
|
||
|
<ActionButton,ActionToggleButton>:
|
||
|
background_normal: 'atlas://data/images/defaulttheme/' + ('action_bar' if self.inside_group else 'action_item')
|
||
|
background_down: 'atlas://data/images/defaulttheme/action_item_down'
|
||
|
size_hint_x: None if not root.inside_group else 1
|
||
|
width: [dp(48) if (root.icon and not root.inside_group) else max(dp(48), (self.texture_size[0] + dp(32))), self.size_hint_x][0]
|
||
|
color: self.color[:3] + [0 if (root.icon and not root.inside_group) else 1]
|
||
|
|
||
|
Image:
|
||
|
fit_mode: "contain"
|
||
|
opacity: 1 if (root.icon and not root.inside_group) else 0
|
||
|
source: root.icon
|
||
|
mipmap: root.mipmap
|
||
|
pos: root.x + dp(4), root.y + dp(4)
|
||
|
size: root.width - dp(8), root.height - sp(8)
|
||
|
|
||
|
<ActionLabel>:
|
||
|
size_hint_x: None if not root.inside_group else 1
|
||
|
width: self.texture_size[0] + dp(32)
|
||
|
|
||
|
<ActionGroup>:
|
||
|
size_hint_x: None
|
||
|
width: self.texture_size[0] + dp(32)
|
||
|
|
||
|
<ActionCheck>:
|
||
|
background_normal: 'atlas://data/images/defaulttheme/action_bar' if self.inside_group else 'atlas://data/images/defaulttheme/action_item'
|
||
|
|
||
|
<ActionPreviousImage@Image>:
|
||
|
temp_width: 0
|
||
|
temp_height: 0
|
||
|
|
||
|
<ActionPreviousButton@Button>:
|
||
|
background_normal: 'atlas://data/images/defaulttheme/action_item'
|
||
|
background_down: 'atlas://data/images/defaulttheme/action_item_down'
|
||
|
|
||
|
<ActionPrevious>:
|
||
|
size_hint_x: 1
|
||
|
minimum_width: layout.minimum_width + min(sp(100), title.width)
|
||
|
important: True
|
||
|
GridLayout:
|
||
|
id: layout
|
||
|
rows: 1
|
||
|
pos: root.pos
|
||
|
size_hint_x: None
|
||
|
width: self.minimum_width
|
||
|
ActionPreviousButton:
|
||
|
on_press: root.dispatch('on_press')
|
||
|
on_release: root.dispatch('on_release')
|
||
|
size_hint_x: None
|
||
|
width: prevlayout.width
|
||
|
GridLayout:
|
||
|
id: prevlayout
|
||
|
rows: 1
|
||
|
width: self.minimum_width
|
||
|
height: self.parent.height
|
||
|
pos: self.parent.pos
|
||
|
ActionPreviousImage:
|
||
|
id: prev_icon_image
|
||
|
source: root.previous_image
|
||
|
opacity: 1 if root.with_previous else 0
|
||
|
fit_mode: "contain"
|
||
|
size_hint_x: None
|
||
|
temp_width: root.previous_image_width or dp(prev_icon_image.texture_size[0])
|
||
|
temp_height: root.previous_image_height or dp(prev_icon_image.texture_size[1])
|
||
|
width:
|
||
|
(self.temp_width if self.temp_height <= self.height else \
|
||
|
self.temp_width * (self.height / self.temp_height)) \
|
||
|
if self.texture else dp(8)
|
||
|
mipmap: root.mipmap
|
||
|
ActionPreviousImage:
|
||
|
id: app_icon_image
|
||
|
source: root.app_icon
|
||
|
fit_mode: "contain"
|
||
|
size_hint_x: None
|
||
|
temp_width: root.app_icon_width or dp(app_icon_image.texture_size[0])
|
||
|
temp_height: root.app_icon_height or dp(app_icon_image.texture_size[1])
|
||
|
width:
|
||
|
(self.temp_width if self.temp_height <= self.height else \
|
||
|
self.temp_width * (self.height / self.temp_height)) \
|
||
|
if self.texture and root.app_icon else 0
|
||
|
mipmap: root.mipmap
|
||
|
Widget:
|
||
|
size_hint_x: None
|
||
|
width: '5sp'
|
||
|
Label:
|
||
|
id: title
|
||
|
text: root.title
|
||
|
text_size: self.size
|
||
|
color: root.color
|
||
|
markup: root.markup
|
||
|
shorten: True
|
||
|
shorten_from: 'right'
|
||
|
halign: 'left'
|
||
|
valign: 'middle'
|
||
|
|
||
|
<ActionGroup>:
|
||
|
background_normal: 'atlas://data/images/defaulttheme/action_group'
|
||
|
background_down: 'atlas://data/images/defaulttheme/action_group_down'
|
||
|
background_disabled_normal: 'atlas://data/images/defaulttheme/action_group_disabled'
|
||
|
border: 30, 30, 3, 3
|
||
|
ActionSeparator:
|
||
|
pos: root.pos
|
||
|
size: root.separator_width, root.height
|
||
|
opacity: 1 if root.use_separator else 0
|
||
|
background_image: root.separator_image if root.use_separator else 'action_view'
|
||
|
|
||
|
<ActionOverflow>:
|
||
|
border: 3, 3, 3, 3
|
||
|
background_normal: 'atlas://data/images/defaulttheme/action_item'
|
||
|
background_down: 'atlas://data/images/defaulttheme/action_item_down'
|
||
|
background_disabled_normal: 'atlas://data/images/defaulttheme/button_disabled'
|
||
|
size_hint_x: None
|
||
|
minimum_width: '48sp'
|
||
|
width: self.texture_size[0] if self.texture else self.minimum_width
|
||
|
canvas.after:
|
||
|
Color:
|
||
|
rgb: 1, 1, 1
|
||
|
Rectangle:
|
||
|
pos: root.center_x - sp(16), root.center_y - sp(16)
|
||
|
size: sp(32), sp(32)
|
||
|
source: root.overflow_image
|
||
|
|
||
|
<ActionDropDown>:
|
||
|
auto_width: False
|
||
|
|
||
|
|
||
|
# =============================================================================
|
||
|
# Accordion widget
|
||
|
# =============================================================================
|
||
|
|
||
|
[AccordionItemTitle@Label]:
|
||
|
text: ctx.title
|
||
|
normal_background: ctx.item.background_normal if ctx.item.collapse else ctx.item.background_selected
|
||
|
disabled_background: ctx.item.background_disabled_normal if ctx.item.collapse else ctx.item.background_disabled_selected
|
||
|
canvas.before:
|
||
|
Color:
|
||
|
rgba: self.disabled_color if self.disabled else self.color
|
||
|
BorderImage:
|
||
|
source: self.disabled_background if self.disabled else self.normal_background
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
PushMatrix
|
||
|
Translate:
|
||
|
xy: self.center_x, self.center_y
|
||
|
Rotate:
|
||
|
angle: 90 if ctx.item.orientation == 'horizontal' else 0
|
||
|
axis: 0, 0, 1
|
||
|
Translate:
|
||
|
xy: -self.center_x, -self.center_y
|
||
|
canvas.after:
|
||
|
PopMatrix
|
||
|
|
||
|
|
||
|
<AccordionItem>:
|
||
|
container: container
|
||
|
container_title: container_title
|
||
|
|
||
|
BoxLayout:
|
||
|
orientation: root.orientation
|
||
|
pos: root.pos
|
||
|
BoxLayout:
|
||
|
size_hint_x: None if root.orientation == 'horizontal' else 1
|
||
|
size_hint_y: None if root.orientation == 'vertical' else 1
|
||
|
width: root.min_space if root.orientation == 'horizontal' else 100
|
||
|
height: root.min_space if root.orientation == 'vertical' else 100
|
||
|
id: container_title
|
||
|
|
||
|
StencilView:
|
||
|
id: sv
|
||
|
|
||
|
BoxLayout:
|
||
|
id: container
|
||
|
pos: sv.pos
|
||
|
size: root.content_size
|
||
|
|
||
|
|
||
|
# =============================================================================
|
||
|
# Settings
|
||
|
# =============================================================================
|
||
|
|
||
|
<SettingSpacer>:
|
||
|
size_hint_y: None
|
||
|
height: 5
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgb: .2, .2, .2
|
||
|
Rectangle:
|
||
|
pos: self.x, self.center_y
|
||
|
size: self.width, 1
|
||
|
|
||
|
<SettingItem>:
|
||
|
size_hint: .25, None
|
||
|
height: labellayout.texture_size[1] + dp(10)
|
||
|
content: content
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: 47 / 255., 167 / 255., 212 / 255., self.selected_alpha
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y + 1
|
||
|
size: self.size
|
||
|
Color:
|
||
|
rgb: .2, .2, .2
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y - 2
|
||
|
size: self.width, 1
|
||
|
|
||
|
BoxLayout:
|
||
|
pos: root.pos
|
||
|
|
||
|
Label:
|
||
|
size_hint_x: .66
|
||
|
id: labellayout
|
||
|
markup: True
|
||
|
text: u'{0}\n[size=13sp][color=999999]{1}[/color][/size]'.format(root.title or '', root.desc or '')
|
||
|
font_size: '15sp'
|
||
|
text_size: self.width - 32, None
|
||
|
|
||
|
BoxLayout:
|
||
|
id: content
|
||
|
size_hint_x: .33
|
||
|
|
||
|
|
||
|
<SettingBoolean>:
|
||
|
Switch:
|
||
|
text: 'Boolean'
|
||
|
pos: root.pos
|
||
|
active: bool(root.values.index(root.value)) if root.value in root.values else False
|
||
|
on_active: root.value = root.values[int(args[1])]
|
||
|
|
||
|
<SettingString>:
|
||
|
Label:
|
||
|
text: root.value or ''
|
||
|
pos: root.pos
|
||
|
font_size: '15sp'
|
||
|
|
||
|
<SettingPath>:
|
||
|
Label:
|
||
|
text: root.value or ''
|
||
|
pos: root.pos
|
||
|
font_size: '15sp'
|
||
|
|
||
|
#:import kivy kivy
|
||
|
<SettingColor>:
|
||
|
BoxLayout:
|
||
|
Label:
|
||
|
size_hint_x: None
|
||
|
width: 44
|
||
|
padding: (0, 5)
|
||
|
canvas.before:
|
||
|
# white border to see that there's a color tile at dark colors e.g. black
|
||
|
Color:
|
||
|
rgba: (1,1,1,1.)
|
||
|
Line:
|
||
|
rectangle: self.x,self.y,self.width,self.height
|
||
|
Color:
|
||
|
rgba: kivy.utils.get_color_from_hex(root.value) if root.value else (1,1,1,1.)
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
|
||
|
Label:
|
||
|
text: root.value or ''
|
||
|
pos: root.pos
|
||
|
font_size: '15sp'
|
||
|
text_size: self.size
|
||
|
valign: 'middle'
|
||
|
halign: 'center'
|
||
|
padding: (5,0)
|
||
|
|
||
|
<SettingOptions>:
|
||
|
Label:
|
||
|
text: root.value or ''
|
||
|
pos: root.pos
|
||
|
font_size: '15sp'
|
||
|
|
||
|
<SettingTitle>:
|
||
|
text: self.title
|
||
|
text_size: self.width - 32, None
|
||
|
size_hint_y: None
|
||
|
height: max(dp(20), self.texture_size[1] + dp(20))
|
||
|
color: (.9, .9, .9, 1)
|
||
|
font_size: '15sp'
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: .15, .15, .15, .5
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y + 2
|
||
|
size: self.width, self.height - 2
|
||
|
Color:
|
||
|
rgb: .2, .2, .2
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y - 2
|
||
|
size: self.width, 1
|
||
|
|
||
|
<SettingSidebarLabel>:
|
||
|
size_hint: 1, None
|
||
|
text_size: self.width - 32, None
|
||
|
height: self.texture_size[1] + dp(20)
|
||
|
font_size: '15sp'
|
||
|
canvas.before:
|
||
|
Color:
|
||
|
rgba: 47 / 255., 167 / 255., 212 / 255., int(self.selected)
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
|
||
|
<SettingsPanel>:
|
||
|
spacing: 5
|
||
|
padding: 5
|
||
|
size_hint_y: None
|
||
|
height: self.minimum_height
|
||
|
|
||
|
Label:
|
||
|
size_hint_y: None
|
||
|
text: root.title
|
||
|
text_size: self.width - 32, None
|
||
|
height: max(50, self.texture_size[1] + 20)
|
||
|
color: (.5, .5, .5, 1)
|
||
|
font_size: '15sp'
|
||
|
|
||
|
canvas.after:
|
||
|
Color:
|
||
|
rgb: .2, .2, .2
|
||
|
Rectangle:
|
||
|
pos: self.x, self.y - 2
|
||
|
size: self.width, 1
|
||
|
|
||
|
<Settings>:
|
||
|
orientation: 'horizontal'
|
||
|
canvas.before:
|
||
|
Color:
|
||
|
rgb: 0, 0, 0
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
|
||
|
<InterfaceWithSidebar>:
|
||
|
orientation: 'horizontal'
|
||
|
menu: menu
|
||
|
content: content
|
||
|
MenuSidebar:
|
||
|
id: menu
|
||
|
ContentPanel:
|
||
|
id: content
|
||
|
current_uid: menu.selected_uid
|
||
|
|
||
|
<InterfaceWithSpinner>:
|
||
|
orientation: 'vertical'
|
||
|
menu: menu
|
||
|
content: content
|
||
|
MenuSpinner:
|
||
|
id: menu
|
||
|
ContentPanel:
|
||
|
id: content
|
||
|
current_uid: menu.selected_uid
|
||
|
|
||
|
<MenuSpinner>:
|
||
|
orientation: 'horizontal'
|
||
|
size_hint_y: None
|
||
|
height: '50dp'
|
||
|
spinner: spinner
|
||
|
spinner_text: spinner.text
|
||
|
close_button: button
|
||
|
Spinner:
|
||
|
id: spinner
|
||
|
Button:
|
||
|
text: 'Close'
|
||
|
id: button
|
||
|
size_hint_x: None
|
||
|
width: min(dp(200), 0.4*root.width)
|
||
|
font_size: '15sp'
|
||
|
|
||
|
|
||
|
<MenuSidebar>:
|
||
|
size_hint_x: None
|
||
|
width: '200dp'
|
||
|
buttons_layout: menu
|
||
|
close_button: button
|
||
|
GridLayout:
|
||
|
pos: root.pos
|
||
|
cols: 1
|
||
|
id: menu
|
||
|
padding: 5
|
||
|
|
||
|
canvas.after:
|
||
|
Color:
|
||
|
rgb: .2, .2, .2
|
||
|
Rectangle:
|
||
|
pos: self.right - 1, self.y
|
||
|
size: 1, self.height
|
||
|
|
||
|
Button:
|
||
|
text: 'Close'
|
||
|
id: button
|
||
|
size_hint: None, None
|
||
|
width: root.width - dp(20)
|
||
|
height: max(50, self.texture_size[1] + dp(20))
|
||
|
pos: root.x + dp(10), root.y + dp(10)
|
||
|
font_size: '15sp'
|
||
|
|
||
|
<ContentPanel>:
|
||
|
do_scroll_x: False
|
||
|
container: content
|
||
|
GridLayout:
|
||
|
id: content
|
||
|
cols: 1
|
||
|
size_hint_y: None
|
||
|
height: self.minimum_height
|
||
|
|
||
|
<InterfaceWithTabbedPanel>:
|
||
|
tabbedpanel: tp
|
||
|
close_button: button
|
||
|
TabbedPanel:
|
||
|
id: tp
|
||
|
size: root.size
|
||
|
pos: root.pos
|
||
|
#do_default_tab: False
|
||
|
background_color: (0,0,0,1)
|
||
|
Button:
|
||
|
id: button
|
||
|
text: 'Close'
|
||
|
size_hint: None, None
|
||
|
height: '45dp'
|
||
|
width: min(dp(200), 0.3*root.width)
|
||
|
x: root.x + root.width - self.width
|
||
|
y: root.y + root.height - self.height
|
||
|
|
||
|
<ScrollView>:
|
||
|
_handle_y_pos: (self.right - self.bar_width - self.bar_margin) if self.bar_pos_y == 'right' else (self.x + self.bar_margin), self.y + self.height * self.vbar[0]
|
||
|
_handle_y_size: min(self.bar_width, self.width), self.height * self.vbar[1]
|
||
|
_handle_x_pos: self.x + self.width * self.hbar[0], (self.y + self.bar_margin) if self.bar_pos_x == 'bottom' else (self.top - self.bar_margin - self.bar_width)
|
||
|
_handle_x_size: self.width * self.hbar[1], min(self.bar_width, self.height)
|
||
|
canvas.after:
|
||
|
Color:
|
||
|
rgba: self._bar_color if (self.do_scroll_y and self.viewport_size[1] > self.height) else [0, 0, 0, 0]
|
||
|
Rectangle:
|
||
|
pos: root._handle_y_pos or (0, 0)
|
||
|
size: root._handle_y_size or (0, 0)
|
||
|
Color:
|
||
|
rgba: self._bar_color if (self.do_scroll_x and self.viewport_size[0] > self.width) else [0, 0, 0, 0]
|
||
|
Rectangle:
|
||
|
pos: root._handle_x_pos or (0, 0)
|
||
|
size: root._handle_x_size or (0, 0)
|
||
|
|
||
|
# =============================================================================
|
||
|
# Video player
|
||
|
# =============================================================================
|
||
|
|
||
|
<VideoPlayerPreview>:
|
||
|
pos_hint: {'x': 0, 'y': 0}
|
||
|
image_overlay_play: 'atlas://data/images/defaulttheme/player-play-overlay'
|
||
|
image_loading: 'data/images/image-loading.zip'
|
||
|
Image:
|
||
|
source: root.source
|
||
|
color: (.5, .5, .5, 1) if root.source else (0, 0, 0, 0)
|
||
|
pos_hint: {'x': 0, 'y': 0}
|
||
|
Image:
|
||
|
source: root.image_overlay_play if not root.click_done else root.image_loading
|
||
|
pos_hint: {'x': 0, 'y': 0}
|
||
|
|
||
|
|
||
|
<VideoPlayerAnnotation>:
|
||
|
canvas.before:
|
||
|
Color:
|
||
|
rgba: self.annotation['bgcolor'] if 'bgcolor' in self.annotation else (0, 0, 0, 0.8)
|
||
|
BorderImage:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
source: self.annotation['bgsource'] if 'bgsource' in self.annotation else None
|
||
|
border: self.annotation['border'] if 'border' in self.annotation else (0, 0, 0, 0)
|
||
|
size_hint: self.annotation['size_hint'] if 'size_hint' in self.annotation else (None, None)
|
||
|
size: self.annotation['size'] if 'size' in self.annotation else (self.texture_size[0] + 20, self.texture_size[1] + 20)
|
||
|
pos_hint: self.annotation['pos_hint'] if 'pos_hint' in self.annotation else {'center_x': .5, 'y': .05}
|
||
|
|
||
|
<VideoPlayer>:
|
||
|
container: container
|
||
|
cols: 1
|
||
|
|
||
|
FloatLayout:
|
||
|
cols: 1
|
||
|
id: container
|
||
|
|
||
|
GridLayout:
|
||
|
rows: 1
|
||
|
size_hint_y: None
|
||
|
height: '44dp'
|
||
|
|
||
|
VideoPlayerStop:
|
||
|
size_hint_x: None
|
||
|
video: root
|
||
|
width: '44dp'
|
||
|
source: root.image_stop
|
||
|
fit_mode: "contain"
|
||
|
|
||
|
VideoPlayerPlayPause:
|
||
|
size_hint_x: None
|
||
|
video: root
|
||
|
width: '44dp'
|
||
|
source: root.image_pause if root.state == 'play' else root.image_play
|
||
|
fit_mode: "contain"
|
||
|
|
||
|
VideoPlayerVolume:
|
||
|
video: root
|
||
|
size_hint_x: None
|
||
|
width: '44dp'
|
||
|
source: root.image_volumehigh if root.volume > 0.8 else (root.image_volumemedium if root.volume > 0.4 else (root.image_volumelow if root.volume > 0 else root.image_volumemuted))
|
||
|
fit_mode: "contain"
|
||
|
|
||
|
Widget:
|
||
|
size_hint_x: None
|
||
|
width: 5
|
||
|
|
||
|
VideoPlayerProgressBar:
|
||
|
video: root
|
||
|
max: max(root.duration, root.position, 1)
|
||
|
value: root.position
|
||
|
|
||
|
Widget:
|
||
|
size_hint_x: None
|
||
|
width: 10
|
||
|
|
||
|
# =============================================================================
|
||
|
# Checkbox
|
||
|
# =============================================================================
|
||
|
|
||
|
<CheckBox>:
|
||
|
_checkbox_state_image:
|
||
|
self.background_checkbox_down \
|
||
|
if self.active else self.background_checkbox_normal
|
||
|
_checkbox_disabled_image:
|
||
|
self.background_checkbox_disabled_down \
|
||
|
if self.active else self.background_checkbox_disabled_normal
|
||
|
_radio_state_image:
|
||
|
self.background_radio_down \
|
||
|
if self.active else self.background_radio_normal
|
||
|
_radio_disabled_image:
|
||
|
self.background_radio_disabled_down \
|
||
|
if self.active else self.background_radio_disabled_normal
|
||
|
_checkbox_image:
|
||
|
self._checkbox_disabled_image \
|
||
|
if self.disabled else self._checkbox_state_image
|
||
|
_radio_image:
|
||
|
self._radio_disabled_image \
|
||
|
if self.disabled else self._radio_state_image
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: self.color
|
||
|
Rectangle:
|
||
|
source: self._radio_image if self.group else self._checkbox_image
|
||
|
size: sp(32), sp(32)
|
||
|
pos: int(self.center_x - sp(16)), int(self.center_y - sp(16))
|
||
|
|
||
|
# =============================================================================
|
||
|
# Screen Manager
|
||
|
# =============================================================================
|
||
|
|
||
|
<ScreenManager>:
|
||
|
canvas.before:
|
||
|
StencilPush
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
StencilUse
|
||
|
canvas.after:
|
||
|
StencilUnUse
|
||
|
Rectangle:
|
||
|
pos: self.pos
|
||
|
size: self.size
|
||
|
StencilPop
|
||
|
|
||
|
# =============================================================================
|
||
|
# Color Picker
|
||
|
# =============================================================================
|
||
|
<ColorPicker_Input@TextInput>
|
||
|
multiline: False
|
||
|
mroot: None
|
||
|
padding: sp(5)
|
||
|
border: 4, 9, 4, 9
|
||
|
|
||
|
<ColorPicker_Label@Label>
|
||
|
mroot: None
|
||
|
size_hint_x: None
|
||
|
width: '30sp'
|
||
|
text_size: self.size
|
||
|
halign: "center"
|
||
|
valign: "middle"
|
||
|
|
||
|
<ColorPicker_Selector@BoxLayout>
|
||
|
foreground_color: None
|
||
|
text: ''
|
||
|
mroot: None
|
||
|
mode: 'rgb'
|
||
|
color: 0
|
||
|
spacing: '2sp'
|
||
|
ColorPicker_Label:
|
||
|
text: root.text
|
||
|
mroot: root.mroot
|
||
|
color: root.foreground_color or (1, 1, 1, 1)
|
||
|
AnchorLayout:
|
||
|
size_hint_x: None
|
||
|
width: '50sp'
|
||
|
ColorPicker_Input:
|
||
|
mroot: root.mroot
|
||
|
text: str(int(sldr.value))
|
||
|
size_hint_y: None
|
||
|
height: '28sp'
|
||
|
on_text:
|
||
|
root.mroot._trigger_update_clr(root.mode, root.clr_idx, args[1])
|
||
|
Slider:
|
||
|
id: sldr
|
||
|
size_hint: 1, .25
|
||
|
pos_hint: {'center_y':.5}
|
||
|
range: 0, 255
|
||
|
value: root.color * 255
|
||
|
on_value:
|
||
|
root.mroot._trigger_update_clr(root.mode, root.clr_idx, args[1])
|
||
|
|
||
|
<ColorWheel>:
|
||
|
_origin: self.center
|
||
|
_radius: 0.45 * min(self.size)
|
||
|
|
||
|
<ColorPicker>:
|
||
|
foreground_color: (1, 1, 1, 1) if self.hsv[2] * root.color[3] < .5 else (0, 0, 0, 1)
|
||
|
wheel: wheel
|
||
|
BoxLayout:
|
||
|
orientation: 'vertical' if root.width < root.height else 'horizontal'
|
||
|
spacing: '5sp'
|
||
|
StackLayout:
|
||
|
orientation: 'tb-lr'
|
||
|
size_hint_y: None if root.width < root.height else 1
|
||
|
height: sp(33) * 4 if root.width < root.height else self.height
|
||
|
canvas:
|
||
|
Color:
|
||
|
rgba: root.color
|
||
|
Rectangle:
|
||
|
size: self.size
|
||
|
pos: self.pos
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
text: 'R'
|
||
|
clr_idx: 0
|
||
|
color: root.color[0]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
text: 'G'
|
||
|
clr_idx: 1
|
||
|
color: root.color[1]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
text: 'B'
|
||
|
clr_idx: 2
|
||
|
color: root.color[2]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
text: 'A'
|
||
|
clr_idx: 3
|
||
|
color: root.color[3]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
mode: 'hsv'
|
||
|
text: 'H'
|
||
|
clr_idx: 0
|
||
|
color: root.hsv[0]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
mode: 'hsv'
|
||
|
text: 'S'
|
||
|
clr_idx: 1
|
||
|
color: root.hsv[1]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
ColorPicker_Selector:
|
||
|
mroot: root
|
||
|
mode: 'hsv'
|
||
|
text: 'V'
|
||
|
clr_idx: 2
|
||
|
color: root.hsv[2]
|
||
|
foreground_color: root.foreground_color
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
BoxLayout:
|
||
|
size_hint_y: None if root.width < root.height else 0.125
|
||
|
size_hint_x: .5 if root.width < root.height else 1
|
||
|
height: '33sp' if root.width < root.height else self.height
|
||
|
|
||
|
spacing: '2sp'
|
||
|
ColorPicker_Label:
|
||
|
mroot: root
|
||
|
text: 'X'
|
||
|
color: root.foreground_color
|
||
|
AnchorLayout:
|
||
|
ColorPicker_Input:
|
||
|
size_hint_y: None
|
||
|
height: '28sp'
|
||
|
mroot: root
|
||
|
text: str(root.hex_color)
|
||
|
on_text: root._trigger_update_hex(args[1])
|
||
|
|
||
|
|
||
|
ColorWheel:
|
||
|
id: wheel
|
||
|
color: root.color
|
||
|
on_color: root.set_color(args[1][:3])
|