I want to draw multi-box on a image. How to chage the parameters of the box pos, size and lable in a LineRectangle class in python kivy?
class LineRectangle(Widget):
def __init__(self, **kwargs):
super(LineRectangle, self).__init__(**kwargs)
with self.canvas:
Color(1, 0, 0, 1)
self.line = Line(width=2, rectangle=(self.x, self.y, self.width, self.height))
self.label = Label(text='Rectangle', pos=(self.x, self.y), size=(10, 10))
class LineExtendedApp(App):
def build(self):
root = FloatLayout()
image = Image(source='000001.jpg', allow_stretch=False, keep_ratio=True)
root.add_widget(image)
bbox1 = LineRectangle()
bbox1.line = Line(width=1, rectangle=(100, 100, 100, 100))
bbox1.label = Label(text='bbox1', pos=(100, 100), size=(10, 10))
bbox2 = LineRectangle()
bbox2.line = Line(width=1, rectangle=(300, 300, 100, 100))
bbox2.label = Label(text='bbox1', pos=(300, 300), size=(10, 10))
root.add_widget(bbox1)
root.add_widget(bbox2)
return root
if __name__ == '__main__':
LineExtendedApp().run()
You can create Properties for the parameters that you want to be able to change. Then use a kv rule to create bindings (so that changes to a Property are automatically shown in your display). Here is an example of how to do that:
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import ListProperty, NumericProperty, StringProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.widget import Widget
class LineRectangle(Widget):
line_color = ListProperty([])
line_rect = ListProperty([])
line_width = NumericProperty()
label_text = StringProperty('')
label_pos = ListProperty([])
def __init__(self, **kwargs):
self.line_color = kwargs.pop('line_color', [1,1,1,1])
self.line_rect = kwargs.pop('line_rect', [0,0,50,50])
self.line_width = kwargs.pop('line_width', 1)
self.label_text = kwargs.pop('label_text', 'text')
self.label_pos = kwargs.pop('label_pos', [0,0])
super(LineRectangle, self).__init__()
Builder.load_string('''
<LineRectangle>:
canvas:
Color:
rgba: root.line_color
Line:
width: root.line_width
rectangle: root.line_rect
Label:
text: root.label_text
pos: root.label_pos
size: 10, 10
''')
class LineExtendedApp(App):
def build(self):
root = FloatLayout()
image = Image(source='000001.jpg', allow_stretch=False, keep_ratio=True)
root.add_widget(image)
self.bbox1 = LineRectangle(line_wdth=2, line_rect=[100, 100, 100, 100], line_color=[1,0,0,1], label_text='bbox1', label_pos=[100, 100])
bbox2 = LineRectangle(line_width=1, line_rect=[300, 300, 300, 300], line_color=[0,1,0,1], label_text='bbox2', label_pos=[300, 300])
root.add_widget(self.bbox1)
root.add_widget(bbox2)
Clock.schedule_once(self.adjust, 2) # just to demonstrate change parameter
return root
def adjust(self, dt):
self.bbox1.line_width = 10
if __name__ == '__main__':
LineExtendedApp().run()
Related
My application works like this: when you click the 'Ask a Question' button, a random question drops out of the file 1.txt in the Random directory. When you click the 'Add Question' button, it opens filechooser.py the path is Random. I want that when you click on the txt file, it is automatically read and random questions from it fall on the Label. How to do it:?
main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from random import choice
from kivy.config import Config
from kivy.uix.label import Label
import os
Config.set('graphics', 'resizable', 0)
Config.set('graphics', 'width', 500)
Config.set('graphics', 'height', 800)
class MyApp(App):
def build(self):
bl1 = BoxLayout(orientation='vertical', spacing = 8)
self.lbl = Label(
text='Зачет по информатике',
text_size = (450, 500),
font_size = 30,
valign = "center",
halign = 'center' )
bl1.add_widget(self.lbl)
self.btn = Button(
text='Задать вопрос!',
on_press = self.change_text,
text_size = (250, 250),
font_size = 30,
size_hint = (1, .3),
valign = "center",
halign = 'center')
bl1.add_widget(self.btn)
self.dir = Button(
text = 'Добавить вопросы',
on_press = self.addqu,
text_size = (500, 500),
font_size = 30,
size_hint = (1, .1),
valign = "center",
halign = 'center')
bl1.add_widget(self.dir)
self.crbl = Button(
text = 'Выбрать вопросы',
on_press = self.selectqu,
text_size = (500, 500),
font_size = 30,
size_hint = (1, .1),
valign = "center",
halign = 'center')
bl1.add_widget(self.crbl)
return bl1
def change_text(self, instance):
file = open('3.txt', encoding="utf8")
b = file.read().split("\n")
self.lbl.text = (choice(b))
def addqu(self, startfile):
os.system('python kivyfilechooser.py')
def selectqu(self):
pass
if __name__ == "__main__":
MyApp().run()
kivyfilechooser.py
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
class MyWidget (GridLayout):
def selected(self, filename):
try:
self.ids.image.source = filename[0]
except:
pass
class FileChooserWindow(App):
def build(self):
return MyWidget()
if __name__ == "__main__":
window = FileChooserWindow()
window.run()
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
class MyWidget (GridLayout):
def selected(self, filename):
try:
self.ids.image.source = filename[0]
except:
pass
class FileChooserWindow(App):
def build(self):
return MyWidget()
if __name__ == "__main__":
window = FileChooserWindow()
window.run()
filechooserwindow.kv
#:kivy 1.11.0
:
cols:2
id:my_widget
FileChooserListView:
id:filechooser
path: "/Users/MSI GAMING/Desktop/Random"
on_submit: filechooser.selection, touch
I want to make a launcher app which matches the windows 11 theme. i made the background and i want to make a button which would close the launcher, but the button does not work for some reason when i put it in a different class. i can put it in the same class but i want to learn this method as i would use it while making the app icons. the code it provided below.
from kivy.config import Config
from kivy.core.window import Window
from kivy.graphics import Rectangle
from kivy.graphics.context_instructions import Color
from kivy.properties import Clock
from kivy.uix.image import Image
import cv2
from kivy.uix.widget import Widget
Config.set('graphics', 'fullscreen', 'auto')
Config.set('graphics', 'borderless', 'true')
Config.set('graphics', 'window_state', 'maximized')
from kivy.app import App
import pyautogui
from kivy.uix.floatlayout import FloatLayout
theme = 'dark'
screen = 'main'
x_button_size = (100,100)
x_button_pos = (50,50)
class XButton(Image):
def __init__(self):
super().__init__(source='assets/images/bg_image.png')
class MainScreenWidget(FloatLayout):
bg = None
rectangle = None
def __init__(self, **kwargs):
super(MainScreenWidget, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1.0/60.0)
self.init_bg()
# x_button_size = (self.width , self.height )
self.x_button = XButton()
def init_bg(self):
with self.canvas.before:
self.bg = Image(source='assets/images/bg_image.png', size_hint=[1, 1])
if theme == 'light':
Color(0.9, .9, .9, 0.7)
elif theme == 'dark':
Color(0, 0, 0, 0.6)
self.rectangle = Rectangle(size=self.size)
pass
def update(self, dt):
self.update_bg()
self.update_x_button()
def update_bg(self):
self.bg.size = self.width, self.height
self.bg.pos_hint = {'center_x': self.width / 2, 'center_y': self.height / 2}
self.rectangle.size = self.size
pass
def update_x_button(self):
self.x_button.size = (Window.size[0], Window.size[1])
self.x_button.pos = (5, 5)
pass
class LauncherApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
bg_image = pyautogui.screenshot()
bg_image.save(r'assets/images/bg_image.png')
image = cv2.imread('assets/images/bg_image.png')
blurred_image = cv2.GaussianBlur(image, (75, 75), 0)
cv2.imwrite('assets/images/bg_image.png', blurred_image)
LauncherApp().run()
any recommendations for how to make the icons are also helpful
I am trying to add navigation in my kivy app using .py file but because the things I tried are not working and I am a complete beginner. I don't know what problem is occurring and I am not able to find any solutions on my own pls help me. I am trying to change the main screen from class Dre to class SecondWindow when the play button is clicked. BTW the things I already tried are tagged now. Pls give the solution in .py file because I am trying to do everything on it. Here is the code. Thanks
import kivy
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Rectangle
from kivy import platform
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class MainWindow(Screen):
pass
#class ThirdWindow(ScreenManager):
# def load(self):
# sm = ScreenManager
# sm.add_widget(Dre(name='Dre'))
# sm.add_widget(SecondWindow(name='SecondWindow'))
# self.sm.current = 'Dre'
class Dre(RelativeLayout):
def __init__(self, **kwargs):
super(Dre, self).__init__(**kwargs)
self.color = [254/255, 102/255, 37/255, 1]
self.H_color = [254/255, 102/255, 37/255]
self.sound_theme = None
self.init_audio()
# self.kv = Builder.load_file('Levels.py')
# self.callback()
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neo.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
else:
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neon.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
def update_bg(self, *args):
if platform in ('linux', 'win', 'macosx'):
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='')
# B1.bind(on_press=return self.kv)
self.add_widget(B1)
else:
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
on_press=self.callback)
self.add_widget(B1)
# def callback(self, instance):
# print('working')
# self.manager.current = 'SecondWindow'
def init_audio(self):
self.sound_theme = SoundLoader.load('Bg_theme.mp3')
self.sound_theme.volume = 1
self.sound_theme.loop = True
if self.sound_theme:
self.sound_theme.play()
print('okay')
else:
print('not okay')
class SecondWindow(Screen):
def __init__(self, **kwargs):
super(SecondWindow, self).__init__(**kwargs)
self.color = [254 / 255, 102 / 255, 37 / 255, 1]
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, color=self.color)
class LabApp(App):
def build(self):
return Dre()
if __name__ == '__main__':
LabApp().run()
Here's the correct code for that (at least for me):
import kivy
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Rectangle
from kivy import platform
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class SM(ScreenManager):
pass
class MainWindow(Screen, RelativeLayout):
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
self.color = [254/255, 102/255, 37/255, 1]
self.H_color = [254/255, 102/255, 37/255]
self.sound_theme = None
self.init_audio()
# self.kv = Builder.load_file('Levels.py')
# self.callback()
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neo.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
else:
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neon.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
def bruh(self):
App.get_running_app().root.current = 'SecondWindow'
def update_bg(self, *args):
if platform in ('linux', 'win', 'macosx'):
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='', on_press= lambda x: self.bruh())
# B1.bind(on_press=return self.kv)
self.add_widget(B1)
else:
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
on_press=self.callback)
self.add_widget(B1)
# def callback(self, instance):
# print('working')
# self.manager.current = 'SecondWindow'
def init_audio(self):
self.sound_theme = SoundLoader.load('Bg_theme.mp3')
self.sound_theme.volume = 1
self.sound_theme.loop = True
if self.sound_theme:
self.sound_theme.play()
print('okay')
else:
print('not okay')
class SecondWindow(Screen):
def __init__(self, **kwargs):
super(SecondWindow, self).__init__(**kwargs)
self.color = [254 / 255, 102 / 255, 37 / 255, 1]
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, color=self.color)
class LabApp(App):
def build(self):
sm = SM()
sm.add_widget(MainWindow(name='MainWindow'))
sm.add_widget(SecondWindow(name='SecondWindow'))
return sm
if __name__ == '__main__':
LabApp().run()
The main changes here are the fact that the build method for LabApp is required, since the .kv file isn't used; to also inherit the Screen class into the MainWindow class, which is renamed from Dre for less confusing code, since it is essential forScreenManager; and the bruh method in the MainWindow (im not good at naming ok dont roast me) that changes to the SecondWindow screen when the B1 button's on_press event is called. Sorry for the confusing English but at least it's understandable(?) ig
I have a music player app that reads the cover of songs and displays them on the screen. For this I created my own class ByteFitImage for the image to read bytes and for it to adapt to different sizes.
The problem I am encountering is that if I decide to change the data, I get a key error:
KeyError: 'source'
And obviously this line is causing the problem:
self.kv.ids.img.data = BytesIO(second_img.read())
Why is it asking for source? My Code:
from io import BytesIO
from kivy.clock import Clock
from kivy.core.image import Image
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from kivy.properties import BooleanProperty, ObjectProperty, VariableListProperty, Property
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.app import App
class ByteFitImage(BoxLayout):
data = Property(None)
radius = VariableListProperty([0], length=4)
mipmap = BooleanProperty(False)
_container = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._late_init)
def _late_init(self, *args):
self._container = Container(self.data)
self.bind(data=self._container.setter("source"))
self.add_widget(self._container)
def reload(self):
self._container.image.reload()
class Container(Widget):
# source = ObjectProperty()
image = ObjectProperty()
def __init__(self, source, **kwargs):
super().__init__(**kwargs)
# self.image = AsyncImage(mipmap=mipmap)
self.bind(size=self.adjust_size, pos=self.adjust_size)
self.image = Image(source, ext="jpg")
self.image.bind(on_load=self.adjust_size)
# self.source = source
def on_source(self, instance, value):
if isinstance(value, str):
self.image.source = value
else:
self.image.texture = value
self.adjust_size()
def adjust_size(self, *args):
if not self.parent or not self.image.texture:
return
(par_x, par_y) = self.parent.size
if par_x == 0 or par_y == 0:
with self.canvas:
self.canvas.clear()
return
par_scale = par_x / par_y
(img_x, img_y) = self.image.texture.size
img_scale = img_x / img_y
if par_scale > img_scale:
(img_x_new, img_y_new) = (img_x, img_x / par_scale)
else:
(img_x_new, img_y_new) = (img_y * par_scale, img_y)
crop_pos_x = (img_x - img_x_new) / 2
crop_pos_y = (img_y - img_y_new) / 2
subtexture = self.image.texture.get_region(
crop_pos_x, crop_pos_y, img_x_new, img_y_new
)
with self.canvas:
self.canvas.clear()
Color(1, 1, 1)
Rectangle(texture=subtexture, pos=self.pos, size=(par_x, par_y))
class Example(App):
def __init__(self, **kwargs):
with open("images/song_img.jpg", "rb") as song_img:
self.song_img_bytes = BytesIO(song_img.read())
super(Example, self).__init__(**kwargs)
self.kv = Builder.load_string('''
#:kivy 2.0.0
BoxLayout:
orientation: "vertical"
padding: 10
ByteFitImage:
id: img
data: app.song_img_bytes
Button:
text: "Change cover!"
font_size: 32
on_release: app.change_cover()''')
def build(self):
return self.kv
def change_cover(self):
with open("images/second_img.jpg", "rb") as second_img:
self.kv.ids.img.data = BytesIO(second_img.read())
if __name__ == '__main__':
Example().run()
So, I want that my buttons call a function when released, so that my labels come up visible.
As you can see the button's on_release is set to buttonPress where I wanted to do this, but whichever button I press it passes the last label into the function. How can I fix this? Is there a better way to do this?
def buttonPress(self, label):
print("hi")
print(label)
label.height = '50dp'
label.font_size = '20sp'
def on_pre_enter(self, *args):
mainLayout = RelativeLayout()
self.add_widget(mainLayout)
scroll = ScrollView(do_scroll_x = False,pos_hint={"top":0.8,"center_x":0.75})
infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
mainLayout.add_widget(scroll)
scroll.add_widget(infoLayout)
files = glob.glob("user/*.txt")
InfoWidgetButtonArray = []
InfoWidgetLabelArray = []
for x in range(len(files)):
InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
print(InfoWidgetLabelArray[x])
InfoWidgetButtonArray.append(Button(text=files[x][5:][:-4], font_size=14, size_hint=(0.5, None), height=30,on_release=lambda lambdaFunction: self.buttonPress(InfoWidgetLabelArray[x])))
infoLayout.add_widget(InfoWidgetButtonArray[x])
infoLayout.add_widget(InfoWidgetLabelArray[x])
Here is a minimal reproducible example:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.widget import Widget
Window.clearcolor = (1,1,1,1)
class InfoScreen(Screen, Widget):
new = True
def buttonPress(self, label):
print("hi")
print(label)
label.height = '50dp'
label.font_size = '20sp'
def on_pre_enter(self, *args):
mainLayout = RelativeLayout()
self.add_widget(mainLayout)
scroll = ScrollView(do_scroll_x = False,pos_hint={"top":0.8,"center_x":0.75})
infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
mainLayout.add_widget(scroll)
scroll.add_widget(infoLayout)
InfoWidgetButtonArray = []
InfoWidgetLabelArray = []
for x in range(2):
InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
print(InfoWidgetLabelArray[x])
InfoWidgetButtonArray.append(Button(text="name"+str(x), font_size=14, size_hint=(0.5, None), height=30,on_release=lambda lambdaFunction: self.buttonPress(InfoWidgetLabelArray[x])))
infoLayout.add_widget(InfoWidgetButtonArray[x])
infoLayout.add_widget(InfoWidgetLabelArray[x])
SpacingButton = Button(text='Hello world', font_size=14, size_hint=(0.5, None), height=50, color=(0, 0, 0, 0), background_color=(0,0,0,0))
infoLayout.add_widget(SpacingButton)
infoLayout.bind(minimum_height=infoLayout.setter('height'))
sm = ScreenManager()
sm.add_widget(InfoScreen(name='Info'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
I think you're looking for the partial function from the functools module. It binds the input in your for loop and returns the actual function you want it to have.
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
from functools import partial #Changed This
Window.clearcolor = (1,1,1,1)
class InfoScreen(Screen, Widget):
new = True
def buttonPress(self, label, *args):
print("hi")
print(label)
label.height = '50dp'
label.font_size = '20sp'
def on_pre_enter(self, *args):
mainLayout = RelativeLayout()
self.add_widget(mainLayout)
scroll = ScrollView(do_scroll_x = False, pos_hint={"top":0.8,"center_x":0.75}, size_hint_max_y=300) #To enable scrolling be sure to set a maximal value, or have enough buttons to cover the whole window
infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
mainLayout.add_widget(scroll)
scroll.add_widget(infoLayout)
InfoWidgetButtonArray = []
InfoWidgetLabelArray = []
for x in range(5):
InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
print(InfoWidgetLabelArray[x])
InfoWidgetButtonArray.append(Button(text="name"+str(x), font_size=14, size_hint=(0.5, None), height=30, on_release=partial(self.buttonPress, InfoWidgetLabelArray[x]))) #Changed This
infoLayout.add_widget(InfoWidgetButtonArray[x])
infoLayout.add_widget(InfoWidgetLabelArray[x])
SpacingButton = Button(text='Hello world', font_size=14, size_hint=(0.5, None), height=50, color=(0, 0, 0, 0), background_color=(0,0,0,0))
infoLayout.add_widget(SpacingButton)
infoLayout.bind(minimum_height=infoLayout.setter('height'))
sm = ScreenManager()
sm.add_widget(InfoScreen(name='Info'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Hope this is what you were looking for, I spent some time rereading the question before I hopefully understood.