Implementing Markdown
This was hard. But now I can post documentation directly into the help dialogue. Instead of it being links to outside sources. I will do this for the next update.
This commit is contained in:
parent
31e4548ac3
commit
d285635870
3 changed files with 991 additions and 27 deletions
765
UI/UI_Markdown.py
Normal file
765
UI/UI_Markdown.py
Normal file
|
@ -0,0 +1,765 @@
|
||||||
|
####################################
|
||||||
|
# #
|
||||||
|
# COPYRIGHT NOTICE #
|
||||||
|
# #
|
||||||
|
# This file is a part of Victori- #
|
||||||
|
# ous Children Studio Organizer. #
|
||||||
|
# Or simply VCStudio. Copyright #
|
||||||
|
# of J.Y.Amihud. But don't be sad #
|
||||||
|
# because I released the entire #
|
||||||
|
# project under a GNU GPL license. #
|
||||||
|
# You may use Version 3 or later. #
|
||||||
|
# See www.gnu.org/licenses if your #
|
||||||
|
# copy has no License file. Please #
|
||||||
|
# note. Ones I used the GPL v2 for #
|
||||||
|
# it. It's no longer the case. #
|
||||||
|
# #
|
||||||
|
####################################
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
# 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 oscalls
|
||||||
|
from project_manager import pm_project
|
||||||
|
|
||||||
|
#UI modules
|
||||||
|
from UI import UI_elements
|
||||||
|
from UI import UI_color
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Markdown. Or .md file format is an easy way to give your simple text documents
|
||||||
|
# a bit of flare. Stuff like links, images and quotes are supported. Also bold
|
||||||
|
# an italic characters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Open(win, filename, name):
|
||||||
|
|
||||||
|
# This function will parse a Markdown (.md) file into a readable python
|
||||||
|
# dictionary object. That you can use for various things.
|
||||||
|
try:
|
||||||
|
|
||||||
|
# If the file is local. AKA exists in the folder. And can be read.
|
||||||
|
# Also it could be not .md
|
||||||
|
if not filename.endswith(".md"):
|
||||||
|
1/0 # Quick fail switch
|
||||||
|
|
||||||
|
md = open(filename)
|
||||||
|
md = md.read()
|
||||||
|
|
||||||
|
except:
|
||||||
|
|
||||||
|
# If reading fails. For example if it's a link to something on the
|
||||||
|
# web. Then try just opening it in the standard application.
|
||||||
|
|
||||||
|
md = ""
|
||||||
|
oscalls.Open(filename)
|
||||||
|
win.current["mdfs"][name] = win.current["mdfs"]["failsafe"]
|
||||||
|
|
||||||
|
|
||||||
|
md = md.split("\n")
|
||||||
|
|
||||||
|
# First thing is I was to read the headings and convert it into a tree.
|
||||||
|
|
||||||
|
|
||||||
|
tree = []
|
||||||
|
indent = 1
|
||||||
|
c = []
|
||||||
|
|
||||||
|
for line in md:
|
||||||
|
|
||||||
|
ty = "text"
|
||||||
|
te = line
|
||||||
|
|
||||||
|
# Here I want to simply get a type of each line. Later we going to parse
|
||||||
|
# the links and other things. But first. Let's parse stuff based on
|
||||||
|
# lines.
|
||||||
|
|
||||||
|
if line.startswith("#"):
|
||||||
|
# The titles of the chapter. The Headers are usually written similar
|
||||||
|
# to how here in python you write comments. It's a # , space, and the
|
||||||
|
# text.
|
||||||
|
|
||||||
|
# The amount of hashes. ## or ### gives different sized text. Officialy
|
||||||
|
# it should support up to 6 hashes. ######. But why not make it more
|
||||||
|
# just in case.
|
||||||
|
|
||||||
|
ty = line.count("#") # This might give bugs
|
||||||
|
|
||||||
|
elif line.startswith("> "):
|
||||||
|
|
||||||
|
# The > sign in the Markdown language is used for quatations.
|
||||||
|
|
||||||
|
ty = "quote"
|
||||||
|
|
||||||
|
tree.append([ty, te+"\n"])
|
||||||
|
|
||||||
|
# Now the stage 0 is over and we parsed the basic things. Now is the hard
|
||||||
|
# part to parse out all the images and stuff inside them. It's going to be
|
||||||
|
# done per part. And we are going to use the same technique I used for the
|
||||||
|
# conversion of the legacy projects. See : studio/story.py
|
||||||
|
|
||||||
|
# We are going to itterate over each letter. And decide what to do by that
|
||||||
|
|
||||||
|
newtree = []
|
||||||
|
|
||||||
|
for block in tree:
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
skip = 0
|
||||||
|
|
||||||
|
for n, l in enumerate(block[-1]):
|
||||||
|
|
||||||
|
if skip > n:
|
||||||
|
continue
|
||||||
|
|
||||||
|
part = part + l
|
||||||
|
|
||||||
|
# Here we are going to do something if a give condition is met.
|
||||||
|
# Usually I gonna do something if [part] ends with a given markdown
|
||||||
|
# thing. I don't have a mnual of markdown on me. So please make it
|
||||||
|
# more supported. I guess. I might forget things I rarely use.
|
||||||
|
|
||||||
|
# Links are made with [stuff you click on](https://example.com)
|
||||||
|
# but similar to it. Images are done ![Tooltip](Image.png)
|
||||||
|
# and even weirder you can put one into the other. Like
|
||||||
|
# [![Tooltip](Image.png)](https://example.com)
|
||||||
|
# Which going to give you a clickable image.
|
||||||
|
|
||||||
|
# For this version what we are going to do is next.
|
||||||
|
# If we got [![ then it's a clickable image
|
||||||
|
# If we got ![ then it's just image
|
||||||
|
# and if we got [ then it's a link.
|
||||||
|
|
||||||
|
if part.endswith("[!["):
|
||||||
|
|
||||||
|
# IMAGE LINK
|
||||||
|
newtree.append([block[0], part[:-3]])
|
||||||
|
|
||||||
|
tooltip = ""
|
||||||
|
imageurl = ""
|
||||||
|
url = ""
|
||||||
|
t = False
|
||||||
|
iu = False
|
||||||
|
skip = n
|
||||||
|
for le in block[-1][n:]: # For letters in the rest of text
|
||||||
|
|
||||||
|
skip = skip + 1
|
||||||
|
|
||||||
|
if le == "]":
|
||||||
|
t = True
|
||||||
|
elif le == ")" and t and not iu:
|
||||||
|
iu = True
|
||||||
|
elif le == ")" and t and iu:
|
||||||
|
break
|
||||||
|
elif not t:
|
||||||
|
tooltip = tooltip +le
|
||||||
|
elif t and not iu:
|
||||||
|
imageurl = imageurl + le
|
||||||
|
else:
|
||||||
|
url = url+le
|
||||||
|
|
||||||
|
tooltip = tooltip[tooltip.find("[")+1:]
|
||||||
|
imageurl = imageurl[imageurl.find("(")+1:]
|
||||||
|
url = url[url.find("(")+1:]
|
||||||
|
|
||||||
|
apnd = ["image_link", tooltip, imageurl, url]
|
||||||
|
|
||||||
|
newtree.append(apnd)
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
|
||||||
|
|
||||||
|
elif part.endswith("!["):
|
||||||
|
|
||||||
|
# IMAGE
|
||||||
|
|
||||||
|
newtree.append([block[0], part[:-2]])
|
||||||
|
|
||||||
|
tooltip = ""
|
||||||
|
url = ""
|
||||||
|
t = False
|
||||||
|
skip = n
|
||||||
|
for le in block[-1][n:]: # For letters in the rest of text
|
||||||
|
|
||||||
|
skip = skip + 1
|
||||||
|
|
||||||
|
if le == "]":
|
||||||
|
t = True
|
||||||
|
elif le == ")" and t:
|
||||||
|
break
|
||||||
|
elif not t:
|
||||||
|
tooltip = tooltip +le
|
||||||
|
else:
|
||||||
|
url = url+le
|
||||||
|
|
||||||
|
tooltip = tooltip[tooltip.find("[")+1:]
|
||||||
|
url = url[url.find("(")+1:]
|
||||||
|
|
||||||
|
apnd = ["image", tooltip, url]
|
||||||
|
newtree.append(apnd)
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
|
||||||
|
|
||||||
|
elif part.endswith("[") and not block[-1][n:].startswith('[!['):
|
||||||
|
|
||||||
|
# LINK
|
||||||
|
newtree.append([block[0], part[:-1]])
|
||||||
|
|
||||||
|
|
||||||
|
tooltip = ""
|
||||||
|
url = ""
|
||||||
|
t = False
|
||||||
|
skip = n
|
||||||
|
for le in block[-1][n:]: # For letters in the rest of text
|
||||||
|
|
||||||
|
skip = skip + 1
|
||||||
|
|
||||||
|
if le == "]":
|
||||||
|
t = True
|
||||||
|
elif le == ")" and t:
|
||||||
|
break
|
||||||
|
elif not t:
|
||||||
|
tooltip = tooltip +le
|
||||||
|
else:
|
||||||
|
url = url+le
|
||||||
|
|
||||||
|
tooltip = tooltip[tooltip.find("[")+1:]
|
||||||
|
url = url[url.find("(")+1:]
|
||||||
|
|
||||||
|
apnd = ["link", tooltip, url]
|
||||||
|
newtree.append(apnd)
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Now I want to deal with `, *, ** and ***. If you want to help me you
|
||||||
|
# can implement other types. Such as _, __, ___ and so on. Markdown is
|
||||||
|
# a very rich language. I'm going to use the cut down version I see other
|
||||||
|
# people use.
|
||||||
|
|
||||||
|
# BTW this is the time. Feb 28. When I switched from Gedit to GNU Emacs.
|
||||||
|
# Interesting feeling using this programm. I kind a love it even tho
|
||||||
|
# so many stuff in not intuitive. Like saving is not Ctrl - S but
|
||||||
|
# Ctrl - X -> Ctrl - S.
|
||||||
|
|
||||||
|
# Things like Alt-; to comment multiple lines at ones is HUGE. Also it
|
||||||
|
# was built by programmers for programmers. So it's a very good tool.
|
||||||
|
|
||||||
|
elif part.endswith("**") and not block[-1][n+2:].startswith('*'):
|
||||||
|
|
||||||
|
# DOUBLE **
|
||||||
|
|
||||||
|
newtree.append([block[0], part[:-2]])
|
||||||
|
|
||||||
|
if block[0] == "text":
|
||||||
|
block[0] = "text_b"
|
||||||
|
else:
|
||||||
|
block[0] = "text"
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
|
||||||
|
elif part.endswith("*") and not block[-1][n+1:].startswith('*'):
|
||||||
|
|
||||||
|
# SINGLE *
|
||||||
|
|
||||||
|
newtree.append([block[0], part[:-1]])
|
||||||
|
|
||||||
|
if block[0] == "text":
|
||||||
|
block[0] = "text_i"
|
||||||
|
else:
|
||||||
|
block[0] = "text"
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
|
||||||
|
|
||||||
|
elif part.endswith("`"):
|
||||||
|
|
||||||
|
# SINGLE `
|
||||||
|
|
||||||
|
newtree.append([block[0], part[:-1]])
|
||||||
|
|
||||||
|
if block[0] == "text":
|
||||||
|
block[0] = "text_c"
|
||||||
|
else:
|
||||||
|
block[0] = "text"
|
||||||
|
|
||||||
|
part = ""
|
||||||
|
|
||||||
|
newtree.append([block[0], part])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tree = newtree
|
||||||
|
|
||||||
|
return(tree)
|
||||||
|
|
||||||
|
def search_convert(s):
|
||||||
|
l = " ./\|[]{}()?!@#$%^&*`~:;'\"=,<>"
|
||||||
|
s = s.lower().replace(" ","-")
|
||||||
|
r = ""
|
||||||
|
for i in s:
|
||||||
|
if i not in l:
|
||||||
|
r = r + i
|
||||||
|
return r
|
||||||
|
|
||||||
|
def draw(outlayer, win, name, x, y, width, height):
|
||||||
|
|
||||||
|
# Now you maybe woundering where is the filname to read from. Well. We are
|
||||||
|
# making it now.
|
||||||
|
|
||||||
|
if "mdfs" not in win.current:
|
||||||
|
win.current["mdfs"] = {}
|
||||||
|
win.current["mdfs"]["failsafe"] = ""
|
||||||
|
|
||||||
|
if name not in win.current["mdfs"]:
|
||||||
|
win.current["mdfs"][name] = ""
|
||||||
|
|
||||||
|
filename = win.current["mdfs"][name]
|
||||||
|
|
||||||
|
# The # sing usually calls for search with in the text.
|
||||||
|
|
||||||
|
if "#" in filename:
|
||||||
|
filename, search = filename.split("#")
|
||||||
|
win.current["mdfs"][name] = filename
|
||||||
|
else:
|
||||||
|
search = ""
|
||||||
|
|
||||||
|
# First we don't want to waste resources to parse the file on each frame
|
||||||
|
# so let's load it ones.
|
||||||
|
|
||||||
|
if "mds" not in win.current:
|
||||||
|
win.current["mds"] = {}
|
||||||
|
|
||||||
|
if filename not in win.current["mds"]:
|
||||||
|
win.current["mds"][filename] = Open(win, filename, name)
|
||||||
|
|
||||||
|
md = win.current["mds"][filename]
|
||||||
|
|
||||||
|
# This peace of code outputs the parsed object into terminal for reading.
|
||||||
|
|
||||||
|
# for i in md:
|
||||||
|
# if type(i) == str:
|
||||||
|
# print("'"+i+"' ,")
|
||||||
|
# else:
|
||||||
|
# print(i, ",")
|
||||||
|
|
||||||
|
|
||||||
|
# Background
|
||||||
|
UI_color.set(outlayer, win, "node_background")
|
||||||
|
UI_elements.roundrect(outlayer, win,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
10)
|
||||||
|
outlayer.fill()
|
||||||
|
|
||||||
|
# The name of the file first. I think it's gonna make sense to make it in
|
||||||
|
# an entry. So people could insert any filename, or link in future.
|
||||||
|
|
||||||
|
try:
|
||||||
|
UI_elements.text(outlayer, win, "markdown_name",
|
||||||
|
x+10,
|
||||||
|
y+5,
|
||||||
|
int(width)-20,
|
||||||
|
40,
|
||||||
|
set_text=filename,
|
||||||
|
fill=False)
|
||||||
|
|
||||||
|
if win.text["markdown_name"]["text"] != filename \
|
||||||
|
and win.textactive != "markdown_name":
|
||||||
|
win.text["markdown_name"]["text"] = filename
|
||||||
|
|
||||||
|
# Let me make it user editable as well. Because I'm a nerd
|
||||||
|
# and I want to see how it handles various problems.
|
||||||
|
|
||||||
|
elif win.text["markdown_name"]["text"] != filename:
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["mdfs"]["failsafe"] = filename
|
||||||
|
win.current["mdfs"][name] = win.text["markdown_name"]["text"]
|
||||||
|
|
||||||
|
UI_elements.roundrect(outlayer, win,
|
||||||
|
x+int(width)-50,
|
||||||
|
y+5,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"))
|
||||||
|
|
||||||
|
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Now let's draw the bastard. We are going to do it the same way as in the
|
||||||
|
# script writer. But rather simplified. For example we are not making an
|
||||||
|
# editor. But only a reader. So we don't need the selection. And we don't
|
||||||
|
# need to calculate every letter preciselly. With something like codes
|
||||||
|
# I can do that every ` object will be drawn in a text entry object. Why
|
||||||
|
# not.
|
||||||
|
|
||||||
|
# I need to make a new Layer because we are going to clip it for the text.
|
||||||
|
|
||||||
|
textsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
|
||||||
|
layer = cairo.Context(textsurface)
|
||||||
|
layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
layer_i = cairo.Context(textsurface)
|
||||||
|
layer_i.select_font_face("Monospace", cairo.FONT_SLANT_ITALIC, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
layer_b = cairo.Context(textsurface)
|
||||||
|
layer_b.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
|
||||||
|
layer_bi = cairo.Context(textsurface)
|
||||||
|
layer_bi.select_font_face("Monospace", cairo.FONT_SLANT_ITALIC, cairo.FONT_WEIGHT_BOLD)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win, 0,50,width, height-50, 10,fill=False)
|
||||||
|
layer.clip()
|
||||||
|
UI_elements.roundrect(layer_b, win, 0,50,width, height-50, 10,fill=False)
|
||||||
|
layer_b.clip()
|
||||||
|
UI_elements.roundrect(layer_bi, win, 0,50,width, height-50, 10,fill=False)
|
||||||
|
layer_bi.clip()
|
||||||
|
UI_elements.roundrect(layer_i, win, 0,50,width, height-50, 10,fill=False)
|
||||||
|
layer_i.clip()
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# HERE WE DRAWING TEXT TO THE SCREEN #
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
if "markdown" not in win.scroll:
|
||||||
|
win.scroll["markdown"] = 0
|
||||||
|
|
||||||
|
current_Y = 70
|
||||||
|
tyleX = 10
|
||||||
|
newX = 10
|
||||||
|
newY = 0
|
||||||
|
|
||||||
|
for block in md:
|
||||||
|
|
||||||
|
# THE # HEADERS
|
||||||
|
|
||||||
|
if type(block[0]) == int:
|
||||||
|
|
||||||
|
current_Y = current_Y + newY + 100
|
||||||
|
|
||||||
|
UI_color.set(layer_b, win, "text_normal")
|
||||||
|
layer_b.set_font_size(30-(block[0]*4))
|
||||||
|
layer_b.move_to(
|
||||||
|
10,
|
||||||
|
current_Y + win.scroll["markdown"]
|
||||||
|
)
|
||||||
|
layer_b.show_text(block[1].replace("\n", "").replace("#", " "))
|
||||||
|
|
||||||
|
current_Y = current_Y + 40
|
||||||
|
|
||||||
|
if search and search in search_convert(block[1].replace("\n", "").replace("#", "")):
|
||||||
|
win.scroll["markdown"] = 0 - current_Y + 140
|
||||||
|
search = ""
|
||||||
|
|
||||||
|
newX = 10
|
||||||
|
newY = 0
|
||||||
|
|
||||||
|
# IMAGES
|
||||||
|
|
||||||
|
# This going to be hard. I have an interesting idea about it.
|
||||||
|
# 1.) Make the images whos links are in the internet loadable.
|
||||||
|
# This will require some clever thinking. Because not all
|
||||||
|
# users want to automatically download images from a source
|
||||||
|
# that they don't trust. I'm hosting most of the images
|
||||||
|
# at the moment on NotABug.org with the project's code.
|
||||||
|
# But. That I trust it. Doesn't mean everybody trust it
|
||||||
|
# or should trust it. So Downloading of images should be
|
||||||
|
# optional. We can make a button to download a given image
|
||||||
|
# and a setting in the settings to download them automatically.
|
||||||
|
#
|
||||||
|
# Now thinking about it. The Update system should use something
|
||||||
|
# similar.
|
||||||
|
#
|
||||||
|
# 2.) Warping of text around the image. This is something original
|
||||||
|
# markdown not really supports. On NotABug the images in the text
|
||||||
|
# look a bit ugly because they stretch the line height.
|
||||||
|
# I propose using a kind of warp around system. Let me demonstrate.
|
||||||
|
|
||||||
|
# ############### This is a sample text about the Image.png. That
|
||||||
|
# # # is going to warp around the image like so.
|
||||||
|
# # Image.png # More text is needed to show the extent of this
|
||||||
|
# # # effect. So I'm going to ramble about something.
|
||||||
|
# # # Hello World! Are you a true hacker? I hope you
|
||||||
|
# ############### are. And not a cracker. Now see what's going to
|
||||||
|
# happen when the image is ended. The next line is written under
|
||||||
|
# the image. Which is a cool look. Now ...
|
||||||
|
|
||||||
|
# I have no idea what to do if the image is going to be rendered in
|
||||||
|
# the middle of the paragraph. Maybe the image in the middle should
|
||||||
|
# act like in a normal implementation. And only at the start as
|
||||||
|
# what I showed you now.
|
||||||
|
|
||||||
|
elif "image" in block[0]:
|
||||||
|
|
||||||
|
|
||||||
|
if newY:
|
||||||
|
current_Y = current_Y + newY + 40
|
||||||
|
tyleX = 10
|
||||||
|
newX = 10
|
||||||
|
newY = 0
|
||||||
|
|
||||||
|
# ICONS
|
||||||
|
|
||||||
|
# Sometimes I link Icons from OldSchool theme to the text. They
|
||||||
|
# look good on a white background in the NotABug.org page.
|
||||||
|
# But. Since they are icons that might have different themes for
|
||||||
|
# the users let's make them theme respecting.
|
||||||
|
|
||||||
|
if "settings/themes/" in block[2] and "/icons/" in block[2]:
|
||||||
|
iconname = block[2][block[2].rfind('/')+1:]
|
||||||
|
block[2] = "settings/themes/"+win.settings["Theme"]+"/icons/"+iconname
|
||||||
|
|
||||||
|
UI_elements. image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/"+iconname,
|
||||||
|
tyleX,
|
||||||
|
current_Y + win.scroll["markdown"]-30)
|
||||||
|
tyleX = tyleX + 40
|
||||||
|
|
||||||
|
# OTHER IMAGES
|
||||||
|
|
||||||
|
# I think the handling of the images loading should be done in the
|
||||||
|
# UI_elements.py file. So I could easy reimplement this feature
|
||||||
|
# else where.
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
UI_elements. image(layer, win, block[2],
|
||||||
|
tyleX,
|
||||||
|
current_Y + win.scroll["markdown"]-15,
|
||||||
|
cell="markdown",offset=[x,y],width=width-40,fit="fit_width")
|
||||||
|
try:
|
||||||
|
imH = win.images["markdown"][block[2]]['image'].get_height()
|
||||||
|
imW = win.images["markdown"][block[2]]['image'].get_width()
|
||||||
|
except:
|
||||||
|
imH = 40
|
||||||
|
imW = 40
|
||||||
|
|
||||||
|
tyleX = tyleX + imW
|
||||||
|
|
||||||
|
newX = imW + 40
|
||||||
|
newY = imH - 20
|
||||||
|
|
||||||
|
# LINKED IMAGES
|
||||||
|
|
||||||
|
if "link" in block[0]:
|
||||||
|
|
||||||
|
# If the image is linked. We are going to separate it in 2 categoies.
|
||||||
|
# If automatic downloading is on. There is no difference. Else. There
|
||||||
|
# will be a difference. Since the image from the Internet going to be
|
||||||
|
# a button to download it. We need to offset the link button. SO.
|
||||||
|
|
||||||
|
def do():
|
||||||
|
if block[2].endswith(".md"):
|
||||||
|
win.current["mdfs"]["failsafe"] = filename
|
||||||
|
win.current["mdfs"][name] = block[3]
|
||||||
|
win.current["current_help_selected"] = ""
|
||||||
|
else:
|
||||||
|
oscalls.Open(block[3])
|
||||||
|
|
||||||
|
try:
|
||||||
|
downloadbutton = win.images["markdown"][block[2]]["image"] == "download_button"
|
||||||
|
except:
|
||||||
|
downloadbutton = False
|
||||||
|
|
||||||
|
|
||||||
|
if not win.settings["auto_download_images"]\
|
||||||
|
and block[2].startswith("http")\
|
||||||
|
and downloadbutton:
|
||||||
|
|
||||||
|
# Here goes the offsetted link.
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win, tyleX,
|
||||||
|
current_Y + win.scroll["markdown"]-15,40,40,10,
|
||||||
|
icon="internet",
|
||||||
|
button=do,
|
||||||
|
offset=[x,y],
|
||||||
|
tip=block[3])
|
||||||
|
|
||||||
|
tyleX = tyleX + 60
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Full on image
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win, tyleX-imW,
|
||||||
|
current_Y + win.scroll["markdown"]-15,imW, imH,10,
|
||||||
|
button=do,
|
||||||
|
offset=[x,y],
|
||||||
|
tip=block[3],
|
||||||
|
fill=False)
|
||||||
|
layer.stroke()
|
||||||
|
|
||||||
|
# TEXT
|
||||||
|
|
||||||
|
elif block[0] in ["text", "text_i", "text_b", "text_ib", "text_c", "link"]:
|
||||||
|
for word in block[1].split(" "):
|
||||||
|
|
||||||
|
if tyleX + len(word)*12+12 > width :
|
||||||
|
tyleX = newX
|
||||||
|
newY = max(0, newY-30)
|
||||||
|
if newY == 0:
|
||||||
|
newX = 10
|
||||||
|
current_Y = current_Y + 30
|
||||||
|
|
||||||
|
# Any type of Text. Whether it's Normal, Bold or Italic gonna
|
||||||
|
# have the same color.
|
||||||
|
|
||||||
|
if "text" in block[0]:
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
UI_color.set(layer_i, win, "text_normal")
|
||||||
|
UI_color.set(layer_b, win, "text_normal")
|
||||||
|
UI_color.set(layer_bi, win, "text_normal")
|
||||||
|
|
||||||
|
# Unless it's a link. Then I have a special color for it in the
|
||||||
|
# theme. I tried reusing pre-existing. Non of them works across
|
||||||
|
# multiple themes.
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
|
||||||
|
# Here I gonna introduce the logic of the links. Because
|
||||||
|
# I'm lazy.
|
||||||
|
|
||||||
|
if "markdown_mouse_link" not in win.current:
|
||||||
|
win.current["markdown_mouse_link"] = ""
|
||||||
|
|
||||||
|
if win.current["mx"] in range(int(x+tyleX-6), int(x+tyleX-6+len(word)*12+12))\
|
||||||
|
and win.current["my"] in range(int(y+current_Y + win.scroll["markdown"]-20),
|
||||||
|
int(y+current_Y + win.scroll["markdown"]+5)):
|
||||||
|
win.current["markdown_mouse_link"] = block[2]
|
||||||
|
|
||||||
|
UI_elements.tooltip(win,block[2])
|
||||||
|
|
||||||
|
# AHh... I'll do a clicker here.
|
||||||
|
if not win.current["LMB"] and win.previous["LMB"]:
|
||||||
|
|
||||||
|
if block[2].endswith(".md"):
|
||||||
|
win.current["mdfs"]["failsafe"] = filename
|
||||||
|
win.current["mdfs"][name] = block[2]
|
||||||
|
win.current["current_help_selected"] = ""
|
||||||
|
elif block[2].startswith("#"):
|
||||||
|
win.current["mdfs"][name] = win.current["mdfs"][name] + block[2]
|
||||||
|
win.current["current_help_selected"] = ""
|
||||||
|
else:
|
||||||
|
oscalls.Open(block[2])
|
||||||
|
|
||||||
|
|
||||||
|
elif win.current["mx"] not in range(win.previous["mx"]-5, win.previous["mx"]+5):
|
||||||
|
win.current["markdown_mouse_link"] = ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# If mouse hovering over a link. Draw a line under the link.
|
||||||
|
|
||||||
|
if win.current["markdown_mouse_link"] == block[2]:
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tyleX-6,
|
||||||
|
current_Y + win.scroll["markdown"],
|
||||||
|
len(word)*12+12,
|
||||||
|
4,
|
||||||
|
2)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_link")
|
||||||
|
|
||||||
|
|
||||||
|
# Italic text
|
||||||
|
|
||||||
|
if "_i" in block[0]:
|
||||||
|
layer_i.set_font_size(20)
|
||||||
|
layer_i.move_to(
|
||||||
|
tyleX,
|
||||||
|
current_Y + win.scroll["markdown"]
|
||||||
|
)
|
||||||
|
layer_i.show_text(word.replace("\n", ""))
|
||||||
|
|
||||||
|
# Bold text
|
||||||
|
|
||||||
|
elif "_b" in block[0]:
|
||||||
|
layer_b.set_font_size(20)
|
||||||
|
layer_b.move_to(
|
||||||
|
tyleX,
|
||||||
|
current_Y + win.scroll["markdown"]
|
||||||
|
)
|
||||||
|
layer_b.show_text(word.replace("\n", ""))
|
||||||
|
|
||||||
|
# Any other text
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
if "_c" in block[0]:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "node_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
tyleX-6,
|
||||||
|
current_Y + win.scroll["markdown"]-20,
|
||||||
|
len(word)*12+12,
|
||||||
|
25,
|
||||||
|
5)
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(
|
||||||
|
tyleX,
|
||||||
|
current_Y + win.scroll["markdown"]
|
||||||
|
)
|
||||||
|
layer.show_text(word.replace("\n", ""))
|
||||||
|
|
||||||
|
# Moving of to the next word.
|
||||||
|
|
||||||
|
if "\n" in word:
|
||||||
|
tyleX = newX
|
||||||
|
newY = max(0, newY-30)
|
||||||
|
if newY == 0:
|
||||||
|
newX = 10
|
||||||
|
current_Y = current_Y + 30
|
||||||
|
else:
|
||||||
|
|
||||||
|
tyleX = tyleX + len(word)*12+12
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Scroll
|
||||||
|
UI_elements.scroll_area(outlayer, win, "markdown",
|
||||||
|
x+0,
|
||||||
|
y+0,
|
||||||
|
width+30,
|
||||||
|
height-0,
|
||||||
|
current_Y,
|
||||||
|
bar=True,
|
||||||
|
mmb=True,
|
||||||
|
bar_always=True)
|
||||||
|
|
||||||
|
|
||||||
|
# Outputting the layer
|
||||||
|
outlayer.set_source_surface(textsurface, x, y)
|
||||||
|
outlayer.paint()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
|
import urllib3
|
||||||
import hashlib
|
import hashlib
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
@ -232,13 +233,71 @@ def hash_file(f):
|
||||||
return "FOLDER"
|
return "FOLDER"
|
||||||
|
|
||||||
def loadimage(layer, win ,path, x, y, width, height, fit, cell=0):
|
def loadimage(layer, win ,path, x, y, width, height, fit, cell=0):
|
||||||
|
|
||||||
|
# Before we load an image we have to know whether the image is local
|
||||||
|
# in the Internet. Markdown files for example can have links to a
|
||||||
|
# picture in the internet. And so if a given Image URL is not local
|
||||||
|
# we have to be able to download it.
|
||||||
|
|
||||||
|
# For reasons we all can relate to. I don't want such downloading to
|
||||||
|
# happen automatically. Unless the user is going to enable auto
|
||||||
|
# download in the settings.
|
||||||
|
|
||||||
|
# Let's set up a setting. I'm doing it here because Images drawn
|
||||||
|
# first. On the main screen. And the setting does not exists in
|
||||||
|
# the earlier settings file from the earlier version.
|
||||||
|
|
||||||
|
if "auto_download_images" not in win.settings:
|
||||||
|
win.settings["auto_download_images"] = False
|
||||||
|
settings.write("auto_download_images", win.settings["auto_download_images"])
|
||||||
|
|
||||||
|
filename = "/tmp/"+path.replace("/","_")
|
||||||
|
tmppath = ""
|
||||||
|
|
||||||
|
if path.startswith("http") and not os.path.exists(filename):
|
||||||
|
|
||||||
|
|
||||||
|
if win.images[cell][path]["image"] != "downloading":
|
||||||
|
|
||||||
|
# If the button is not pressed yet. Then we need to
|
||||||
|
# put a downlod button. Look down where implement
|
||||||
|
# the drawing of the image for the button it self.
|
||||||
|
|
||||||
|
win.images[cell][path]["loading"] = False
|
||||||
|
win.images[cell][path]["image"] = "download_button"
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Now somebody either pressed the button. Or it set to
|
||||||
|
# automatic downloads. Then, let's get the file.
|
||||||
|
|
||||||
|
win.images[cell][path]["image"] = None
|
||||||
|
|
||||||
|
http = urllib3.PoolManager()
|
||||||
|
r = http.request('GET', path, preload_content=False)
|
||||||
|
with open(filename, 'wb') as out:
|
||||||
|
while True:
|
||||||
|
data = r.read(1024)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
out.write(data)
|
||||||
|
|
||||||
|
r.release_conn()
|
||||||
|
|
||||||
|
|
||||||
|
elif path.startswith("http"):
|
||||||
|
tmppath = path
|
||||||
|
path = filename
|
||||||
|
|
||||||
|
|
||||||
|
# Also I don't want downloading to happen here. Since if it's not
|
||||||
|
# downloaded
|
||||||
|
|
||||||
# So multiple types of the image could be loaded. It could be either
|
# So multiple types of the image could be loaded. It could be either
|
||||||
# an image file. Like png or jpeg. Either a video file. Or a blend file
|
# an image file. Like png or jpeg. Either a video file. Or a blend file
|
||||||
# each with it's own loading problems.
|
# each with it's own loading problems.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# While cairo can read pngs directly. It's not the best way of doing it
|
# While cairo can read pngs directly. It's not the best way of doing it
|
||||||
# since it's not capable of reading jpegs and other files. So let's do
|
# since it's not capable of reading jpegs and other files. So let's do
|
||||||
# something about it.
|
# something about it.
|
||||||
|
@ -260,6 +319,7 @@ def loadimage(layer, win ,path, x, y, width, height, fit, cell=0):
|
||||||
try:
|
try:
|
||||||
load1 = GdkPixbuf.Pixbuf.new_from_file(path)
|
load1 = GdkPixbuf.Pixbuf.new_from_file(path)
|
||||||
except:
|
except:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
load1 = GdkPixbuf.Pixbuf.new_from_file("settings/themes/"+win.settings["Theme"]+"/icons/image.png")
|
load1 = GdkPixbuf.Pixbuf.new_from_file("settings/themes/"+win.settings["Theme"]+"/icons/image.png")
|
||||||
except:
|
except:
|
||||||
|
@ -395,7 +455,25 @@ def loadimage(layer, win ,path, x, y, width, height, fit, cell=0):
|
||||||
imagedraw.scale(factor, factor)
|
imagedraw.scale(factor, factor)
|
||||||
dx = (width/2)/factor -(load2.get_width() /2)
|
dx = (width/2)/factor -(load2.get_width() /2)
|
||||||
dy = (height/2)/factor -(load2.get_height()/2)
|
dy = (height/2)/factor -(load2.get_height()/2)
|
||||||
|
|
||||||
|
# Finally I need to implement something but the Crop.
|
||||||
|
# Fit Width I want to use in MarkDowns. Maybe also in the
|
||||||
|
# text of the script. Makes sense.
|
||||||
|
|
||||||
|
elif fit == "fit_width" and load2.get_width() > width:
|
||||||
|
factor = width / load2.get_width()
|
||||||
|
dx = 0
|
||||||
|
dy = 0
|
||||||
|
imagesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(load2.get_height()*factor))
|
||||||
|
imagedraw = cairo.Context(imagesurface)
|
||||||
|
imagedraw.scale(factor, factor)
|
||||||
|
elif fit == "fit_width":
|
||||||
|
dx = 0
|
||||||
|
dy = 0
|
||||||
|
imagesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(load2.get_width()), int(load2.get_height()))
|
||||||
|
imagedraw = cairo.Context(imagesurface)
|
||||||
|
|
||||||
|
|
||||||
# Let's make an ability for theme makers to simply color the standard
|
# Let's make an ability for theme makers to simply color the standard
|
||||||
# icons into any shade.
|
# icons into any shade.
|
||||||
|
|
||||||
|
@ -405,6 +483,8 @@ def loadimage(layer, win ,path, x, y, width, height, fit, cell=0):
|
||||||
imagesurface = load2
|
imagesurface = load2
|
||||||
|
|
||||||
# Saving it into the win.images
|
# Saving it into the win.images
|
||||||
|
if tmppath:
|
||||||
|
path = tmppath
|
||||||
win.images[cell][path]["loading"] = False
|
win.images[cell][path]["loading"] = False
|
||||||
win.images[cell][path]["image"] = imagesurface
|
win.images[cell][path]["image"] = imagesurface
|
||||||
win.images[cell][path]["hash"] = hash_file(path)
|
win.images[cell][path]["hash"] = hash_file(path)
|
||||||
|
@ -426,7 +506,7 @@ def reload_images(win):
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def image(layer, win ,path, x, y, width=0, height=0, fit="crop", cell=0):
|
def image(layer, win ,path, x, y, width=0, height=0, fit="crop", cell=0, offset=[0,0]):
|
||||||
|
|
||||||
# This module will handle drawing images to the layers. It's not that hard
|
# 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
|
# to do in cairo by default. But i'm doing it at every frame. And so it
|
||||||
|
@ -444,7 +524,7 @@ def image(layer, win ,path, x, y, width=0, height=0, fit="crop", cell=0):
|
||||||
win.images[cell] = {}
|
win.images[cell] = {}
|
||||||
|
|
||||||
if int(x) not in range(int(0-width ), int(win.current["w"])) or \
|
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"])) :
|
int(y) not in range(int(0-height-win.current["h"]), int(win.current["h"])) :
|
||||||
return
|
return
|
||||||
|
|
||||||
# If you ran this software you probably noticed that images are loading
|
# If you ran this software you probably noticed that images are loading
|
||||||
|
@ -493,26 +573,28 @@ def image(layer, win ,path, x, y, width=0, height=0, fit="crop", cell=0):
|
||||||
|
|
||||||
#loading it back
|
#loading it back
|
||||||
else:
|
else:
|
||||||
if win.images[cell][path]["image"]:
|
if win.images[cell][path]["image"] and win.images[cell][path]["image"] != "download_button":
|
||||||
imagesurface = win.images[cell][path]["image"]
|
imagesurface = win.images[cell][path]["image"]
|
||||||
|
|
||||||
# Writting the image to the screen
|
# Writting the image to the screen
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
if "icons" in win.color and "settings/themes/" in path:
|
if "icons" in win.color and "settings/themes/" in path:
|
||||||
|
|
||||||
UI_color.set(layer, win, "icons")
|
UI_color.set(layer, win, "icons")
|
||||||
layer.rectangle(x,y,0,0)
|
layer.rectangle(x,y,0,0)
|
||||||
layer.fill()
|
layer.fill()
|
||||||
|
|
||||||
layer.mask_surface(imagesurface, x, y)
|
layer.mask_surface(imagesurface, x, y)
|
||||||
|
|
||||||
UI_color.set(layer, win, "icons")
|
UI_color.set(layer, win, "icons")
|
||||||
layer.fill()
|
layer.fill()
|
||||||
else:
|
else:
|
||||||
layer.set_source_surface(imagesurface, x, y)
|
layer.set_source_surface(imagesurface, x, y)
|
||||||
layer.paint()
|
layer.paint()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# And if testing
|
# And if testing
|
||||||
|
|
||||||
|
@ -520,6 +602,34 @@ def image(layer, win ,path, x, y, width=0, height=0, fit="crop", cell=0):
|
||||||
UI_color.set(layer, win, "testing_image")
|
UI_color.set(layer, win, "testing_image")
|
||||||
layer.rectangle(x,y,imagesurface.get_width(),imagesurface.get_height())
|
layer.rectangle(x,y,imagesurface.get_width(),imagesurface.get_height())
|
||||||
layer.stroke()
|
layer.stroke()
|
||||||
|
|
||||||
|
elif win.images[cell][path]["image"] == "download_button":
|
||||||
|
|
||||||
|
# If the image is online. By default it will not load it unless the
|
||||||
|
# user presses a download button. So here it is.
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.images[cell][path]["image"] = "downloading"
|
||||||
|
loadimage(layer, win ,path, x, y, width, height, fit, cell)
|
||||||
|
win.images[cell][path]["loading"] = True
|
||||||
|
|
||||||
|
# Some link image will be automatically clicked. This
|
||||||
|
# fixes the problem.
|
||||||
|
win.current["LMB"] = False
|
||||||
|
win.previous["LMB"] = False
|
||||||
|
|
||||||
|
|
||||||
|
if win.settings["auto_download_images"]:
|
||||||
|
t = threading.Thread(target=do)
|
||||||
|
t.start()
|
||||||
|
else:
|
||||||
|
|
||||||
|
roundrect(layer, win, x,y,40,40,10,
|
||||||
|
icon="image_link",
|
||||||
|
button=do,
|
||||||
|
offset=offset,
|
||||||
|
tip=path)
|
||||||
|
|
||||||
|
|
||||||
def tooltip(win, text):
|
def tooltip(win, text):
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ from project_manager import pm_project
|
||||||
from UI import UI_elements
|
from UI import UI_elements
|
||||||
from UI import UI_color
|
from UI import UI_color
|
||||||
from UI import UI_math
|
from UI import UI_math
|
||||||
|
from UI import UI_Markdown
|
||||||
|
|
||||||
# Studio
|
# Studio
|
||||||
from studio import studio_dialogs
|
from studio import studio_dialogs
|
||||||
|
@ -62,7 +63,7 @@ def layer(win, call):
|
||||||
|
|
||||||
UI_color.set(layer, win, "node_background")
|
UI_color.set(layer, win, "node_background")
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
win.current["w"]/2-250,
|
100,
|
||||||
100,
|
100,
|
||||||
500,
|
500,
|
||||||
win.current["h"]-200,
|
win.current["h"]-200,
|
||||||
|
@ -70,13 +71,15 @@ def layer(win, call):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Exit button
|
# Exit button
|
||||||
def do():
|
def do():
|
||||||
win.current["calls"][call]["var"] = False
|
win.current["calls"][call]["var"] = False
|
||||||
|
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
win.current["w"]/2-20,
|
560,
|
||||||
win.current["h"]-140,
|
win.current["h"]-140,
|
||||||
40,
|
40,
|
||||||
40,
|
40,
|
||||||
|
@ -86,7 +89,7 @@ def layer(win, call):
|
||||||
tip=talk.text("cancel"))
|
tip=talk.text("cancel"))
|
||||||
|
|
||||||
|
|
||||||
x = win.current["w"]/2-250 + 10
|
x = 110
|
||||||
y = 170
|
y = 170
|
||||||
width = 500 - 20
|
width = 500 - 20
|
||||||
height = win.current["h"]-270
|
height = win.current["h"]-270
|
||||||
|
@ -106,6 +109,17 @@ def layer(win, call):
|
||||||
width/2-50,
|
width/2-50,
|
||||||
40)
|
40)
|
||||||
|
|
||||||
|
### MARKDOWN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UI_Markdown.draw(layer, win, "help_markdown",
|
||||||
|
700,
|
||||||
|
100,
|
||||||
|
win.current["w"]-800,
|
||||||
|
win.current["h"]-200)
|
||||||
|
|
||||||
|
|
||||||
# Clip
|
# Clip
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
|
@ -142,11 +156,20 @@ def layer(win, call):
|
||||||
# create a little dictionary
|
# create a little dictionary
|
||||||
|
|
||||||
documentations = {
|
documentations = {
|
||||||
|
talk.text("readme"):[
|
||||||
|
["Markdown", "README.md"],
|
||||||
|
["scene", "https://notabug.org/jyamihud/VCStudio/src/master/README.md"]
|
||||||
|
],
|
||||||
|
talk.text("license"):[
|
||||||
|
["Markdown", "LICENSE.md"],
|
||||||
|
],
|
||||||
talk.text("documentation_installation"):[
|
talk.text("documentation_installation"):[
|
||||||
["scene", "https://notabug.org/jyamihud/VCStudio/wiki/Documenation+%7C+Installation+%7C+Version+20.128"]
|
["scene", "https://notabug.org/jyamihud/VCStudio/wiki/Documenation+%7C+Installation+%7C+Version+20.128"],
|
||||||
|
["video", "https://open.lbry.com/@blender-organizer:5/rnd0001-4061:1?r=7YADjAZEbHJg8n4qV5rAuBh5Hca7cZQK"]
|
||||||
],
|
],
|
||||||
talk.text("documentation_project_manager"):[
|
talk.text("documentation_project_manager"):[
|
||||||
["scene", "https://notabug.org/jyamihud/VCStudio/wiki/Documenation+%7C+Project+Manager+%7C+Version+20.128"]
|
["scene", "https://notabug.org/jyamihud/VCStudio/wiki/Documenation+%7C+Project+Manager+%7C+Version+20.128"],
|
||||||
|
["video", "https://open.lbry.com/@blender-organizer:5/Victorious-Children-Studio-Organizer-%28-VCStudio-%29---Project-Manager-Tutorial---Creating-Projects---Scanning-the-OS---Settings:7?r=7YADjAZEbHJg8n4qV5rAuBh5Hca7cZQK"]
|
||||||
],
|
],
|
||||||
talk.text("documentation_story_editor"):[
|
talk.text("documentation_story_editor"):[
|
||||||
["scene", "https://notabug.org/jyamihud/VCStudio/wiki/Documenation+%7C+Story+Editor+%7C+Version+20.128+"]
|
["scene", "https://notabug.org/jyamihud/VCStudio/wiki/Documenation+%7C+Story+Editor+%7C+Version+20.128+"]
|
||||||
|
@ -186,9 +209,9 @@ def layer(win, call):
|
||||||
# Let's make the search work.
|
# Let's make the search work.
|
||||||
|
|
||||||
# First I want it to automatically select the stuff with the right name
|
# First I want it to automatically select the stuff with the right name
|
||||||
if win.text["in_help"]["text"] != win.current["current_help_selected"]\
|
if win.text["in_help"]["text"].lower() == name.lower():
|
||||||
and win.text["in_help"]["text"].lower() == name.lower():
|
|
||||||
win.current["current_help_selected"] = name
|
win.current["current_help_selected"] = name
|
||||||
|
win.text["in_help"]["text"] = ""
|
||||||
|
|
||||||
# Now let's ignore all those not in the search
|
# Now let's ignore all those not in the search
|
||||||
if win.text["in_help"]["text"] and win.text["in_help"]["text"].lower() not in name.lower():
|
if win.text["in_help"]["text"] and win.text["in_help"]["text"].lower() not in name.lower():
|
||||||
|
@ -242,6 +265,23 @@ def layer(win, call):
|
||||||
# Let's not list all the entries.
|
# Let's not list all the entries.
|
||||||
|
|
||||||
for entry in doc:
|
for entry in doc:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if entry[0] == "Markdown":
|
||||||
|
|
||||||
|
# Sometimes a language File is provided. let's
|
||||||
|
# look for it.
|
||||||
|
|
||||||
|
l = win.settings["Language"]
|
||||||
|
|
||||||
|
if os.path.exists(os.getcwd()+"/"+entry[1][:-3]+"_"+l+".md"):
|
||||||
|
entry[1] = entry[1][:-3]+"_"+l+".md"
|
||||||
|
|
||||||
|
win.current["mdfs"]["help_markdown"] = entry[1]
|
||||||
|
#win.current["current_help_selected"] = ""
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
# Launch button
|
# Launch button
|
||||||
def do():
|
def do():
|
||||||
|
@ -268,7 +308,56 @@ def layer(win, call):
|
||||||
else:
|
else:
|
||||||
|
|
||||||
current_Y = current_Y + 50
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
|
|
||||||
|
# Call
|
||||||
|
def do():
|
||||||
|
os.system("xdg-open https://meet.jit.si/VCStudioDevelopmentConference")
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x,
|
||||||
|
y+current_Y + win.scroll["help"],
|
||||||
|
width,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="call",
|
||||||
|
tip=talk.text("contact_us_tip"))
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(x+50,
|
||||||
|
y+current_Y + win.scroll["help"]+25)
|
||||||
|
layer.show_text(talk.text("contact_us_now"))
|
||||||
|
|
||||||
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
|
# Report Bug Button
|
||||||
|
def do():
|
||||||
|
os.system("xdg-open https://notabug.org/jyamihud/VCStudio/issues/new")
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x,
|
||||||
|
y+current_Y + win.scroll["help"],
|
||||||
|
width,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="bug",
|
||||||
|
tip=talk.text("report_bug_tip"))
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(x+50,
|
||||||
|
y+current_Y + win.scroll["help"]+25)
|
||||||
|
layer.show_text(talk.text("report_bug_now"))
|
||||||
|
|
||||||
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
|
|
||||||
UI_elements.scroll_area(layer, win, "help",
|
UI_elements.scroll_area(layer, win, "help",
|
||||||
|
|
Loading…
Reference in a new issue