diff --git a/Main Project/battleGUI.py b/Main Project/battleGUI.py index 113953e..1d57a8e 100644 --- a/Main Project/battleGUI.py +++ b/Main Project/battleGUI.py @@ -36,8 +36,7 @@ def battleGUI(player): window = Tk() window.geometry('600x600') window.configure(bg='#FFFFFF') - canvas = Canvas(window, bg='#FFFFFF', height=600, width=600, - bd=0, highlightthickness=0, relief='ridge') + canvas = Canvas(window, bg='#FFFFFF', height=600, width=600,bd=0, highlightthickness=0, relief='ridge') canvas.place(x=0, y=0) # Background @@ -45,8 +44,7 @@ def battleGUI(player): canvas.create_image(300, 300, image=background) # Render pokemon images - playerPokemonImg = flipImg(imgCreator( - playerPokemons[playerPokeCount-1].name, True)) + playerPokemonImg = flipImg(imgCreator(playerPokemons[playerPokeCount-1].name, True)) playerPokemonId = canvas.create_image(107, 107, image=playerPokemonImg) compPokemonImg = imgCreator(compPokemons[compPokeCount-1].name) compPokemonId = canvas.create_image(492, 107, image=compPokemonImg) @@ -58,10 +56,8 @@ def battleGUI(player): fill='#000', font=('Inter', -28)) # HP variables hp = { - 'player': canvas.create_text(228, 61, anchor='nw', text='100/100', - fill='#040243', font=('Inter', -30)), - 'comp': canvas.create_text(228, 153, anchor='nw', text='100/100', - fill='#040243', font=('Inter', -30)) + 'player': canvas.create_text(228, 61, anchor='nw', text='100/100', fill='#040243', font=('Inter', -30)), + 'comp': canvas.create_text(228, 153, anchor='nw', text='100/100',fill='#040243', font=('Inter', -30)) } # Ability Buttons @@ -80,9 +76,7 @@ def battleGUI(player): # History box canvas.create_rectangle(0, 394, 600, 600, fill='#D9D9D9', outline='') - history = [ - canvas.create_text(1, 372.5 + 22.5 * i, anchor='nw', text=f'History line {i}', - fill='#000000', font=('Inter', -22))for i in range(1, 10) + history = [canvas.create_text(1, 372.5 + 22.5 * i, anchor='nw', text=f'History line {i}', fill='#000000', font=('Inter', -22))for i in range(1, 10) ] window.resizable(False, False) @@ -102,10 +96,8 @@ def useAbility(no: int): # Player damage algorithm dmgDealt = int(playerAbilities[playerPokeCount-1][no-1]['power']) + randint(0, int(playerPokemons[playerPokeCount-1].stats[1])*int( playerPokemons[playerPokeCount-1].stats[3])) if random() < int(playerAbilities[playerPokeCount-1][no-1]['accuracy'])/100 else 0 - info( - f"(Player) {playerPokemons[playerPokeCount-1].name}'s {playerAbilities[playerPokeCount-1][no-1]['name']} dealt {dmgDealt} dmg!") - historyUpdate( - f"(Player) {playerPokemons[playerPokeCount-1].name}'s {playerAbilities[playerPokeCount-1][no-1]['name']} dealt {dmgDealt} dmg!") + info(f"(Player) {playerPokemons[playerPokeCount-1].name}'s {playerAbilities[playerPokeCount-1][no-1]['name']} dealt {dmgDealt} dmg!") + historyUpdate(f"(Player) {playerPokemons[playerPokeCount-1].name}'s {playerAbilities[playerPokeCount-1][no-1]['name']} dealt {dmgDealt} dmg!") compCurrHp = int(canvas.itemcget( hp['comp'], 'text').split('/')[0])-dmgDealt # If computer hp goes below 0 @@ -116,8 +108,7 @@ def useAbility(no: int): f'(Comp) {compPokemons[compPokeCount-1].name} has fainted.') if compPokeCount >= 3: gameOver = True - canvas.itemconfig( - hp['comp'], text=f"0/{int(canvas.itemcget(hp['comp'], 'text').split('/')[1])}") + canvas.itemconfig(hp['comp'], text=f"0/{int(canvas.itemcget(hp['comp'], 'text').split('/')[1])}") info('(Comp) Computer has no usable pokemon. Player wins!') return historyUpdate('(Comp) Computer has no usable pokemon. Player wins!') compPokeCount += 1 # Increase counter by 1 @@ -133,8 +124,7 @@ def useAbility(no: int): if random() < int(compAbilities[compPokeCount-1][randomAbility-1]['accuracy'])/100: dmgDealt = int(compAbilities[compPokeCount-1][randomAbility-1]['power']) + randint(0, int(compPokemons[compPokeCount-1].stats[1])*int( compPokemons[compPokeCount-1].stats[3])) - else: - dmgDealt = 0 + else:dmgDealt = 0 info(f"(Comp) {compPokemons[compPokeCount-1].name}'s {compAbilities[compPokeCount-1][randomAbility-1]['name']} dealt {dmgDealt} dmg!") historyUpdate( f"(Comp) {compPokemons[compPokeCount-1].name}'s {compAbilities[compPokeCount-1][randomAbility-1]['name']} dealt {dmgDealt} dmg!") @@ -148,8 +138,7 @@ def useAbility(no: int): f'(Player) {playerPokemons[playerPokeCount-1].name} has fainted.') if playerPokeCount >= 3: gameOver = True - canvas.itemconfig( - hp['player'], text=f"0/{int(canvas.itemcget(hp['player'], 'text').split('/')[1])}") + canvas.itemconfig(hp['player'], text=f"0/{int(canvas.itemcget(hp['player'], 'text').split('/')[1])}") info('(Player) Player has no usable pokemon. Computer wins!') return historyUpdate('(Player) Player has no usable pokemon. Computer wins!') playerPokeCount += 1 # Increase counter by 1 @@ -169,14 +158,12 @@ def initPokemon(no: int, trainer: str): # sourcery skip: remove-pass-elif, swit # Set current hp to max hp playerCurrHp = int(playerPokemons[no-1].stats[0])*100 # Update hp text - canvas.itemconfig( - hp['player'], text=f'{playerCurrHp}/{playerCurrHp}') + canvas.itemconfig(hp['player'], text=f'{playerCurrHp}/{playerCurrHp}') canvas.update() elif trainer == 'comp': compCurrHp = int(compPokemons[no-1].stats[0])*100 - canvas.itemconfig( - hp['comp'], text=f'{compCurrHp}/{compCurrHp}') + canvas.itemconfig(hp['comp'], text=f'{compCurrHp}/{compCurrHp}') canvas.update() diff --git a/Main Project/index.py b/Main Project/index.py index a150c29..a607808 100644 --- a/Main Project/index.py +++ b/Main Project/index.py @@ -55,8 +55,5 @@ logging.info(f'Pokemon Trainer Name: {playerName}') startGUI(playerName, time(), pokemons) player=getPlayer() -# player = Player('John Doe') -# player.pokemons = [pokemons[1], pokemons[2], pokemons[3]] -logging.info( - f'Player {player.name} has chosen {player.pokemons[0].name}, {player.pokemons[1].name}, {player.pokemons[2].name} as their pokemons.') +logging.info(f'Player {player.name} has chosen {player.pokemons[0].name}, {player.pokemons[1].name}, {player.pokemons[2].name} as their pokemons.') battleGUI(player) \ No newline at end of file diff --git a/Main Project/info.txt b/Main Project/info.txt deleted file mode 100644 index cb04c6b..0000000 --- a/Main Project/info.txt +++ /dev/null @@ -1,24 +0,0 @@ -Pick 3 characters -Player's characters from top down -AI chooses player's characters, uses random position. - -Enemy HP reduced by calc dmg -Own xp increased by calc dmg -Enemy xp increased by def pt -If dmg calc >10, xp gained = 120% -If dmg calc <=0, xp gained = 150% -Character evo at 100, add 1 for every stat if unable to -Remove char if hp <=0 -Allow player to select which chars attack which enemy char -AI randomly picks player char from AI char top down - -Dmg Calc: Attacker Atk + (Attacker Special Atk Range) - Enemy Def - (Enemy Special Def Range) -Exp calculation: Dmg Dealt -Extra exp is given if the enemy has fainted: -Level calculation is taken from the 'fluctuating' evolution version. The source can be found here: (https://bulbapedia.bulbagarden.net/wiki/Experience) -Level calculation: -Before level 15: (n**3 * (((n+1)/3)+24))/50 -Level 15-35: (n**3 * (n+14))/50 -Level 36-100: (n**3 * ((n*2)+32))/50 -Pokemon evolves every 20 levels till max evolution (20,40,60) -If pokemon is unable to evolve due to max evolution, add 1 to every stat \ No newline at end of file diff --git a/Tkinter Designer/gui/gui.py b/Tkinter Designer/gui/gui.py index a803035..db129ed 100644 --- a/Tkinter Designer/gui/gui.py +++ b/Tkinter Designer/gui/gui.py @@ -1,183 +1,76 @@ -import webbrowser -import re -import sys -import os -import tkinter as tk -import tkinter.messagebox as tk1 -import tkinter.filedialog -from pathlib import Path - -# Add tkdesigner to path -sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) -try: - from tkdesigner.designer import Designer -except ModuleNotFoundError: - raise RuntimeError("Couldn't add tkdesigner to the PATH.") - - -# Path to asset files for this GUI window. -ASSETS_PATH = Path(__file__).resolve().parent / "assets" - -# Required in order to add data files to Windows executable -path = getattr(sys, '_MEIPASS', os.getcwd()) +import re,sys,os,tkinter as tk,tkinter.messagebox as tk1,tkinter.filedialog;from pathlib import Path +sys.path.insert(0,str(Path(__file__).resolve().parent.parent)), +try:from tkdesigner.designer import Designer +except ModuleNotFoundError:raise RuntimeError('Couldn\'t add tkdesigner to the PATH.') +ASSETS_PATH=Path(__file__).resolve().parent/'assets' +path=getattr(sys,'_MEIPASS',os.getcwd()) os.chdir(path) - -output_path = "" - - +output_path='' def btn_clicked(): - token = token_entry.get() - URL = URL_entry.get() - output_path = path_entry.get() - output_path = output_path.strip() - + token=token_entry.get() + URL=URL_entry.get() + output_path=path_entry.get() + output_path=output_path.strip() if not token: - tk.messagebox.showerror( - title="Empty Fields!", message="Please enter Token.") + tk.messagebox.showerror(title='Empty Fields!',message='Please enter Token.') return if not URL: - tk.messagebox.showerror( - title="Empty Fields!", message="Please enter URL.") + tk.messagebox.showerror(title='Empty Fields!',message='Please enter URL.') return if not output_path: - tk.messagebox.showerror( - title="Invalid Path!", message="Enter a valid output path.") + tk.messagebox.showerror( title='Invalid Path!',message='Enter a valid output path.') return - - match = re.search( - r'https://www.figma.com/file/([0-9A-Za-z]+)', URL.strip()) + match=re.search(r'https://www.figma.com/file/([0-9A-Za-z]+)',URL.strip()) if match is None: - tk.messagebox.showerror( - "Invalid URL!", "Please enter a valid file URL.") + tk.messagebox.showerror('Invalid URL!','Please enter a valid file URL.') return - - file_key = match.group(1).strip() - token = token.strip() - output = Path(output_path + "/build").expanduser().resolve() - - if output.exists() and not output.is_dir(): - tk1.showerror( - "Exists!", - f"{output} already exists and is not a directory.\n" - "Enter a valid output directory.") - elif output.exists() and output.is_dir() and tuple(output.glob('*')): - response = tk1.askyesno( - "Continue?", - f"Directory {output} is not empty.\n" - "Do you want to continue and overwrite?") - if not response: - return - - designer = Designer(token, file_key, output) - designer.design() - - tk.messagebox.showinfo( - "Success!", f"Project successfully generated at {output}.") - - + file_key=match[1].strip() + token=token.strip() + output=Path(output_path+'/build').expanduser().resolve() + if output.exists() and not output.is_dir():tk1.showerror(f'Exists! {output} already exists and is not a directory.\nEnter a valid output directory.') + elif output.exists()and output.is_dir()and tuple(output.glob('*')): + if not tk1.askyesno(f'Continue? Directory {output} is not empty.\nDo you want to continue and overwrite?'): return + Designer(token,file_key,output).design() + tk.messagebox.showinfo('Success!',f'Project successfully generated at {output}.') def select_path(): global output_path - - output_path = tk.filedialog.askdirectory() - path_entry.delete(0, tk.END) - path_entry.insert(0, output_path) - - -def make_label(master, x, y, h, w, *args, **kwargs): - f = tk.Frame(master, height=h, width=w) - f.pack_propagate(0) # don't shrink - f.place(x=x, y=y) - - label = tk.Label(f, *args, **kwargs) - label.pack(fill=tk.BOTH, expand=1) - - return label - - -window = tk.Tk() -logo = tk.PhotoImage(file=ASSETS_PATH / "iconbitmap.gif") -window.call('wm', 'iconphoto', window._w, logo) -window.title("Tkinter Designer") - -window.geometry("862x519") -window.configure(bg="#3A7FF6") -canvas = tk.Canvas( - window, bg="#3A7FF6", height=519, width=862, - bd=0, highlightthickness=0, relief="ridge") -canvas.place(x=0, y=0) -canvas.create_rectangle(431, 0, 431 + 431, 0 + 519, fill="#FCFCFC", outline="") -canvas.create_rectangle(40, 160, 40 + 60, 160 + 5, fill="#FCFCFC", outline="") - -text_box_bg = tk.PhotoImage(file=ASSETS_PATH / "TextBox_Bg.png") -token_entry_img = canvas.create_image(650.5, 167.5, image=text_box_bg) -URL_entry_img = canvas.create_image(650.5, 248.5, image=text_box_bg) -filePath_entry_img = canvas.create_image(650.5, 329.5, image=text_box_bg) - -token_entry = tk.Entry(bd=0, bg="#F6F7F9",fg="#000716", highlightthickness=0) -token_entry.place(x=490.0, y=137+25, width=321.0, height=35) + output_path=tk.filedialog.askdirectory() + path_entry.delete(0,tk.END) + path_entry.insert(0,output_path) +def make_label(master,x,y,h,w,*args,**kwargs): + f=tk.Frame(master,height=h,width=w) + f.pack_propagate(0) + f.place(x=x,y=y) + return tk.Label(f,*args,**kwargs).pack(fill=tk.BOTH,expand=1) +window=tk.Tk() +logo=tk.PhotoImage(file=ASSETS_PATH/'iconbitmap.gif') +window.call('wm','iconphoto',window._w,logo) +window.title('Tkinter Designer') +window.geometry('862x519') +window.configure(bg='#3A7FF6') +canvas=tk.Canvas(window,bg='#3A7FF6',height=519,width=862,bd=0,highlightthickness=0,relief='ridge') +canvas.place(x=0,y=0) +canvas.create_rectangle(431,0,862,519,fill='#FCFCFC',outline='') +canvas.create_rectangle(40,160,100,160 + 5,fill='#FCFCFC',outline='') +tk.PhotoImage(file=ASSETS_PATH/'TextBox_Bg.png') +canvas.create_image(650.5,167.5,image=text_box_bg) +canvas.create_image(650.5,248.5,image=text_box_bg) +canvas.create_image(650.5,329.5,image=text_box_bg) +token_entry=tk.Entry(bd=0,bg='#F6F7F9',fg='#000716',highlightthickness=0) +token_entry.place(x=490.0,y=137+25,width=321.0,height=35) token_entry.focus() - -URL_entry = tk.Entry(bd=0, bg="#F6F7F9", fg="#000716", highlightthickness=0) -URL_entry.place(x=490.0, y=218+25, width=321.0, height=35) - -path_entry = tk.Entry(bd=0, bg="#F6F7F9", fg="#000716", highlightthickness=0) -path_entry.place(x=490.0, y=299+25, width=321.0, height=35) - -path_picker_img = tk.PhotoImage(file = ASSETS_PATH / "path_picker.png") -path_picker_button = tk.Button( - image = path_picker_img, - text = '', - compound = 'center', - fg = 'white', - borderwidth = 0, - highlightthickness = 0, - command = select_path, - relief = 'flat') - -path_picker_button.place( - x = 783, y = 319, - width = 24, - height = 22) - -canvas.create_text( - 490.0, 156.0, text="Token ID", fill="#515486", - font=("Arial-BoldMT", int(13.0)), anchor="w") -canvas.create_text( - 490.0, 234.5, text="File URL", fill="#515486", - font=("Arial-BoldMT", int(13.0)), anchor="w") -canvas.create_text( - 490.0, 315.5, text="Output Path", - fill="#515486", font=("Arial-BoldMT", int(13.0)), anchor="w") -canvas.create_text( - 646.5, 428.5, text="Generate", - fill="#FFFFFF", font=("Arial-BoldMT", int(13.0))) -canvas.create_text( - 573.5, 88.0, text="Enter the details.", - fill="#515486", font=("Arial-BoldMT", int(22.0))) - -title = tk.Label( - text="Welcome to Tkinter Designer", bg="#3A7FF6", - fg="white", font=("Arial-BoldMT", int(20.0))) -title.place(x=27.0, y=120.0) - -info_text = tk.Label( - text="Tkinter Designer uses the Figma API\n" - "to analyse a design file, then creates\n" - "the respective code and files needed\n" - "for your GUI.\n\n" - - "Even this GUI was created\n" - "using Tkinter Designer.", - bg="#3A7FF6", fg="white", justify="left", - font=("Georgia", int(16.0))) - -info_text.place(x=27.0, y=200.0) - -generate_btn_img = tk.PhotoImage(file=ASSETS_PATH / "generate.png") -generate_btn = tk.Button( - image=generate_btn_img, borderwidth=0, highlightthickness=0, - command=btn_clicked, relief="flat") -generate_btn.place(x=557, y=401, width=180, height=55) - -window.resizable(False, False) +tk.Entry(bd=0,bg='#F6F7F9',fg='#000716',highlightthickness=0).place(x=490.0,y=218+25,width=321.0,height=35) +tk.Entry(bd=0,bg='#F6F7F9',fg='#000716',highlightthickness=0).place(x=490.0,y=299+25,width=321.0,height=35) +path_picker_img=tk.PhotoImage(file=ASSETS_PATH / 'path_picker.png') +tk.Button(image=path_picker_img,text='',compound='center',fg='white',borderwidth=0,highlightthickness=0,command=select_path,relief='flat').place(x=783,y=319,width=24,height=22) +canvas.create_text(490.0,156.0,text='Token ID',fill='#515486',font=('Arial-BoldMT',int(13.0)),anchor='w') +canvas.create_text(490.0,234.5,text='File URL',fill='#515486',font=('Arial-BoldMT',int(13.0)),anchor='w') +canvas.create_text(490.0,315.5,text='Output Path',fill='#515486',font=('Arial-BoldMT',int(13.0)),anchor='w') +canvas.create_text(646.5,428.5,text='Generate',fill='#FFFFFF',font=('Arial-BoldMT',int(13.0))) +canvas.create_text(573.5,88.0,text='Enter the details.',fill='#515486',font=('Arial-BoldMT',int(22.0))) +tk.Label(text='Welcome to Tkinter Designer',bg='#3A7FF6',fg='white',font=('Arial-BoldMT',int(20.0))).place(x=27.0,y=120.0) +tk.Label(text='Tkinter Designer uses the Figma API\nto analyse a design file,then creates\nthe respective code and files needed\nfor your GUI.\n\nEven this GUI was created\nusing Tkinter Designer.',bg='#3A7FF6',fg='white',justify='left',font=('Georgia',int(16.0))).place(x=27.0,y=200.0) +generate_btn_img=tk.PhotoImage(file=ASSETS_PATH / 'generate.png') +tk.Button(image=generate_btn_img,borderwidth=0,highlightthickness=0,command=btn_clicked,relief='flat').place(x=557,y=401,width=180,height=55) +window.resizable(False,False) window.mainloop() diff --git a/Tkinter Designer/tkdesigner/cli.py b/Tkinter Designer/tkdesigner/cli.py index 78ddf81..5429450 100644 --- a/Tkinter Designer/tkdesigner/cli.py +++ b/Tkinter Designer/tkdesigner/cli.py @@ -1,76 +1,31 @@ -""" -TKinter Designer command-line interface. -""" - +'''Tkinter Designer command-line interface.''' from tkdesigner.designer import Designer - -import re -import os -import logging -import argparse - +import re,os,logging,argparse from pathlib import Path - - -if int(os.getenv("TKDESIGNER_VERBOSE", 0)) == 1: - log_level = logging.INFO -else: - log_level = logging.WARN - +if int(os.getenv('TKDESIGNER_VERBOSE',0))==1:log_level=logging.INFO +else:log_level=logging.WARN logging.basicConfig(level=log_level) - - def main(): - # TODO: Add support for `--force`. Be careful while deleting files. - parser = argparse.ArgumentParser( - description="Generate TKinter GUI code from Figma design.") - - parser.add_argument( - "-o", "--output", type=str, default=".", - help=( - "Folder to output code and image assets to. " - "Defaults to current working directory.")) - parser.add_argument( - "-f", "--force", action="store_true", - help=( - "If this flag is passed in, the output directory given " - "will be overwritten if it exists.")) - - parser.add_argument( - "file_url", type=str, help="File url of the Figma design.") - parser.add_argument("token", type=str, help="Figma token.") - - args = parser.parse_args() - + parser=argparse.ArgumentParser(description='Generate Tkinter GUI code from Figma design.') + parser.add_argument('-o','--output',type=str,default='.',help=('Folder to output code and image assets to. Defaults to current working directory.')) + parser.add_argument('-f','--force',action='store_true',help=('If this flag is passed in,the output directory given will be overwritten if it exists.')) + parser.add_argument('file_url',type=str,help='File url of the Figma design.') + parser.add_argument('token',type=str,help='Figma token.') + args=parser.parse_args() logging.basicConfig() - logging.info(f"args: {args}") - - match = re.search( - r'https://www.figma.com/file/([0-9A-Za-z]+)', args.file_url) - if match is None: - raise ValueError("Invalid file URL.") - - file_key = match.group(1).strip() - token = args.token.strip() - output_path = Path(args.output.strip()).expanduser().resolve() / "build" - - if output_path.exists() and not output_path.is_dir(): - raise RuntimeError( - f"`{output_path}` already exists and is not a directory.\n" - "Hints: Input a different output directory " - "or remove that existing file.") + logging.info(f'args: {args}') + match=re.search(r'https://www.figma.com/file/([0-9A-Za-z]+)',args.file_url) + if match is None:raise ValueError('Invalid file URL.') + file_key=match[1].strip() + token=args.token.strip() + output_path=Path(args.output.strip()).expanduser().resolve() / 'build' + if output_path.exists() and not output_path.is_dir():raise RuntimeError(f'`{output_path}` already exists and is not a directory.\nHints: Input a different output directory or remove that existing file.') elif output_path.exists() and output_path.is_dir(): - if tuple(output_path.glob('*')) and not args.force: - print(f"Directory `{output_path}` already exists.") - response = input("Do you want to continue and overwrite? [N/y] ") - if response.lower().strip() != "y": - print("Aborting!") + if tuple(output_path.glob('*'))and not args.force: + print(f'Directory `{output_path}` already exists.') + if input('Do you want to continue and overwrite? [Y/N] ').lower().strip() != 'y': + print('Aborting!') exit(-1) - - designer = Designer(token, file_key, output_path) - designer.design() - print(f"\nProject successfully generated at {output_path}.\n") - - -if __name__ == "__main__": - main() + Designer(token,file_key,output_path).design() + print(f'\nProject successfully generated at {output_path}.\n') +if __name__=='__main__':main() \ No newline at end of file diff --git a/Tkinter Designer/tkdesigner/conftest.py b/Tkinter Designer/tkdesigner/conftest.py deleted file mode 100644 index e69de29..0000000 diff --git a/Tkinter Designer/tkdesigner/constants.py b/Tkinter Designer/tkdesigner/constants.py index 3db5410..86552f6 100644 --- a/Tkinter Designer/tkdesigner/constants.py +++ b/Tkinter Designer/tkdesigner/constants.py @@ -1,2 +1,2 @@ # Path to assets directory (i.e. images) relative to the output directory. -ASSETS_PATH = "./assets" +ASSETS_PATH="./assets" diff --git a/Tkinter Designer/tkdesigner/designer.py b/Tkinter Designer/tkdesigner/designer.py index d8a8236..5883dce 100644 --- a/Tkinter Designer/tkdesigner/designer.py +++ b/Tkinter Designer/tkdesigner/designer.py @@ -1,37 +1,20 @@ -import tkdesigner.figma.endpoints as endpoints -from tkdesigner.figma.frame import Frame - -from tkdesigner.template import TEMPLATE - -from pathlib import Path - +import tkdesigner.figma.endpoints as endpoints;from tkdesigner.figma.frame import Frame;from tkdesigner.template import TEMPLATE;from pathlib import Path class Designer: - def __init__(self, token, file_key, output_path: Path): - self.output_path = output_path - self.figma_file = endpoints.Files(token, file_key) - self.file_data = self.figma_file.get_file() - self.frameCounter = 0 - + def __init__(self,token,file_key,output_path: Path): + self.output_path=output_path + self.figma_file=endpoints.Files(token,file_key) + self.file_data=self.figma_file.get_file() + self.frameCounter=0 def to_code(self) -> str: - """Return main code. - """ - frames = []; - for f in self.file_data["document"]["children"][0]["children"]: - try: - frame = Frame(f, self.figma_file, self.output_path, self.frameCounter) - except Exception: - raise Exception("Frame not found in figma file or is empty") + '''Return main code.''' + frames=[]; + for f in self.file_data['document']['children'][0]['children']: + try:frame=Frame(f,self.figma_file,self.output_path,self.frameCounter) + except Exception:raise Exception('Frame not found in figma file or is empty') frames.append(frame.to_code(TEMPLATE)) - self.frameCounter += 1 + self.frameCounter+=1 return frames - - def design(self): - """Write code and assets to the specified directories. - """ - code = self.to_code() - for index in range(len(code)): - if (index == 0): - self.output_path.joinpath(f"gui.py").write_text(code[index], encoding='UTF-8') - else: - self.output_path.joinpath(f"gui{index}.py").write_text(code[index], encoding='UTF-8') + '''Write code and assets to the specified directories.''' + code=self.to_code() + for index in range(len(code)):self.output_path.joinpath('gui.py'if index==0 else f'gui{index}.py').write_text(code[index],encoding='UTF-8') \ No newline at end of file diff --git a/Tkinter Designer/tkdesigner/figma/custom_elements.py b/Tkinter Designer/tkdesigner/figma/custom_elements.py index 6980f6a..bb01632 100644 --- a/Tkinter Designer/tkdesigner/figma/custom_elements.py +++ b/Tkinter Designer/tkdesigner/figma/custom_elements.py @@ -1,170 +1,57 @@ -from .vector_elements import Vector, Rectangle - -TEXT_INPUT_ELEMENT_TYPES = { - "TextArea": "Text", - "TextBox": "Entry" -} - - +from .vector_elements import Vector,Rectangle +TEXT_INPUT_ELEMENT_TYPES={'TextArea':'Text','TextBox':'Entry'} class Button(Rectangle): - def __init__(self, node, frame, image_path, *, id_): - super().__init__(node, frame) - self.image_path = image_path - self.id_ = id_ - - def to_code(self): - return f""" -button_image_{self.id_} = PhotoImage( - file=relative_to_assets("{self.image_path}")) -button_{self.id_} = Button( - image=button_image_{self.id_}, - borderwidth=0, - highlightthickness=0, - command=lambda: print("button_{self.id_} clicked"), - relief="flat" -) -button_{self.id_}.place( - x={self.x}, - y={self.y}, - width={self.width}, - height={self.height} -) -""" - - + def __init__(self,node,frame,image_path,*,id_): + super().__init__(node,frame) + self.image_path,self.id_=image_path,id_ + def to_code(self):return f'''button_image_{self.id_}=PhotoImage(file=relative_to_assets('{self.image_path}')) +button_{self.id_}=Button(image=button_image_{self.id_},borderwidth=0,highlightthickness=0,command=lambda:print('button_{self.id_} clicked'),relief='flat') +button_{self.id_}.place(x={self.x},y={self.y},width={self.width},height={self.height})''' class Text(Vector): - def __init__(self, node, frame): + def __init__(self,node,frame): super().__init__(node) - - self.x, self.y = self.position(frame) - self.width, self.height = self.size() - - self.text_color = self.color() - self.font, self.font_size = self.font_property() - self.text = self.characters.replace("\n", "\\n") - + (self.x,self.y),(self.width,self.height),self.text_color,(self.font,self.font_size),self.text=self.position(frame),self.size(),self.color(),self.font_property(),self.characters.replace('\n','\\n') @property def characters(self) -> str: - string: str = self.node.get("characters") - text_case: str = self.style.get("textCase", "ORIGINAL") - - if text_case == "UPPER": - string = string.upper() - elif text_case == "LOWER": - string = string.lower() - elif text_case == "TITLE": - string = string.title() - + string:str=self.node.get('characters') + text_case:str=self.style.get('textCase','ORIGINAL') + if text_case=='UPPER':string=string.upper() + elif text_case=='LOWER':string=string.lower() + elif text_case=='TITLE':string=string.title() return string - @property - def style(self): - # TODO: Native conversion - return self.node.get("style") - + def style(self):return self.node.get('style') @property - def character_style_overrides(self): - return self.node.get("characterStyleOverrides") - + def character_style_overrides(self):return self.node.get('characterStyleOverrides') @property - def style_override_table(self): - # TODO: Native conversion - return self.node.get("styleOverrideTable") - + def style_override_table(self):return self.node.get('styleOverrideTable') def font_property(self): - style = self.node.get("style") - - font_name = style.get("fontPostScriptName") - if font_name is None: - font_name = style["fontFamily"] - - font_name = font_name.replace('-', ' ') - font_size = style["fontSize"] - return font_name, font_size - - def to_code(self): - return f""" -canvas.create_text( - {self.x}, - {self.y}, - anchor="nw", - text="{self.text}", - fill="{self.text_color}", - font=("{self.font}", {int(self.font_size)} * -1) -) -""" - - + style,font_name=self.node.get('style'),style.get('fontPostScriptName') + if font_name is None:font_name=style['fontFamily'] + return font_name.replace('-',' '),style['fontSize'] + def to_code(self):return f'canvas.create_text({self.x},{self.y},anchor="nw",text="{self.text}",fill="{self.text_color}",font=("{self.font}",{int(self.font_size)}*-1))' class Image(Vector): - def __init__(self, node, frame, image_path, *, id_): + def __init__(self,node,frame,image_path,*,id_): super().__init__(node) - - self.x, self.y = self.position(frame) - - width, height = self.size() - self.x += width // 2 - self.y += height // 2 - - self.image_path = image_path - self.id_ = id_ - - def to_code(self): - return f""" -image_image_{self.id_} = PhotoImage( - file=relative_to_assets("{self.image_path}")) -image_{self.id_} = canvas.create_image( - {self.x}, - {self.y}, - image=image_image_{self.id_} -) -""" - - + (self.x,self.y),(width,height)=self.position(frame),self.size() + self.x,self.y,self.image_path,self.id_=self.x+(width//2),self.y+(height//2),image_path,id_ + def to_code(self):return f'''image_image_{self.id_}=PhotoImage(file=relative_to_assets('{self.image_path}')) +image_{self.id_}=canvas.create_image({self.x},{self.y},image=image_image_{self.id_})''' class TextEntry(Vector): - def __init__(self, node, frame, image_path, *, id_): + def __init__(self,node,frame,image_path,*,id_): super().__init__(node) - - self.id_ = id_ - self.image_path = image_path - - self.x, self.y = self.position(frame) - width, height = self.size() - self.x += width / 2 - self.y += height / 2 - - self.bg_color = self.color() - - corner_radius = self.get("cornerRadius", 0) - if corner_radius > height / 2: - corner_radius = height / 2 - - self.entry_width = width - (corner_radius * 2) - self.entry_height = height - 2 - - self.entry_x, self.entry_y = self.position(frame) - self.entry_x += corner_radius - - self.entry_type = TEXT_INPUT_ELEMENT_TYPES.get(self.get("name")) - - def to_code(self): - return f""" -entry_image_{self.id_} = PhotoImage( - file=relative_to_assets("{self.image_path}")) -entry_bg_{self.id_} = canvas.create_image( - {self.x}, - {self.y}, - image=entry_image_{self.id_} -) -entry_{self.id_} = {self.entry_type}( - bd=0, - bg="{self.bg_color}", - fg="#000716", - highlightthickness=0 -) -entry_{self.id_}.place( - x={self.entry_x}, - y={self.entry_y}, - width={self.entry_width}, - height={self.entry_height} -) -""" + self.id_,self.image_path=id_,image_path + (self.x,self.y),(width,height)=self.position(frame),self.size() + self.x,self.y=self.x+(width//2),self.y+(height//2) + self.bg_color=self.color() + corner_radius=self.get('cornerRadius',0) + corner_radius=min(corner_radius,height / 2) + self.entry_width=width-(corner_radius * 2) + self.entry_height=height-2 + self.entry_x,self.entry_y=self.position(frame) + self.entry_x+=corner_radius + self.entry_type=TEXT_INPUT_ELEMENT_TYPES.get(self.get('name')) + def to_code(self):return f'''entry_image_{self.id_}=PhotoImage(file=relative_to_assets('{self.image_path}')) +entry_bg_{self.id_}=canvas.create_image({self.x},{self.y},image=entry_image_{self.id_}) +entry_{self.id_}={self.entry_type}(bd=0,bg='{self.bg_color}',fg='#000716',highlightthickness=0) +entry_{self.id_}.place(x={self.entry_x},y={self.entry_y},width={self.entry_width},height={self.entry_height})''' diff --git a/Tkinter Designer/tkdesigner/figma/endpoints.py b/Tkinter Designer/tkdesigner/figma/endpoints.py index f0a80d3..2bd0c50 100644 --- a/Tkinter Designer/tkdesigner/figma/endpoints.py +++ b/Tkinter Designer/tkdesigner/figma/endpoints.py @@ -1,40 +1,14 @@ """Utility classes and functions for Figma API endpoints. """ import requests - - class Files: - """https://www.figma.com/developers/api#files-endpoints - """ - - API_ENDPOINT_URL = "https://api.figma.com/v1" - - def __init__(self, token, file_key): - self.token = token - self.file_key = file_key - - def __str__(self): - return f"Files {{ Token: {self.token}, File: {self.file_key} }}" - + """https://www.figma.com/developers/api#files-endpoints""" + API_ENDPOINT_URL="https://api.figma.com/v1" + def __init__(self,token,file_key):self.token,self.file_key=token,file_key + def __str__(self):return f"Files {{ Token: {self.token},File: {self.file_key} }}" def get_file(self) -> dict: - try: - response = requests.get( - f"{self.API_ENDPOINT_URL}/files/{self.file_key}", - headers={"X-FIGMA-TOKEN": self.token} - ) - except ValueError: - raise RuntimeError( - "Invalid Input. Please check your input and try again.") - except requests.ConnectionError: - raise RuntimeError( - "Tkinter Designer requires internet access to work.") - else: - return response.json() - - def get_image(self, item_id) -> str: - response = requests.get( - f"{self.API_ENDPOINT_URL}/images/{self.file_key}?ids={item_id}&scale=2", - headers={"X-FIGMA-TOKEN": self.token} - ) - - return response.json()["images"][item_id] + try:response=requests.get(f"{self.API_ENDPOINT_URL}/files/{self.file_key}",headers={"X-FIGMA-TOKEN": self.token}) + except ValueError:raise RuntimeError("Invalid Input. Please check your input and try again.") + except requests.ConnectionError:raise RuntimeError("Tkinter Designer requires internet access to work.") + else:return response.json() + def get_image(self,item_id)->str:return requests.get(f"{self.API_ENDPOINT_URL}/images/{self.file_key}?ids={item_id}&scale=2",headers={"X-FIGMA-TOKEN": self.token}).json()["images"][item_id] diff --git a/Tkinter Designer/tkdesigner/figma/frame.py b/Tkinter Designer/tkdesigner/figma/frame.py index 5fad351..ccf66d0 100644 --- a/Tkinter Designer/tkdesigner/figma/frame.py +++ b/Tkinter Designer/tkdesigner/figma/frame.py @@ -1,152 +1,79 @@ from ..constants import ASSETS_PATH from ..utils import download_image - from .node import Node -from .vector_elements import Line, Rectangle, UnknownElement -from .custom_elements import Button, Text, Image, TextEntry - +from .vector_elements import Line,Rectangle,UnknownElement +from .custom_elements import Button,Text,Image,TextEntry from jinja2 import Template from pathlib import Path - - class Frame(Node): - def __init__(self, node, figma_file, output_path, frameCount=0): + def __init__(self,node,figma_file,output_path,frameCount=0): super().__init__(node) - - self.width, self.height = self.size() - self.bg_color = self.color() - - self.counter = {} - - self.figma_file = figma_file - - self.output_path: Path = output_path - self.assets_path: Path = output_path / ASSETS_PATH / f"frame{frameCount}" - - self.output_path.mkdir(parents=True, exist_ok=True) - self.assets_path.mkdir(parents=True, exist_ok=True) - - self.elements = [ - self.create_element(child) - for child in self.children - if Node(child).visible - ] - - def create_element(self, element): - element_name = element["name"].strip().lower() - element_type = element["type"].strip().lower() - - print( - "Creating Element " - f"{{ name: {element_name}, type: {element_type} }}" - ) - - if element_name == "button": - self.counter[Button] = self.counter.get(Button, 0) + 1 - - item_id = element["id"] - image_url = self.figma_file.get_image(item_id) - image_path = ( - self.assets_path / f"button_{self.counter[Button]}.png") - download_image(image_url, image_path) - - image_path = image_path.relative_to(self.assets_path) - - return Button( - element, self, image_path, id_=f"{self.counter[Button]}") - - elif element_name in ("textbox", "textarea"): - self.counter[TextEntry] = self.counter.get(TextEntry, 0) + 1 - - item_id = element["id"] - image_url = self.figma_file.get_image(item_id) - image_path = ( - self.assets_path / f"entry_{self.counter[TextEntry]}.png") - download_image(image_url, image_path) - - image_path = image_path.relative_to(self.assets_path) - - return TextEntry( - element, self, image_path, id_=f"{self.counter[TextEntry]}") - - elif element_name == "image": - self.counter[Image] = self.counter.get(Image, 0) + 1 - - item_id = element["id"] - image_url = self.figma_file.get_image(item_id) - image_path = self.assets_path / f"image_{self.counter[Image]}.png" - download_image(image_url, image_path) - - image_path = image_path.relative_to(self.assets_path) - - return Image( - element, self, image_path, id_=f"{self.counter[Image]}") - - if element_name == "rectangle" or element_type == "rectangle": - return Rectangle(element, self) - - if element_name == "line" or element_type == "line": - return Line(element, self) - - elif element_type == "text": - return Text(element, self) - + self.width,self.height=self.size() + self.bg_color=self.color() + self.counter={} + self.figma_file=figma_file + self.output_path:Path=output_path + self.assets_path:Path=output_path/ASSETS_PATH/f'frame{frameCount}' + self.output_path.mkdir(parents=True,exist_ok=True) + self.assets_path.mkdir(parents=True,exist_ok=True) + self.elements=[self.create_element(child)for child in self.children if Node(child).visible] + def create_element(self,element): + element_name=element['name'].strip().lower() + element_type=element['type'].strip().lower() + print(f'Creating Element {{ name: {element_name}, type: {element_type} }}') + if element_name=='button': + self.counter[Button]=self.counter.get(Button,0) + 1 + item_id=element['id'] + image_url=self.figma_file.get_image(item_id) + image_path=(self.assets_path/f'button_{self.counter[Button]}.png') + download_image(image_url,image_path) + image_path=image_path.relative_to(self.assets_path) + return Button(element,self,image_path,id_=f'{self.counter[Button]}') + elif element_name in ('textbox','textarea'): + self.counter[TextEntry]=self.counter.get(TextEntry,0) + 1 + item_id=element['id'] + image_url=self.figma_file.get_image(item_id) + image_path=( + self.assets_path/f'entry_{self.counter[TextEntry]}.png') + download_image(image_url,image_path) + image_path=image_path.relative_to(self.assets_path) + return TextEntry(element,self,image_path,id_=f'{self.counter[TextEntry]}') + elif element_name=='image': + self.counter[Image]=self.counter.get(Image,0) + 1 + item_id=element['id'] + image_url=self.figma_file.get_image(item_id) + image_path=self.assets_path/f'image_{self.counter[Image]}.png' + download_image(image_url,image_path) + image_path=image_path.relative_to(self.assets_path) + return Image(element,self,image_path,id_=f'{self.counter[Image]}') + if element_name=='rectangle' or element_type=='rectangle': + return Rectangle(element,self) + if element_name=='line' or element_type=='line':return Line(element,self) + elif element_type=='text':return Text(element,self) else: - print( - f"Element with the name: `{element_name}` cannot be parsed. " - "Would be displayed as Black Rectangle") - return UnknownElement(element, self) - + print(f'Element with the name:`{element_name}` cannot be parsed. Would be displayed as Black Rectangle') + return UnknownElement(element,self) @property - def children(self): - return self.node.get("children") - - def color(self) -> str: - """Returns HEX form of element RGB color (str) - """ + def children(self):return self.node.get('children') + def color(self)->str: + '''Returns HEX form of element RGB color (str)''' try: - color = self.node["fills"][0]["color"] - r, g, b, *_ = [int(color.get(i, 0) * 255) for i in "rgba"] - return f"#{r:02X}{g:02X}{b:02X}" - except Exception: - return "#FFFFFF" - - def size(self) -> tuple: - """Returns element dimensions as width (int) and height (int) - """ - bbox = self.node["absoluteBoundingBox"] - width = bbox["width"] - height = bbox["height"] - return int(width), int(height) - - def to_code(self, template): - t = Template(template) - return t.render( - window=self, elements=self.elements, assets_path=self.assets_path) - - -# Frame Subclasses - - + color=self.node['fills'][0]['color'] + r,g,b,*_=[int(color.get(i,0)*255)for i in'rgba'] + return f'#{r:02X}{g:02X}{b:02X}' + except Exception:return '#FFFFFF' + def size(self)->tuple: + '''Returns element dimensions as width (int) and height (int)''' + bbox=self.node['absoluteBoundingBox'] + return int(bbox['width']),int(bbox['height']) + def to_code(self,template):return Template(template).render(window=self,elements=self.elements,assets_path=self.assets_path) class Group(Frame): - def __init__(self, node): - super().__init__(node) - - + def __init__(self,node):super().__init__(node) class Component(Frame): - def __init__(self, node): - super().__init__(node) - - + def __init__(self,node):super().__init__(node) class ComponentSet(Frame): - def __init__(self, node): - super().__init__(node) - - + def __init__(self,node):super().__init__(node) class Instance(Frame): - def __init__(self, node): - super().__init__(node) - + def __init__(self,node):super().__init__(node) @property - def component_id(self) -> str: - self.node.get("componentId") + def component_id(self)->str:self.node.get('componentId') diff --git a/Tkinter Designer/tkdesigner/figma/node.py b/Tkinter Designer/tkdesigner/figma/node.py index e7a5083..90915e3 100644 --- a/Tkinter Designer/tkdesigner/figma/node.py +++ b/Tkinter Designer/tkdesigner/figma/node.py @@ -1,89 +1,43 @@ class Node: - def __init__(self, node: dict): - self.node = node - + def __init__(self,node):self.node=node @property - def id(self) -> str: - return self.node.get("id") - + def id(self)->str:return self.node.get('id') @property - def name(self) -> str: - return self.node.get("name") - + def name(self)->str:return self.node.get('name') @property - def visible(self) -> bool: - """Whether or not the node is visible on the canvas. - """ - return self.node.get("visible", True) - + def visible(self)->bool:'''Whether or not the node is visible on the canvas.''' + return self.node.get('visible',True) @property - def type(self) -> str: - return self.node.get("type") - + def type(self)->str:return self.node.get('type') @property - def plugin_data(self): - return self.node.get("pluginData") - + def plugin_data(self):return self.node.get('pluginData') @property - def shared_plugin_data(self): - return self.node.get("sharedPluginData") - - def get(self, key, default=None): - return self.node.get(key, default) - - + def shared_plugin_data(self):return self.node.get('sharedPluginData') + def get(self,key,default=None):return self.node.get(key,default) class Document(Node): - def __init__(self, node, root="window"): + def __init__(self,node,root='window'): super().__init__(node) - self.root = root - + self.root=root @property - def children(self): - return self.node.get("children") - - + def children(self):return self.node.get('children') class Canvas(Node): - def __init__(self, node): - super().__init__(node) - + def __init__(self,node):super().__init__(node) @property - def children(self): - return self.node.get("children") - + def children(self):return self.node.get('children') @property - def background_color(self): - return self.node.get("backgroundColor") - + def background_color(self):return self.node.get('backgroundColor') @property - def prototype_start_node_id(self) -> str: - return self.node.get("prototypeStartNodeID") - + def prototype_start_node_id(self)->str:return self.node.get('prototypeStartNodeID') @property - def export_settings(self): - return self.node.get("exportSettings") - - def generate(self): - return "" - - + def export_settings(self):return self.node.get('exportSettings') + def generate(self):return'' class Slice(Node): - def __init__(self, node): - super().__init__(node) - + def __init__(self,node):super().__init__(node) @property - def export_settings(self): - # TODO: Native conversion - return self.node.get("exportSettings") - + def export_settings(self):return self.node.get('exportSettings') @property - def absolute_bounding_box(self): - # TODO: Native conversion - return self.node.get("absoluteBoundingBox") - + def absolute_bounding_box(self):return self.node.get('absoluteBoundingBox') @property - def size(self): - return self.node.get("size") - + def size(self):return self.node.get('size') @property - def relative_transform(self): - return self.node.get("relativeTransform") + def relative_transform(self):return self.node.get('relativeTransform') \ No newline at end of file diff --git a/Tkinter Designer/tkdesigner/figma/vector_elements.py b/Tkinter Designer/tkdesigner/figma/vector_elements.py index 1f50b3f..aeb96d7 100644 --- a/Tkinter Designer/tkdesigner/figma/vector_elements.py +++ b/Tkinter Designer/tkdesigner/figma/vector_elements.py @@ -1,118 +1,60 @@ from .node import Node - - class Vector(Node): - def __init__(self, node): - super().__init__(node) - - def color(self) -> str: - """Returns HEX form of element RGB color (str) - """ + def __init__(self,node):super().__init__(node) + def color(self)->str: + '''Returns HEX form of element RGB color (str)''' try: - color = self.node["fills"][0]["color"] - r, g, b, *_ = [int(color.get(i, 0) * 255) for i in "rgba"] - return f"#{r:02X}{g:02X}{b:02X}" - except Exception: - return "#FFFFFF" - + color=self.node['fills'][0]['color'] + r,g,b,*_=[int(color.get(i,0) * 255) for i in 'rgba'] + return f'#{r:02X}{g:02X}{b:02X}' + except Exception:return '#FFFFFF' def size(self): - bbox = self.node["absoluteBoundingBox"] - width = bbox["width"] - height = bbox["height"] - return width, height - - def position(self, frame): - # Returns element coordinates as x (int) and y (int) - bbox = self.node["absoluteBoundingBox"] - x = bbox["x"] - y = bbox["y"] - - frame_bbox = frame.node["absoluteBoundingBox"] - frame_x = frame_bbox["x"] - frame_y = frame_bbox["y"] - - x = abs(x - frame_x) - y = abs(y - frame_y) - return x, y - - + bbox=self.node['absoluteBoundingBox'] + return bbox['width'],bbox['height'] + def position(self,frame): + '''Returns element coordinates as x (int) and y (int)''' + bbox=self.node['absoluteBoundingBox'] + x=bbox['x'] + y=bbox['y'] + frame_bbox=frame.node['absoluteBoundingBox'] + frame_x=frame_bbox['x'] + frame_y=frame_bbox['y'] + return abs(x-frame_x),abs(y-frame_y) class Star(Vector): - def __init__(self, node): - super().__init__(node) - + def __init__(self,node):super().__init__(node) class Ellipse(Vector): - def __init__(self, node): - super().__init__(node) - - + def __init__(self,node):super().__init__(node) class RegularPolygon(Vector): - def __init__(self, node): - super().__init__(node) - - + def __init__(self,node):super().__init__(node) class Rectangle(Vector): - def __init__(self, node, frame): + def __init__(self,node,frame): super().__init__(node) - self.x, self.y = self.position(frame) - self.width, self.height = self.size() - self.fill_color = self.color() - + self.x,self.y=self.position(frame) + self.width,self.height=self.size() + self.fill_color=self.color() @property - def corner_radius(self): - return self.node.get("cornerRadius") - + def corner_radius(self):return self.node.get('cornerRadius') @property - def rectangle_corner_radii(self): - return self.node.get("rectangleCornerRadii") - - def to_code(self): - return f""" -canvas.create_rectangle( - {self.x}, - {self.y}, - {self.x + self.width}, - {self.y + self.height}, - fill="{self.fill_color}", - outline="") -""" - - + def rectangle_corner_radii(self):return self.node.get('rectangleCornerRadii') + def to_code(self):return f'''canvas.create_rectangle({self.x},{self.y},{self.x+self.width},{self.y+self.height},fill='{self.fill_color}',outline='')''' class Line(Rectangle): - def __init__(self, node, frame): - super().__init__(node, frame) - - def color(self) -> str: - """Returns HEX form of element RGB color (str) - """ + def __init__(self,node,frame):super().__init__(node,frame) + def color(self)->str: + '''Returns HEX form of element RGB color (str)''' try: - color = self.node["strokes"][0]["color"] - r, g, b, *_ = [int(color.get(i, 0) * 255) for i in "rgba"] - return f"#{r:02X}{g:02X}{b:02X}" - except Exception: - return "#FFFFFF" - + color=self.node['strokes'][0]['color'] + r,g,b,*_=[int(color.get(i,0) * 255) for i in 'rgba'] + return f'#{r:02X}{g:02X}{b:02X}' + except Exception:return '#FFFFFF' def size(self): - width, height = super().size() - return width + self.node["strokeWeight"], height + self.node["strokeWeight"] - - def position(self, frame): - x, y = super().position(frame) - return x - self.node["strokeWeight"], y - self.node["strokeWeight"] - - + width,height=super().size() + return width+self.node['strokeWeight'],height+self.node['strokeWeight'] + def position(self,frame): + x,y=super().position(frame) + return x-self.node['strokeWeight'],y-self.node['strokeWeight'] class UnknownElement(Vector): - def __init__(self, node, frame): + def __init__(self,node,frame): super().__init__(node) - self.x, self.y = self.position(frame) - self.width, self.height = self.size() - - def to_code(self): - return f""" -canvas.create_rectangle( - {self.x}, - {self.y}, - {self.x + self.width}, - {self.y + self.height}, - fill="#000000", - outline="") -""" + self.x,self.y=self.position(frame) + self.width,self.height=self.size() + def to_code(self):return f'''canvas.create_rectangle({self.x},{self.y},{self.x+self.width},{self.y+self.height},fill='#000000',outline='')''' diff --git a/Tkinter Designer/tkdesigner/template.py b/Tkinter Designer/tkdesigner/template.py index 3315438..35f899e 100644 --- a/Tkinter Designer/tkdesigner/template.py +++ b/Tkinter Designer/tkdesigner/template.py @@ -1,44 +1,16 @@ -TEMPLATE = """ +TEMPLATE=''' from pathlib import Path - -# from tkinter import * -# Explicit imports to satisfy Flake8 from tkinter import Tk, Canvas, Entry, Text, Button, PhotoImage - - -OUTPUT_PATH = Path(__file__).parent -ASSETS_PATH = OUTPUT_PATH / Path(r"{{ assets_path }}") - - -def relative_to_assets(path: str) -> Path: - return ASSETS_PATH / Path(path) - - -window = Tk() - -window.geometry("{{ window.width }}x{{ window.height }}") -window.configure(bg = "{{ window.bg_color }}") - - -canvas = Canvas( - window, - bg = "{{ window.bg_color }}", - height = {{ window.height }}, - width = {{ window.width }}, - bd = 0, - highlightthickness = 0, - relief = "ridge" -) - -canvas.place(x = 0, y = 0) - - +OUTPUT_PATH=Path(__file__).parent +ASSETS_PATH=OUTPUT_PATH / Path(r'{{ assets_path }}') +def relative_to_assets(path: str) -> Path:return ASSETS_PATH / Path(path) +window=Tk() +window.geometry('{{ window.width }}x{{ window.height }}') +window.configure(bg='{{ window.bg_color }}') +canvas=Canvas(window,bg='{{ window.bg_color }}',height={{ window.height }},width={{ window.width }},bd=0,highlightthickness=0,relief='ridge') +canvas.place(x=0, y=0) {%- for element in elements -%} {{ element.to_code() }} {%- endfor -%} - - window.resizable(False, False) -window.mainloop() - -""" +window.mainloop()''' \ No newline at end of file diff --git a/Tkinter Designer/tkdesigner/utils.py b/Tkinter Designer/tkdesigner/utils.py index a73695e..92309f9 100644 --- a/Tkinter Designer/tkdesigner/utils.py +++ b/Tkinter Designer/tkdesigner/utils.py @@ -1,25 +1,17 @@ """ Small utility functions. """ -import requests +import requests,io from PIL import Image -import io - - def find_between(s, first, last): try: - start = s.index(first) + len(first) - end = s.index(last, start) - + start=s.index(first) + len(first) + end=s.index(last, start) return s[start:end] - except ValueError: - return "" - - + except ValueError:return "" def download_image(url, image_path): - response = requests.get(url) - content = io.BytesIO(response.content) - im = Image.open(content) - im = im.resize((im.size[0] // 2, im.size[1] // 2), Image.ANTIALIAS) - with open(image_path, "wb") as file: - im.save(file) + response=requests.get(url) + content=io.BytesIO(response.content) + im=Image.open(content) + im=im.resize((im.size[0] // 2, im.size[1] // 2), Image.ANTIALIAS) + with open(image_path, "wb") as file:im.save(file) diff --git a/Web Scrapers/buildGUI.bat b/Web Scrapers/buildGUI.bat deleted file mode 100644 index 010f1d2..0000000 --- a/Web Scrapers/buildGUI.bat +++ /dev/null @@ -1,2 +0,0 @@ -python -u "c:\Users\aaron\Documents\GitHub\Python-Pokemon-Project\Tkinter Designer\gui\gui.py" -PAUSE \ No newline at end of file