mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
244 lines
7.8 KiB
Python
244 lines
7.8 KiB
Python
#!/usr/bin/python
|
|
# -*- mode: python; coding: utf-8; -*-
|
|
# =============================================================================
|
|
# Copyright (C) 2017-2023 LB
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# =============================================================================
|
|
|
|
import math
|
|
# import inspect
|
|
|
|
from kivy.graphics import Color
|
|
from kivy.graphics import Rectangle
|
|
from kivy.properties import ObjectProperty
|
|
from kivy.properties import StringProperty
|
|
from kivy.uix.image import Image as KivyImage
|
|
from kivy.uix.widget import Widget
|
|
|
|
from pysollib.kivy.LBase import LBase
|
|
|
|
# =============================================================================
|
|
|
|
|
|
class LImage(Widget, LBase):
|
|
CONTAIN = 0
|
|
FILL = 1
|
|
COVER = 2
|
|
SCALE_DOWN = 3
|
|
TILING = 4
|
|
fit_mode = StringProperty("fill")
|
|
texture = ObjectProperty(None, allownone=True)
|
|
|
|
def make_scale_down(self, s, p):
|
|
r = self.rect
|
|
t = self.texture.size
|
|
if (t[0] > s[0]) or (t[1] > s[1]):
|
|
self.make_contain(s, p)
|
|
else:
|
|
r.size = t
|
|
r.pos = (p[0]+(s[0]-t[0])/2.0, p[1]+(s[1]-t[1])/2.0)
|
|
|
|
def make_fill(self, s, p):
|
|
self.rect.size = s
|
|
self.rect.pos = p
|
|
|
|
def make_contain(self, s, p):
|
|
taspect = self.texture.size[0]/self.texture.size[1]
|
|
waspect = s[0]/s[1]
|
|
r = self.rect
|
|
if waspect < taspect:
|
|
s1 = s[1]*waspect/taspect
|
|
r.size = (s[0], s1)
|
|
r.pos = (p[0], p[1]+(s[1]-s1)/2.0)
|
|
else:
|
|
s0 = s[0]/waspect*taspect
|
|
r.size = (s0, s[1])
|
|
r.pos = (p[0]+(s[0]-s0)/2.0, p[1])
|
|
|
|
def make_cover(self, s, p):
|
|
aspect = self.texture.size[0]/self.texture.size[1]
|
|
waspect = self.size[0]/self.size[1]
|
|
print ('aspect: ', aspect) # noqa
|
|
print ('waspect: ', waspect) # noqa
|
|
|
|
# 'clamp_to_edge','repeat','mirrored_repeat'
|
|
self.texture.wrap = 'repeat'
|
|
print ('wrap: ',self.texture.wrap) # noqa
|
|
|
|
# set rect size/pos to window
|
|
self.rect.size = s
|
|
self.rect.pos = p
|
|
|
|
# evaluate original texture coords ?
|
|
u = uu = self.tex_u # noqa
|
|
v = vv = self.tex_v # noqa
|
|
w = ww = self.tex_w
|
|
h = hh = self.tex_h
|
|
|
|
# in order to center the image in the window
|
|
# modify texture coords
|
|
if waspect < aspect:
|
|
w = ww/aspect*waspect # noqa
|
|
u = 0.5 - w/2.0 # noqa
|
|
else:
|
|
h = hh*aspect/waspect # noqa
|
|
v = 0.5 - h/2.0 # noqa
|
|
|
|
# and update them.
|
|
tc = ( u, v, u + w, v, u + w, v + h, u, v + h ) # noqa
|
|
self.rect.tex_coords = tc
|
|
|
|
def make_tiling(self, s, p):
|
|
# set rect size/pos to window
|
|
self.rect.size = s
|
|
self.rect.pos = p
|
|
|
|
# number of repetitions
|
|
t = self.texture
|
|
t.wrap = 'repeat'
|
|
stepsy = self.size[1] / t.size[1]
|
|
stepsx = self.size[0] / t.size[0]
|
|
|
|
# set coord parameters.
|
|
w = self.tex_w * stepsx
|
|
h = self.tex_h * stepsy
|
|
u = self.tex_u
|
|
v = stepsy - math.floor(stepsy)
|
|
self.rect.tex_coords = ( u, v, u + w, v, u + w, v + h, u, v + h ) # noqa
|
|
|
|
def make_format(self, size, pos):
|
|
if hasattr(self, "rect"):
|
|
if self.texture is None:
|
|
self.rect.size = size
|
|
self.rect.pos = pos
|
|
elif self.fit_num == self.CONTAIN:
|
|
self.make_contain(size, pos)
|
|
elif self.fit_num == self.FILL:
|
|
self.make_fill(size, pos)
|
|
elif self.fit_num == self.COVER:
|
|
self.make_cover(size, pos)
|
|
elif self.fit_num == self.SCALE_DOWN:
|
|
self.make_scale_down(size, pos)
|
|
elif self.fit_num == self.TILING:
|
|
self.make_tiling(size, pos)
|
|
|
|
def __init__(self, **kwargs):
|
|
super(LImage, self).__init__(**kwargs)
|
|
|
|
# NOTE:
|
|
# properties self.texture and self.fit_mode are
|
|
# already set here from the super call either to its
|
|
# default value or set from evaluaion of a matching kwargs
|
|
# entry.
|
|
'''
|
|
print('LImage __init__: ',self)
|
|
print('stack[1] = ',inspect.stack()[1].frame)
|
|
print('stack[2] = ',inspect.stack()[2].frame)
|
|
print('texture=',self.texture)
|
|
print('fit_mode=',self.fit_mode)
|
|
'''
|
|
self.corePos = None
|
|
self.coreSize = None
|
|
self.source = None
|
|
if "source" in kwargs:
|
|
self.source = kwargs["source"]
|
|
image = KivyImage(source=self.source)
|
|
self.texture = image.texture
|
|
|
|
# update fit_num from fit_mode (needs self.fit_num defined)
|
|
self.fit_num = self.FILL
|
|
self.fit_num_update(self.fit_mode)
|
|
|
|
# setup canvas.
|
|
self.background = False
|
|
if "background" in kwargs:
|
|
self.background = kwargs["background"]
|
|
|
|
if self.background:
|
|
with self.canvas.before:
|
|
self.color = Color(1.0,1.0,1.0,1.0) # noqa
|
|
self.rect = Rectangle(texture=self.texture)
|
|
else:
|
|
with self.canvas:
|
|
self.color = Color(1.0,1.0,1.0,1.0) # noqa
|
|
self.rect = Rectangle(texture=self.texture)
|
|
|
|
# save original tex_coords (needs self.rect defined)
|
|
self.tex_coord_update(self.texture)
|
|
|
|
# initial size is the natural size of the image.
|
|
self.size = self.texture.size
|
|
|
|
def tex_coord_update(self, texture):
|
|
if hasattr(self, "rect"):
|
|
self.rect.texture = texture
|
|
self.tex_u = self.rect.tex_coords[0]
|
|
self.tex_v = self.rect.tex_coords[1]
|
|
self.tex_w = self.rect.tex_coords[2] - self.tex_u
|
|
self.tex_h = self.rect.tex_coords[5] - self.tex_v
|
|
|
|
def fit_num_update(self, fit_mode):
|
|
if hasattr(self, "fit_num"):
|
|
if fit_mode == "contain":
|
|
self.fit_num = self.CONTAIN
|
|
if fit_mode == "fill":
|
|
self.fit_num = self.FILL
|
|
if fit_mode == "cover":
|
|
self.fit_num = self.COVER
|
|
if fit_mode == "scale_down":
|
|
self.fit_num = self.SCALE_DOWN
|
|
if fit_mode == "tiling":
|
|
self.fit_num = self.TILING
|
|
|
|
def on_size(self, a, s):
|
|
self.make_format(s, self.pos)
|
|
|
|
def on_pos(self, a, p):
|
|
self.make_format(self.size, p)
|
|
|
|
def on_fit_mode(self, a, m):
|
|
self.fit_num_update(self.fit_mode)
|
|
self.make_format(self.size, self.pos)
|
|
|
|
def on_texture(self, a, texture):
|
|
self.tex_coord_update(self.texture)
|
|
self.make_format(self.size, self.pos)
|
|
|
|
def setColor(self, color):
|
|
self.color.rgba = color
|
|
|
|
def getHeight(self):
|
|
return self.size[1]
|
|
|
|
def getWidth(self):
|
|
return self.size[0]
|
|
|
|
def subsample(self, r):
|
|
return LImage(texture=self.texture)
|
|
|
|
def on_touch_down(self, touch):
|
|
# print('LImage: touch_down on %s' % str(touch.pos))
|
|
if self.collide_point(*touch.pos):
|
|
if (self.source is not None):
|
|
print('LImage match %s' % self.source)
|
|
else:
|
|
print('LImage match with texture')
|
|
return True
|
|
return False
|
|
|
|
def on_touch_up(self, touch):
|
|
# print('LImage: touch_up on %s' % str(touch.pos))
|
|
if self.collide_point(*touch.pos):
|
|
if (self.source is not None):
|
|
print('LImage match %s' % self.source)
|
|
else:
|
|
print('LImage match with texture')
|
|
return True
|
|
return False
|
|
|
|
# =============================================================================
|