1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
PySolFC/pysollib/kivy/LImage.py
lufebe16 c3ffbff146 Kivy Version
- refactorings & some clean up
2023-11-23 17:49:38 +01:00

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
# =============================================================================