# THIS FILE IS A PART OF VCStudio # PYTHON 3 import os from subprocess import * # GTK module ( Graphical interface import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import GLib from gi.repository import Gdk import cairo # Own modules from settings import settings from settings import talk from settings import fileformats from project_manager import pm_project #UI modules from UI import UI_elements from UI import UI_color # story from studio import story from studio import analytics from studio import history from studio import studio_dialogs # network from network import multiuser_terminal 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) UI_color.set(layer, win, "dark_overdrop") layer.rectangle( 0, 0, win.current["w"], win.current["h"], ) layer.fill() ############################################################################ # This is our multiuser UI. From here the user will start and stop the server # for the multiuser. See what that server has to say. And write text messages # to all the other users. Like a little messaging app, so they will not use # closed source apps for this. I know a lot of companies that ustilize # whatsapp for this. This is not cool. And I can make a little app here. # The way it's going to look it the folosing. ############################################################################ # START / STOP BUTTON # # ###################################################### BOB: Hello World # # # # # server started # Steve: What's Up # # BOB connected # # # Steve connected # John: Hey guys # # John connected # who can make the # # Steve updated Moria # rig for Moria? # # John reqested Moria # # # Steve sent Moria to John # Steve: I can. # # # # #################################################### # John: Thanks. # # 3 users connected: # # # BOB # # # John ####################### # Steve # # # ############################################################################ # I know that it's a bit unfair to give so much space to a terminal like # output window. But this is kind of the most important thing in the # entire Multiuser. The server. Actually the server will run only on one # computer. But all users will feel like they are controlling the server. # I don't like when one user thinks that he is more important then the other # . Because in the film production. Usually the director listens even to # the guy who makes the tea. In the case of this program I want everybody # to feel exactly the same amount of power. ############################################################################ win.multiuser["unread"] = 0 # SERVER PEACE FRAME UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, 80, 80, win.current["w"]/3*2-160, win.current["h"]/2-100, 10) # USERS PEACE FRAME UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, 80, win.current["h"]/2, win.current["w"]/3*2-160, win.current["h"]/2-80, 10) # THE SIDE PEACE FRAME UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, win.current["w"]/3*2-60, 80, win.current["w"]/3-20, win.current["h"]-160, 10) ####### SERVER PART ####### # On the top panel first button will be either make a server. Or if server exists, # close the server. This will require a little dialog similar to when deleting # scenes in the story editor. # I'm going to hack my way into checking the server. Basically it autoconnects to # it if one is up. So.. if win.multiuser["server"]: def do(): # Simple UDP message multiuser_terminal.message("VCStudio ABORT MULTIUSER") UI_elements.roundrect(layer, win, 90, 90, 40, 40, 10, button=do, icon="server_close", tip=talk.text("multiuser_server_stop")) else: def do(): # Simple Popen Popen(["python3", "network/multiuser_server.py", win.analytics["name"]]) UI_elements.roundrect(layer, win, 90, 90, 40, 40, 10, button=do, icon="server_new", tip=talk.text("multiuser_server_start")) # Server outputs part. I'm creating a layer for it just because it needs # a clipping. x = 90 y = 140 width = win.current["w"]/3*2-160-20 height = win.current["h"]/2-170 # Making the layer surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) node = cairo.Context(surface2) node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) # Clip UI_elements.roundrect(node, win, 0, 0, width, height, 10, fill=False) node.clip() # Background tester #UI_color.set(node, win, "dark_overdrop") #node.rectangle(0,0,width, height) #node.fill() # Here I want to have the output of the server in a raw fasion. if "multiuser_terminal" not in win.scroll: win.scroll["multiuser_terminal"] = 0 current_Y = 10 for message in win.multiuser["terminal"]: # We are going to draw a little server icon. UI_elements.image(node, win, "settings/themes/"+win.settings["Theme"]+"/icons/server.png", 10, current_Y+win.scroll["multiuser_terminal"], 40, 40) # And we want to have the text of the message UI_color.set(node, win, "text_normal") node.set_font_size(15) node.move_to( 60, current_Y+win.scroll["multiuser_terminal"]+27) node.show_text(message) current_Y = current_Y + 50 # Outputting the layer layer.set_source_surface(surface2, x, y) layer.paint() UI_elements.scroll_area(layer, win, "multiuser_terminal", x, y, width, height, current_Y, bar=True, mmb=True) ############ USERS PART ############## # Here in this part I want to put a complite list of currently connected users. # I have few ideas of what functionality could be added to here. But at this # point I'm just trying to make the window somewhat busy looking. # So we need to make layer here. Since I want to clip it. But be able to draw outisde # the clipping area later. x = 90 y = win.current["h"]/2+10 width = win.current["w"]/3*2-160-20 height = win.current["h"]/2-80-60 # Making the layer surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) node = cairo.Context(surface2) node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) # Clip UI_elements.roundrect(node, win, 0, 0, width, height, 10, fill=False) node.clip() # Background tester #UI_color.set(node, win, "dark_overdrop") #node.rectangle(0,0,width, height) #node.fill() if "multiuser_users" not in win.scroll: win.scroll["multiuser_users"] = 0 current_Y = 10 for ip in list(win.multiuser["users"].keys()): try: user = win.multiuser["users"][ip] except: continue username = user["username"] # For each user I want to show the name, then IP:PORT # If it's us on the list I want to draw a little rectangle arround # this particular user if ip == win.multiuser["userid"]: UI_color.set(node, win, "node_blendfile") UI_elements.roundrect(node, win, 0, current_Y+win.scroll["multiuser_users"]-5, width, 45, 10) # User Icon UI_elements.image(node, win, "settings/themes/"+win.settings["Theme"]+"/icons/user.png", 10, current_Y+win.scroll["multiuser_users"], 40, 40) # Text UI_color.set(node, win, "text_normal") node.set_font_size(20) node.move_to( 60, current_Y+win.scroll["multiuser_users"]+25) node.show_text(username+" | "+ip) current_Y = current_Y + 50 # Outputting the layer layer.set_source_surface(surface2, x, y) layer.paint() UI_elements.scroll_area(layer, win, "multiuser_users", x, y, width, height, current_Y, bar=True, mmb=True) # At the bottom I want to have a little multiuser icon with the count of users. # then a user icon and a name selection. UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/multiuser.png", x, y+height+5, 40, 40) # The little count thing at the corner if win.multiuser["users"]: count = str(len(win.multiuser["users"])) UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, x+25, y+height, len(count)*12+6, 25, 5) layer.fill() UI_color.set(layer, win, "text_normal") layer.set_font_size(20) layer.move_to(x+28,y+height+20) layer.show_text(count) # Documentation entry def do(): def after(win, var): pass studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_multiuser")) UI_elements.roundrect(layer, win, win.current["w"]/3*2-160, win.current["h"]-120, 40, 40, 10, do, icon="question") # CANCEl def do(): win.url = "story_editor" UI_elements.roundrect(layer, win, win.current["w"]/3*2-120, win.current["h"]-120, 40, 40, 10, button=do, icon="cancel", tip=talk.text("cancel")) # Short cut ESC if 65307 in win.current["keys"] and not win.textactive: do() ########## THE MESSANGER APP ON THE RIGHT ########## # I'm creating a layer for it just because it needs a clipping. x = win.current["w"]/3*2-50 y = 90 width = win.current["w"]/3-40 height = win.current["h"]-220 # Making the layer surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) node = cairo.Context(surface2) node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) # Clip UI_elements.roundrect(node, win, 0, 0, width, height, 10, fill=False) node.clip() # Background tester #UI_color.set(node, win, "dark_overdrop") #node.rectangle(0,0,width, height) #node.fill() # So here I want to present all the messages by all the users. if "multiuser_messages" not in win.scroll: win.scroll["multiuser_messages"] = 0 current_Y = 10 for message in win.multiuser["messages"]: # let's get the name of the user username = message[0] if username == "Multiuser Server": continue # User Icon UI_elements.image(node, win, "settings/themes/"+win.settings["Theme"]+"/icons/user.png", 10, current_Y+win.scroll["multiuser_messages"], 40, 40) UI_color.set(node, win, "text_normal") node.set_font_size(20) node.move_to(60, current_Y+win.scroll["multiuser_messages"]+25) node.show_text(username) current_Y = current_Y + 50 # Now the message it self going to need to have line breaks. For this # we are going to make similar rendering to the one in the script # writer. But simpler. tileX = 10 for word in message[1].split(" "): if tileX + len(word)*12+12 > width-10: tileX = 10 current_Y = current_Y + 30 UI_color.set(node, win, "text_normal") node.set_font_size(20) node.move_to(tileX, current_Y+win.scroll["multiuser_messages"]+25) node.show_text(word) tileX = tileX + len(word)*12+12 current_Y = current_Y + 50 # Outputting the layer layer.set_source_surface(surface2, x, y) layer.paint() UI_elements.scroll_area(layer, win, "multiuser_messages", x, y, width, height, current_Y, bar=True, mmb=True) # So here after the messages I want to make a little input for the new # message and a send button UI_elements.text(layer, win, "multiuser_message", x, y+height+5, width-50, 40) # Send button def do(): if win.text["multiuser_message"]["text"]: win.multiuser["request"] = ["message", win.text["multiuser_message"]["text"]] win.text["multiuser_message"]["text"] = "" UI_elements.roundrect(layer, win, x+width-40, y+height+5, 40, 40, 10, button=do, icon="send") # ENTER if 65293 in win.current["keys"]: do() win.current["keys"] = [] return surface