MetaCoreEngineV2/Builtin/Elements.py
2026-01-13 17:06:06 +08:00

340 lines
11 KiB
Python

"""
OUTDATED
Do not use anymore.
"""
import colorsys
from LUIObject import LUIObject
from LUISlider import LUISlider
from LUISprite import LUISprite
from LUIVerticalLayout import LUIVerticalLayout
from LUICallback import LUICallback
from LUILabel import LUILabel
from LUIFrame import LUIFrame
from LUIButton import LUIButton
class LUISliderWithLabel(LUIObject, LUICallback):
def __init__(self, parent=None, width=100.0, filled=False, min_value=0, max_value=1.0, precision=2, value=None):
LUIObject.__init__(self, x=0, y=0, w=width, h=0)
LUICallback.__init__(self)
max_numbers_before = max(len(str(int(max_value))), len(str(int(min_value))))
number_space_required = max_numbers_before
if precision > 0:
number_space_required += 1 + precision
pixels_per_number = 7
self.precision = precision
self.slider = LUISlider(self, width=width - pixels_per_number * number_space_required - 5, filled=filled, min_value=min_value, max_value=max_value, value=value)
self.label = LUILabel(parent=self, shadow=True, text=u"1.23")
self.label.right = 0
self.label.top = self.label.height - self.slider.height
self.label.color = (1,1,1,0.5)
self.slider.add_change_callback(self._on_slider_changed)
self.slider.add_change_callback(self._trigger_callback)
self._on_slider_changed(self.slider, self.slider.get_value())
if parent is not None:
self.parent = parent
self.fit_to_children()
def get_value(self):
return self.slider.get_value()
def set_value(self, val):
self.slider.set_value(val)
def _on_slider_changed(self, obj, value):
self.label.text = ("{:." + str(self.precision) + "f}").format(value)
class LUIKeyMarker(LUIObject):
def __init__(self, parent=None, key=u"A"):
LUIObject.__init__(self)
self.bgLeft = LUISprite(self, "Keymarker_Left", "skin")
self.bgMid = LUISprite(self, "Keymarker", "skin")
self.bgRight = LUISprite(self, "Keymarker_Right", "skin")
self.label = LUILabel(parent=self, text=key, shadow=True)
self.label.centered = (True, True)
self.label.margin = (-3, 0, 0, -1)
self.margin = (-1, 0, 0, -1)
self.set_key(key)
if parent is not None:
self.parent = parent
self.fit_to_children()
def set_key(self, key):
self.label.set_text(key)
self.width = self.label.width + self.bgLeft.width + self.bgRight.width + 7
self.bgMid.width = self.width - self.bgLeft.width - self.bgRight.width
self.bgMid.left = self.bgLeft.width
self.bgRight.left = self.bgMid.width + self.bgMid.left
self.fit_to_children()
class LUIKeyInstruction(LUIObject):
def __init__(self, parent=None, key=u"A", instruction=u"Instruction"):
LUIObject.__init__(self)
self.marker = LUIKeyMarker(parent=self, key=key)
self.instructionLabel = LUILabel(parent=self, text=instruction, shadow=True)
self.instructionLabel.centered = (False, True)
self.instructionLabel.margin.top = -4
self.set_key(key)
def set_key(self, key):
self.marker.set_key(key)
self.instructionLabel.left = self.marker.width + 5
self.fit_to_children()
class LUIColorpicker(LUIObject):
def __init__(self, parent=None, color=None):
LUIObject.__init__(self, x=0, y=0, w=27, h=27)
self.previewBg = LUISprite(self, "ColorpickerPreviewBg", "skin")
self.filler = LUISprite(self, "blank", "skin")
self.filler.width = 21
self.filler.height = 21
self.filler.pos = (5, 5)
self.filler.color = (0.2,0.6,1.0,1.0)
self.overlay = LUISprite(self, "ColorpickerPreviewOverlay", "skin")
self.overlay.pos = (2, 2)
self.overlay.bind("click", self._open_dialog)
self.fit_to_children()
self.popup = LUIColorpickerPopup(self)
self.popup.hide()
if color is not None:
self.colorValue = color
else:
# My favourite color
self.colorValue = (0.2, 0.6, 1.0)
self.set_color_value(self.colorValue)
self.popup.add_change_callback(self._on_popup_color_changed)
if parent is not None:
self.parent = parent
def _open_dialog(self, event):
if self.has_focus():
self.blur()
else:
self.request_focus()
def on_focus(self, event):
self.popup._load_rgb(self.colorValue)
self.popup.open_at(self, 14.0)
def set_color_value(self, rgb):
self.colorValue = rgb
self.filler.color = rgb
def get_color_value(self):
return self.colorValue
def on_tick(self, event):
self.popup._update(event)
def on_blur(self, event):
self.popup.close()
def _on_popup_color_changed(self, popup, rgb):
self.set_color_value(rgb)
def _on_popup_closed(self):
self.blur()
class LUIPopup(LUIFrame):
def __init__(self, parent=None, width=200, height=200):
LUIFrame.__init__(self, parent=parent, width=width, height=height, padding=10, innerPadding=0)
self.topmost = True
self.borderSize = 33
self.content.bind("click", self._on_content_click)
def open_at(self, targetElement, distance):
self.show()
targetPos = targetElement.get_abs_pos()+ targetElement.get_size() / 2
showAbove = targetPos.y > self.height - self.borderSize
showLeft = targetPos.x > self.width - self.borderSize
relative = self.get_relative_pos(targetPos)
self.pos += relative
if showLeft:
self.left -= self.width - self.borderSize
self.left += 25
else:
self.left -= self.borderSize
self.left -= 25
if showAbove:
self.top -= distance
self.top -= self.height - self.borderSize
else:
self.top += distance
self.top -= self.borderSize
def _on_content_click(self, event):
pass
def close(self):
self.hide()
class LUIColorpickerPopup(LUIPopup, LUICallback):
def __init__(self, parent=None):
LUIPopup.__init__(self, parent=parent, width=240, height=146)
LUICallback.__init__(self)
self.field = LUIObject(self.content, x=0, y=0, w=128, h=128)
self.fieldBG = LUISprite(self.field, "blank", "skin")
self.fieldBG.size = (128, 128)
self.fieldBG.color = (0.2,0.6,1.0)
self.fieldFG = LUISprite(self.field, "ColorpickerFieldOverlay", "skin")
self.fieldFG.pos = (-2, 0)
self.fieldBG.bind("mousedown", self._start_field_dragging)
self.fieldBG.bind("mouseup", self._stop_field_dragging)
self.fieldHandle = LUISprite(self.field, "ColorpickerFieldHandle", "skin")
self.fieldHandle.bind("mousedown", self._start_field_dragging)
self.fieldHandle.bind("mouseup", self._stop_field_dragging)
self.fieldDragging = False
self.hueSlider = LUIObject(self.content, x=140, y=0, w=40, h=128)
self.hueSliderFG = LUISprite(self.hueSlider, "ColorpickerHueSlider", "skin")
self.hueHandle = LUISprite(self.hueSlider, "ColorpickerHueHandle", "skin")
self.hueHandle.left = (self.hueSliderFG.width - self.hueHandle.width) / 2.0
self.hueHandle.top = 50
self.hueDragging = False
self.hueSlider.bind("mousedown", self._start_hue_dragging)
self.hueSlider.bind("mouseup", self._stop_hue_dragging)
self.labels = LUIVerticalLayout(self.content, width=40)
self.labels.pos = (177, 42)
colors = [u"R", u"G", u"B"]
self.colorLabels = []
for color in colors:
label = LUILabel(text=color, shadow=True)
label.color = (1,1,1,0.3)
valueLabel = LUILabel(text=u"255", shadow=True)
valueLabel.right = 0
self.labels.add(label, valueLabel)
self.colorLabels.append(valueLabel)
self.activeColor = LUIObject(self.content, x=177, y=0)
self.activeColorBG = LUISprite(self.activeColor, "blank", "skin")
self.activeColorFG = LUISprite(self.activeColor, "ColorpickerActiveColorOverlay", "skin")
self.activeColorBG.size = (40, 40)
self.activeColorBG.pos = (2, 0)
self.activeColorBG.color = (0.2,0.6,1.0,1.0)
self.closeButton = LUIButton(parent=self.content, text=u"Done", width=45, template="ButtonGreen")
self.closeButton.left = 177
self.closeButton.top = 98
self.closeButton.bind("click", self._close_popup)
self._set_hue(0.5)
self._set_sat_val(0.5, 0.5)
self.widget = parent
def _load_rgb(self, rgb):
hsv = colorsys.rgb_to_hsv(*rgb)
self._set_hue(hsv[0])
self._set_sat_val(hsv[1], hsv[2])
def _close_popup(self, event):
self.widget._on_popup_closed()
self.close()
def _update(self, event):
if self.hueDragging:
offset = event.coordinates.y - self.hueSliderFG.abs_pos.y
offset /= 128.0
offset = 1.0 - max(0.0, min(1.0, offset))
self._set_hue(offset)
if self.fieldDragging:
offset = event.coordinates - self.fieldBG.abs_pos
saturation = max(0.0, min(1.0, offset.x / 128.0))
value = 1.0 - max(0.0, min(1.0, offset.y / 128.0))
self._set_sat_val(saturation, value)
self._update_color()
def _set_sat_val(self, sat, val):
self.saturation = sat
self.valueValue = val
self.fieldHandle.top = (1.0 - self.valueValue) * 128.0 - self.fieldHandle.height / 2.0
self.fieldHandle.left = self.saturation * 128.0 - self.fieldHandle.width / 2.0
def _set_hue(self, hue):
self.hueValue = min(0.999, hue)
self.hueHandle.top = (1.0-hue) * 128.0 - self.hueHandle.height / 2
self.fieldBG.color = colorsys.hsv_to_rgb(self.hueValue, 1, 1)
def _update_color(self):
rgb = colorsys.hsv_to_rgb(self.hueValue, self.saturation, self.valueValue)
self.activeColorBG.color = rgb
self.colorLabels[0].set_text(str(int(rgb[0]*255.0)))
self.colorLabels[1].set_text(str(int(rgb[1]*255.0)))
self.colorLabels[2].set_text(str(int(rgb[2]*255.0)))
self._trigger_callback(rgb)
def _start_field_dragging(self, event):
if not self.fieldDragging:
self.fieldDragging = True
def _stop_field_dragging(self, event):
if self.fieldDragging:
self.fieldDragging = False
def _start_hue_dragging(self, event):
if not self.hueDragging:
self.hueDragging = True
def _stop_hue_dragging(self, event):
if self.hueDragging:
self.hueDragging = False