From d60c9fa31d1a71a056192f04bf0d4ef0c7948f7d Mon Sep 17 00:00:00 2001 From: jyamihud Date: Thu, 26 Nov 2020 15:32:28 +0000 Subject: [PATCH] Upload files to 'UI' --- UI/UI_color.py | 2 +- UI/UI_elements.py | 781 ++++++++++++++++++++++++++++++++++++++++++++++ UI/UI_testing.py | 147 +++++++++ 3 files changed, 929 insertions(+), 1 deletion(-) create mode 100644 UI/UI_elements.py create mode 100644 UI/UI_testing.py diff --git a/UI/UI_color.py b/UI/UI_color.py index a94b1bf..c03b90e 100644 --- a/UI/UI_color.py +++ b/UI/UI_color.py @@ -58,4 +58,4 @@ def set(layer, win, color): r,g,b,a = win.color[color] layer.set_source_rgba(r,g,b,a) except: - layer.set_source_rgba(1,0,1,1) \ No newline at end of file + layer.set_source_rgba(1,0,1,1) diff --git a/UI/UI_elements.py b/UI/UI_elements.py new file mode 100644 index 0000000..39ecba1 --- /dev/null +++ b/UI/UI_elements.py @@ -0,0 +1,781 @@ +# THIS FILE IS A PART OF VCStudio +# PYTHON 3 + +# This a console project manager. + +import os +import math + +# GTK module ( Graphical interface +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib +from gi.repository import GdkPixbuf +import cairo + +# Own modules +from settings import settings +from settings import talk + +# UI +from UI import UI_color + +def roundrect(layer, win, x, y, width, height, r, button=False, icon=False, + tip="", fill=True, url="", clip=False): + + # This function draws a rectangle with rounded edges. + + # A button variable is a calable for the button action. Basically it's a + # function. Roundrect will act as a button. + if button: + + #if not current url in the software + if url and url != win.url: + return + + # If UI testing is on preview. Buttons. + if win.current["testing"]: + UI_color.set(layer, win, "testing_banner") + layer.rectangle(x,y,width,height) + layer.stroke() + + + if win.current['mx'] in range(int(x), int(x+width)) \ + and win.current['my'] in range(int(y), int(y+height)) : + do = True + + if clip: + if win.current['mx'] in range(int(clip[0]), int(clip[0]+clip[2])) \ + and win.current['my'] in range(int(clip[1]), int(clip[1]+clip[3])) : + do = True + else: + do = False + + else: + do = False + + + + if do: + # If holding click + if win.current["LMB"]: + UI_color.set(layer, win, "button_clicked") + else: + UI_color.set(layer, win, "button_active") + # If clicked + if win.previous["LMB"] and not win.current["LMB"]: + button() + + # Button might have a tooltip as well + if tip: + tooltip(win, tip) + + + else: + do = True + + if do: + # Making sure that round rectangle will not be smaller then it's round- + # ness. Also with width and height zero, it's going to draw a circle. + + if width < r*2: + width = r*2 + if height < r*2: + height = r*2 + + # actuall drawing + layer.move_to(x,y+r) + layer.arc(x+r, y+r, r, math.pi, 3*math.pi/2) + layer.arc(x+width-r, y+r, r, 3*math.pi/2, 0) + layer.arc(x+width-r, y+height-r, r, 0, math.pi/2) + layer.arc(x+r, y+height-r, r, math.pi/2, math.pi) + layer.close_path() + if fill: + layer.fill() + + # Icon is a continuation of the button part. Because you need a way to see + # that that the button is even there to begin with. + if icon: + image(layer, win, "settings/themes/"\ + +win.settings["Theme"]+"/icons/"+icon+".png", x, y) + +def animate(name, win, v1=0, v2=None, time=10, force=False): + + # This function will make animating values over time possible. For smooth + # Transisions and things like this it's going to be very usefull. + + # Let's clear mess in case they I'm lazy to make all the things + if v2 == None: + v2 = v1 + + # Set up the animation into the animations. If it's not there yet. + if name not in win.animations or force: + win.animations[name] = [ + v1, + v2, + time, + win.current["frame"] + ] + + # Let's get data out of the win.animation[name] + v1 = win.animations[name][0] + v2 = win.animations[name][1] + time = win.animations[name][2] + start = win.animations[name][3] + frame = win.current["frame"] + + # If animation is over. + if start + time < frame: + return v2 + + # If v1 and v2 are the same. I'm doing it here. In case the value would be + # Animated later. So it will create the animation instance. + if v1 == v2: + return v2 + + if v1 < v2: + vN = v1 + ((v2 - v1)/time*(frame-start)) + else: + vN = v1 - ((v1 - v2)/time*(frame-start)) + + return vN + +def blur(surface, win, amount): + + # This function will blur a given layer by scaling it down and scaling it + # back up. It will be doing it only when a given blur setting it active. + + # To avoid all kinds of Zero devision problems. And speed up the draw if + # using animated blur values. + if amount < 3: # When Blue value was less then 3 it felt sharp but not enough + return surface # Which caused sense of uneasiness. + + # Setting up initial Blur + if not "Blur" in win.settings: + settings.write("Blur", True) # Writing to file + win.settings = settings.load_all() # Loading file back to RAM + + # If to active blur. Will be changed in the graphics settings. + if win.settings["Blur"]: + # scaling down + surface1 = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'], + win.current['h']) + slacedownlayer = cairo.Context(surface1) + slacedownlayer.scale(1/amount, + 1/amount) + + slacedownlayer.set_source_surface(surface, 0 , 0) + slacedownlayer.paint() + + #scaling back up + surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'], + win.current['h']) + slaceuplayer = cairo.Context(surface2) + slaceuplayer.scale(amount, + amount) + + slaceuplayer.set_source_surface(surface1, 0 , 0) + slaceuplayer.paint() + + return surface2 + else: + return surface + +def image(layer, win ,path, x, y, width=0, height=0, fit="crop"): + + # This module will handle drawing images to the layers. It's not that hard + # to do in cairo by default. But i'm doing it at every frame. And so it + # means a system of images should exist to take out the load. Basically + # it will make sure the images is loaded only ones. And for the next draw + # calls it will forward the old image. + + # Attempt of optimization. Keeping in mind the nature of the programm. Basi- + # cally I will not load image unless x and y are in frame. Kind a ugly. I + # know. But I don't want to even bother checking the resolution of the image + # if it's not in a frame. Roughly speaking. Will see maybe I will make do + # something to make it better. + + if int(x) not in range(int(0-width ), int(win.current["w"])) or \ + int(y) not in range(int(0-height), int(win.current["h"])) : + return + + # If you ran this software you probably noticed that images are loading + # dynamically. I did it using this following crazy algorythm borowed from + # the old organizer. Basically for each image I see it's any image is loading + # at the moment. If yes, wait. If not loading. Meaning it can take the turn + # I create a thread using GLib. Because I'm lazy. Which is loading the image. + # Basically the UI keeps working before all images are loaded. + + if path not in win.images or win.images[path] == "LOADING-IMAGE": + + win.images[path] = "LOADING-IMAGE" + + if not win.imageload: + win.imageload = True + def loadimage(layer, win ,path, x, y, width, height, fit): + + # Loading the image into the cairo. + try: + # It could be not PNG + try: + loadimage = cairo.ImageSurface.create_from_png(path) + except: + # If it's not png it's gonna take few steps + + # First we need to make a pixbuf. + load1 = GdkPixbuf.Pixbuf.new_from_file(path) + Px = load1.get_width() + Py = load1.get_height() + + # Then to convert the pixbuf to a cairo surface + loadimage = cairo.ImageSurface(cairo.FORMAT_ARGB32, Px, Py) + imagedraw = cairo.Context(loadimage) + Gdk.cairo_set_source_pixbuf( imagedraw, load1, 0, 0) + imagedraw.paint() + + # If I want to resize the image for an icon or something. There is + # gonna be the folowing algorythm. + + if width or height: + + dx = 0 + dy = 0 + + + imagesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) + imagedraw = cairo.Context(imagesurface) + + # Crop effect. Really hard on my brains. + + if fit == 'crop': + if height > loadimage.get_height()\ + or width > loadimage.get_width(): + + dx = (width/2) -(loadimage.get_width() /2) + dy = (height/2)-(loadimage.get_height()/2) + + else: + factor = 1 + if (loadimage.get_height()*(width/loadimage.get_width()))\ + < height: + factor = height / loadimage.get_height() + else: + factor = width / loadimage.get_width() + #factor = 0.1 + imagedraw.scale(factor, factor) + dx = (width/2)/factor -(loadimage.get_width() /2) + dy = (height/2)/factor -(loadimage.get_height()/2) + + + + imagedraw.set_source_surface(loadimage, dx, dy) + imagedraw.paint() + + + else: + imagesurface = loadimage + except Exception as e: + print(e) + imagesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) + + # Saving it into the win.images + win.images[path] = imagesurface + win.imageload = False + + GLib.timeout_add(1, loadimage, layer, win ,path, x, y, width, height, fit) + + #loading it back + else: + if win.images[path] != "LOADING-IMAGE": + imagesurface = win.images[path] + + # Writting the image to the screen + layer.set_source_surface(imagesurface, x, y) + layer.paint() + + # And if testing + + if win.current["testing"]: + UI_color.set(layer, win, "testing_image") + layer.rectangle(x,y,imagesurface.get_width(),imagesurface.get_height()) + layer.stroke() + +def tooltip(win, text): + + layer = win.tooltip + + # This function draws a tooltip helper window. + + # Just in case + text = str(text) + + # Let's get dimantions of the cube first. + lines = 0 + maxletters = 0 + + for line in text.split("\n"): + lines += 1 + + if len(line) > maxletters: + maxletters = len(line) + + + # Now when we now the mount of lines and the max lenght of a line. We can + # start actually drawing something. + + # Let's try to make so it's not out of the frame. + sx = win.current["mx"] + sy = win.current["my"] + + if sx+(maxletters*9)+40 > win.current["w"]: + sx = win.current["w"] - ((maxletters*9)+40) + if sy+(lines*20)+10 > win.current["h"]: + sy = win.current["h"] - ((lines*20)+10) + + # Rectangle + UI_color.set(layer, win, "node_background") + roundrect(layer, win, + sx, + sy, + (maxletters*9)+40, + (lines*20)+10, + 10) + + + # Text it self + layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, + cairo.FONT_WEIGHT_NORMAL) + layer.set_font_size(15) + UI_color.set(layer, win, "text_normal") + + for num, line in enumerate(text.split("\n")): + layer.move_to(sx+20, + sy+20+(20*num) ) + layer.show_text(line) + +def scroll_area(layer, win, name, x, y, width, height, maxlength, + bar=False,sideways=False, mmb=False, mmb_only=False, + url=""): + + # This function going to handle all the scrolling windows. Making it so it's + # relativelly simple to set up big widgets with in small areas. + # It will handle only the value of the scroll stored in win.scroll[name] + + if maxlength == 0: + maxlength = 1 + + # First let's set one up if it's not setup + if name not in win.scroll: + win.scroll[name] = 0 + return + + # Getting scroll amount based on all kinds of settings. AT THIS MOMENT + # IT'S IN AN ALPHA BECAUSE I'M LAZY. I GONNA IMPLEMENT THING AS I NEED THEM + # Or you can do that. IDK... + + amount = 0.0 + if win.current['mx'] in range(x, x+width) \ + and win.current['my'] in range(y, y+height) : + if not mmb_only: + if not sideways: + amount = win.current["scroll"][1]*50 + else: + amount = win.current["scroll"][0]*50 + + if mmb_only: + mmb = True + + # Middle mouse button scroll, or using a graphical tablet. + if mmb: + if win.current["MMB"]: + amount = 0 - ( win.current["my"] - win.previous["my"] ) + + # I guess I need to separate the logic into a separate minifunction. + # I will use later for the scroll bar thingy. So not to rewrite the code + # Here is a function thingy. + + def logic(): + if url and url != win.url: + return + # Scroll logic + win.scroll[name] -= amount + + # If too low + if win.scroll[name] < (1-maxlength+height): + win.scroll[name] = (1-maxlength+height) + # If too high + if win.scroll[name] > 0: + win.scroll[name] = 0 + logic() + # Not BAR. Which is going to be drawn at a side of what ever content there + # Basically a scrollbar. But implemented from scratch. Because I'm crazy. + # and have nothing better to do now. + + if bar: + + # For now I'm going to implement only vertical bar. I gonna implement + # the horisontal one when the time comes. + + if not sideways: + + # Fist let's make some math in front. Because things like this + # require ton of maths. And it's good to have some predone. + + tobreak = False # Also if we can abort the operation early with it. + fraction = height / maxlength # Similar to progress bar for now + if fraction > 1: + tobreak = True + + # To break parameter basically says. To draw it the bar only when + # it's actully needed. When content aka maxlength is bigger then + # our viewport. + + if not tobreak: + + # Now the offset value. That will move our progress bar with + # the scroll value. + + offset = (height-60)*( (1-win.scroll[name]) / maxlength ) + + # Background bar + + UI_color.set(layer, win, "background") + roundrect(layer, win, + (x+width)-20, + y+30, + 10, + height-60, + 5 + ) + + # Active bar + + UI_color.set(layer, win, "button_active") + + # Let's save a little bit more math because it's going to be + # vild. And I love it. + + Lx = (x+width)-20 + LSx = 10 + Ly = y+30+offset + LSy = (height-60)*fraction + + # Mouse over thingy. To make the bat a tiny bit brighter. + # indicating to the user that it's now could be used. + + if win.current['mx'] in range(int(Lx), int(Lx+LSx)) \ + and win.current['my'] in range(int(Ly), int(Lx+LSy)) : + UI_color.set(layer, win, "button_clicked") + + # Now separatelly we gonna check for if the mouse pressed. + # Remember if it's not pressed it's False. It's written in one + # of the files. Basically I want to be able to move the mouse + # outside the bar while moving. And so it won't cancel the motion. + + # It seems like I did something wrong. Anyways it works. + + if win.current["LMB"]: + if int(win.current['LMB'][0]) in range(int(Lx), int(Lx+LSx)) \ + and int(win.current['LMB'][1]) in range(int(Ly), int(Lx+(height-60))) : + + UI_color.set(layer, win, "button_clicked") + + # A bit more math to set the value back. + amount = ( win.current["my"] - win.previous["my"] ) / \ + (height-60) * maxlength + logic() # Yeah. Look a few lines back. + + # And only after all of this nonsense we can draw the cube. Or + # should I say roundrect? A button? Aaaaaa.... + + roundrect(layer, win, + Lx, + Ly, + LSx, + LSy, + 5 + ) + + +def text(outlayer, win, name, x, y, width, height, set_text="", parse=False, fill=True, + editable=True, multiline=False , linebreak=False, centered=False): + + # This function will handle all the text writting in the software. + # I'm not sure about how parsing going to work for script files later. + # But if it's currently works, means that I already implemented it into + # the program. + + # Making the layer + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) + layer = cairo.Context(surface) + layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + layer.set_font_size(20) + + # Some challenges that it will have is how to correctly store data about + # the text in the system. I think we can use the win.text variable to store + # directories of the data. + + if name not in win.text: + + # I need to get something done before I can pu scroll in. + scrollname = name + while scrollname in win.scroll: + scrollname = scrollname+"_text" + + win.text[name] = { + "text" :set_text, # Actuall text you are editing. + "cursor":[len(str(set_text)),len(str(set_text))], # Cursor + "insert":False, # Whether the insert mode is on + "scroll":scrollname # If multiline. The pointer for the scroll value. + } + + # Background + if fill: + UI_color.set(layer, win, "darker_parts") + roundrect(layer, win, + 0, + 0, + width, + height, + 10) + layer.fill() + + # Now after filling it up. I want to clip everything. SO no text will get + # out of a given area. + roundrect(layer, win, + 0, + 0, + width, + height, + 10, + fill=False) + layer.clip() + + # Now I want to give a preview of the text it self. BUT. I need to be sure + # that if the text longer then a given width and there is no multiline or a + # linebreak. Then it scrolls sideways to the cursor. + + # Automatic scroll system: Based on the position of the cursor. + offsetX = 0 + cursor2location = win.text[name]["cursor"][1]*12 + offsetX + while cursor2location > width - 50: + offsetX -= 1 + cursor2location = win.text[name]["cursor"][1]*12 + offsetX + + + # Text selection. AKA cursor + # So here we draw the cursor + if editable: + UI_color.set(layer, win, "node_blendfile") + if win.text[name]["cursor"][0] == win.text[name]["cursor"][1]: + layer.rectangle( + win.text[name]["cursor"][0]*12+5 +offsetX, + 5, + (win.text[name]["cursor"][1]*12)-(win.text[name]["cursor"][0]*12)+2, + 30 + ) + else: + roundrect(layer, win, + win.text[name]["cursor"][0]*12+5 +offsetX, + 5, + (win.text[name]["cursor"][1]*12)-(win.text[name]["cursor"][0]*12)+2, + 30, + 5, + fill=False + ) + if win.textactive == name: + layer.fill() + else: + layer.stroke() + + + # Making sure that cursor is correct. Because a lot of bugs are happening + # with it and it's not cool. + + # Mouse select + if win.current["LMB"]: + if int(win.current["mx"]) in range(int(x), int(x+width))\ + and int(win.current["my"]) in range(int(y), int(y+height)): + win.text[name]["cursor"][0] = int((win.current["LMB"][0]-x-offsetX)/12) + win.text[name]["cursor"][1] = int((win.current["mx"]-x-offsetX)/12) + + # If second part of selection ends up bigger then the first. Reverse them. + if win.text[name]["cursor"][0] > win.text[name]["cursor"][1]: + win.text[name]["cursor"] = [ + win.text[name]["cursor"][1], + win.text[name]["cursor"][0]] + + # If any part ends up beyond the text. Clip them in. + if win.text[name]["cursor"][0] < 0: + win.text[name]["cursor"][0] = 0 + if win.text[name]["cursor"][1] < 0: + win.text[name]["cursor"][1] = 0 + if win.text[name]["cursor"][0] > len(str(win.text[name]["text"])): + win.text[name]["cursor"][0] = len(str(win.text[name]["text"])) + if win.text[name]["cursor"][1] > len(str(win.text[name]["text"])): + win.text[name]["cursor"][1] = len(str(win.text[name]["text"])) + + + + # Drawing the text + + UI_color.set(layer, win, "text_normal") + layer.move_to(5+offsetX, height/2+5) + if centered: + layer.move_to(width/2-len(str(win.text[name]["text"]))*12/2, height/2+5) + layer.show_text(str(win.text[name]["text"])) + + # Editing the text + if win.current["keys"] and editable and name == win.textactive: + # Let's filter the input first. + # For example + if not multiline: #Removing enter key press + if 65293 in win.current["keys"] or 65421 in win.current["keys"]: + win.current["key_letter"] = "" + + prevlen = len(win.text[name]["text"]) + clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + regularclean = True + ORD = 0 + try: + ORD = ord(win.current["key_letter"]) + except: + pass + backremove = False # Whether to make selection go to 0 width thing + #print(ORD, win.text[name]["cursor"][0]) + + + # Backspace + if 65288 in win.current["keys"]: + if win.text[name]["cursor"][0] != 0 and win.text[name]["cursor"][0]\ + == win.text[name]["cursor"][1]: + + win.text[name]["text"] = win.text[name]["text"]\ + [:win.text[name]["cursor"][0]-1]+\ + win.text[name]["text"]\ + [win.text[name]["cursor"][1]:] + + elif win.text[name]["cursor"][1] != 0 and win.text[name]["cursor"][0]\ + != win.text[name]["cursor"][1]: + + win.text[name]["text"] = win.text[name]["text"]\ + [:win.text[name]["cursor"][0]]+\ + win.text[name]["text"]\ + [win.text[name]["cursor"][1]:] + backremove = True + + # Ctrl - C + elif ORD == 3: + + cliptext = str(clipboard.wait_for_text()) + + clipboard.set_text( win.text[name]["text"]\ + [win.text[name]["cursor"][0]:win.text[name]["cursor"][1]], -1) + + # Ctrl - V + elif ORD == 22: + + cliptext = str(clipboard.wait_for_text()) + + win.text[name]["text"] = win.text[name]["text"]\ + [:win.text[name]["cursor"][0]]\ + + cliptext +\ + win.text[name]["text"]\ + [win.text[name]["cursor"][1]:] + win.text[name]["cursor"][0] = win.text[name]["cursor"][1] + + # Ctrl - A + elif ORD == 1: + win.text[name]["cursor"][0] = 0 + win.text[name]["cursor"][1] = len(win.text[name]["text"]) + + # To clear up the Controll + elif 65507 in win.current["keys"]: + pass + + # Shift + elif 65506 in win.current["keys"]: + # Right + if 65363 in win.current["keys"]: + win.text[name]["cursor"][1] = win.text[name]["cursor"][1] + 1 + #win.current["keys"].remove(65363) + + # Left + elif 65361 in win.current["keys"]: + if win.text[name]["cursor"][1] > win.text[name]["cursor"][0]: + win.text[name]["cursor"][1] = win.text[name]["cursor"][1] - 1 + #win.current["keys"].remove(65361) + + # Right button + elif 65363 in win.current["keys"]: + win.text[name]["cursor"][0] = win.text[name]["cursor"][0] + 1 + win.text[name]["cursor"][1] = win.text[name]["cursor"][0] + win.current["keys"].remove(65363) + + # Left button + elif 65361 in win.current["keys"]: + win.text[name]["cursor"][0] = win.text[name]["cursor"][0] - 1 + win.text[name]["cursor"][1] = win.text[name]["cursor"][0] + win.current["keys"].remove(65361) + + # Escape + elif 65307 in win.current["keys"]: + win.textactive = "" + win.current["keys"].remove(65307) + + else: + win.text[name]["text"] = win.text[name]["text"]\ + [:win.text[name]["cursor"][0]]\ + + win.current["key_letter"]+\ + win.text[name]["text"]\ + [win.text[name]["cursor"][1]:] + + + # Auto moving the cursor + nowlen = len(win.text[name]["text"]) + if win.text[name]["cursor"][0] == win.text[name]["cursor"][1]: + win.text[name]["cursor"][0] = win.text[name]["cursor"][0] + (nowlen - prevlen) + win.text[name]["cursor"][1] = win.text[name]["cursor"][0] + + elif backremove: + win.text[name]["cursor"][1] = win.text[name]["cursor"][0] + + + if nowlen != prevlen and regularclean: + # Deleting all the keys from the keys. So yeah. + win.current["keys"] = [] + + + + + # Outputing to the outlayer. + outlayer.set_source_surface(surface, x, y) + outlayer.paint() + + # Button if editable. + if editable: + def do(): + win.textactive = name + roundrect(outlayer, win, + x, + y, + width, + height, + 10, + fill=False, + button=do) + outlayer.stroke() + + if win.textactive == name: + UI_color.set(outlayer, win, "button_active") + roundrect(outlayer, win, + x, + y, + width, + height, + 10, + fill=False) + outlayer.stroke() + diff --git a/UI/UI_testing.py b/UI/UI_testing.py new file mode 100644 index 0000000..d39bcb6 --- /dev/null +++ b/UI/UI_testing.py @@ -0,0 +1,147 @@ +# THIS FILE IS A PART OF VCStudio +# PYTHON 3 + +# This a console project manager. + +import os + +# GTK module ( Graphical interface +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +import cairo + +# Own modules +from settings import settings +from settings import talk + +#UI modules +from UI import UI_elements +from UI import UI_color + + +def layer(win): + + # Making the layer + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'], + win.current['h']) + layer = cairo.Context(surface) + + #text setting + layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + + # Variables I will need tfor animations + testing_bar = UI_elements.animate("UI_testing_banner", win) + + + # Testing top banner thingy + if testing_bar > 0.01: + layer.set_source_rgba(1,1,1,0.5) + UI_elements.roundrect(layer, win, + 5, + 5, + (win.current['w']-10)*testing_bar, + 30, + 10) + + + # testing will be drawn only it's activated + if win.current["testing"]: + + #Animating values + testing_bar = UI_elements.animate("UI_testing_banner", win, testing_bar, 1, 10, force=True) + + + + # Current Framerate + UI_color.set(layer, win, "testing_banner") + UI_elements.roundrect(layer, win, + 5, + 5, + 60, + 30, + 10) + + + UI_color.set(layer, win, "testing_text") + layer.set_font_size(20) + layer.move_to(20,27) + layer.show_text(str(win.FPS)) + + + + # Mouse Visualization thingy + for n ,button in enumerate(["LMB", "MMB", "RMB"]): + + if win.current[button]: + UI_color.set(layer, win, button) + + #line from click to current mouse position + layer.move_to(win.current[button][0], + win.current[button][1]) + layer.line_to(win.current["mx"], + win.current["my"]) + layer.stroke() + + else: + UI_color.set(layer, win, "testing_banner") + UI_elements.roundrect(layer, win, + 75 + (35 * n), + 5, + 30, + 30, + 10) + + + # Keyboard + UI_color.set(layer, win, "testing_banner") + UI_elements.roundrect(layer, win, + 185, + 5, + 30, + 30, + 10) + + + UI_color.set(layer, win, "testing_text") + layer.set_font_size(20) + layer.move_to(195,27) + layer.show_text(win.current["key_letter"]) + + for n, key in enumerate(win.current["keys"]): + UI_color.set(layer, win, "testing_banner") + UI_elements.roundrect(layer, win, + 220 + (80 * n), + 5, + 75, + 30, + 10) + + + UI_color.set(layer, win, "testing_text") + layer.set_font_size(20) + layer.move_to(225 + (80 * n),27) + layer.show_text(str(key)) + + else: # if not testing bar + # Animating back to 0 + testing_bar = UI_elements.animate("UI_testing_banner", win, testing_bar, 0, 10, force=True) + + # Switch to activate testing (or diactivate it). Top, Right corner. + def do(): + # Mouse Click + win.current["testing"] = not win.current["testing"] + + UI_color.set(layer, win, "testing_banner") + UI_elements.roundrect(layer, win, + win.current['w'] - 35, + 5, + 30, + 30, + 10, + do, + tip=talk.text("UI_testing_tooltip")) + + + + return surface