+#!/usr/bin/env python3
+import tkinter as tk
+from tkinter import ttk
+import datetime
+import re
+import shelve
+
+entries=[] # updated by user
+buttons=[]
+count=0
+kount=0
+
+window=tk.Tk()
+window.title((datetime.date.today()).strftime("%B"))
+window.minsize(width=240, height=50)
+window.maxsize(width=240,height=365)
+window.resizable(width=True,height=True)
+window.columnconfigure(0,weight=1)
+window.columnconfigure(1,weight=1)
+
+
+uframe=tk.Frame(window) #entry widget, add and delete button
+uframe.columnconfigure(0,weight=1)
+uframe.columnconfigure(1,weight=1)
+uframe.grid(row=0,column=0,columnspan=2,sticky='nsew')
+
+scrollframe=tk.Frame(window, height=283, width=240)
+scrollframe.grid_columnconfigure(0,weight=1)
+scrollframe.grid_rowconfigure(0,weight=1)
+scrollframe.grid(row=1,column=0,sticky='nsew')
+scrollframe.grid_propagate(0)
+
+kanvas=tk.Canvas(scrollframe)
+rScroll=ttk.Scrollbar(scrollframe,orient='vertical',
+ command=kanvas.yview)
+rScroll.grid(row=0,column=1,sticky='ns')
+kanvas.configure(yscrollcommand=rScroll.set,borderwidth=0,
+ bg='medium purple')
+kanvas.configure(scrollregion=kanvas.bbox('all'))
+kanvas.grid(row=0,column=0,sticky='nsew')
+
+rframe=tk.Frame(kanvas) # buttons created from input
+kanvas.create_window((0,0),window=rframe,anchor='nw')
+rframe.columnconfigure(0, minsize=225)
+
+
+# reset/configure inner frame (rframe) to be scrollregion
+def updateScrollRegion(kanvas):
+ kanvas.update_idletasks()
+ kanvas.configure(scrollregion=kanvas.bbox('all'))
+
+# set scrollwheel
+def MouseWheelHandler(event):
+ direction=0
+ if event.num==5 or event.delta==-120:
+ direction=1
+ if event.num==4 or event.delta==120:
+ direction=-1
+ kanvas.yview_scroll(direction,'units')
+window.bind("<MouseWheel>",MouseWheelHandler)
+window.bind("<Button-4>",MouseWheelHandler)
+window.bind("<Button-5>",MouseWheelHandler)
+
+rframe.bind("<Configure>", lambda event, kanvas=kanvas: updateScrollRegion(kanvas))
+
+style=ttk.Style()
+style2=ttk.Style()
+style3=ttk.Style()
+
+style.theme_use('default')
+style.configure('todo.TButton',foreground='blue4',
+ background='medium purple')
+style.map('todo.TButton',
+ foreground=[('pressed','maroon'),('disabled','medium purple')],
+ background=[('active','slate blue'),('disabled','blue4')])
+style2.configure('admin.TButton',forgeground='deep pink',
+ background='MediumPurple4')
+style2.map('admin.TButton',
+ foreground=[('pressed','DeepPink2'),('focus','hot pink'),('!focus','deep pink')],
+ background=[('active','DeepPink4'),('focus','MediumOrchid4')])
+style3.configure('admin.TEntry',forgeground='deep pink',
+ fieldbackground='MediumPurple4')
+style3.map('admin.TEntry',
+ foreground=[('focus','hot pink'),('!focus','deep pink')],
+ fieldbackground=[('active','DeepPink4'),('focus','MediumOrchid4')])
+
+content=tk.StringVar()
+
+def clear_entry():
+ inPut.delete(0,'end')
+
+def add():
+ cOntent=content.get()
+ entries.append(cOntent)
+ clear_entry()
+ count=len(entries)
+ for entry in entries:
+ btn=ttk.Button(rframe,text=entry,style='todo.TButton',
+ command=lambda :done())
+ btn.grid(row=(count),column=0,sticky='ew')
+ if btn['text'].endswith(" DONE"):
+ btn['state']='disabled'
+ buttons.append(btn)
+ for children in rframe.winfo_children():
+ if children.winfo_class() =='TButton':
+ if children not in buttons:
+ children.destroy()
+ inPut.focus_set()
+ updateScrollRegion(kanvas)
+ kanvas.yview('moveto',1)
+
+ def done():
+ btn.configure(text=btn['text']+" DONE",state='disabled')
+ return btn
+
+def reset(x):
+ remove=r'\sDONE'
+ for btn in buttons:
+ btn['state']='normal'
+ btn['text']=re.sub(remove,'',(btn['text']))
+
+def save():
+ saveData=[]
+ for button in buttons:
+ saveData.append(button['text'])
+
+ shelfFile=shelve.open('/home/Jimmy/mu_code/savedButtons')
+ shelfFile['saveData']=saveData
+ shelfFile.close()
+
+def load():
+ a=len(entries)
+ if a==0:
+ shelfFile=shelve.open('/home/Jimmy/mu_code/savedButtons')
+ saveData=shelfFile['saveData']
+ for item in saveData:
+ inPut.insert(0,item)
+ add()
+
+def delete():
+ entries.clear()
+ for button in buttons:
+ entries.append(button['text'])
+
+ new=tk.Toplevel(window)
+ new.title('delete')
+ new.minsize(width=240, height=50)
+ new.resizable(width=True,height=True)
+ new.columnconfigure(0,weight=1)
+ new.columnconfigure(1,weight=1)
+ new.transient(window)
+
+
+ newFrame=tk.Frame(new)
+ newFrame.columnconfigure(0,weight=1)
+ newFrame.grid(row=0,column=0,columnspan=2,sticky='nsew')
+
+# listbox with vertical(y) scroll
+ lb=tk.Listbox(newFrame,bg='peach puff',fg='DeepPink2',
+ selectbackground='maroon3',selectforeground='DarkOrchid4')
+ lb.grid(column=0,row=0, columnspan=2,sticky='nsew')
+ yScroll=ttk.Scrollbar(new, orient='vertical')
+ yScroll.grid(column=2, row=0, sticky='ns')
+ yScroll['command']=lb.yview
+ lb.configure(yscrollcommand=yScroll.set)
+
+ reMove=ttk.Button(newFrame,text='remove',style='admin.TButton',
+ command=lambda :remove())
+ reMove.grid(column=0,row=1,sticky='ew')
+
+ for entry in entries:
+ lb.insert(tk.END,entry)
+
+ def remove():
+ rmvdTxt=lb.get(tk.ANCHOR)
+ lb.delete(tk.ANCHOR)
+ entries.remove(rmvdTxt)
+ new.destroy()
+ reload=[]
+ for button in buttons:
+ if button['text']==rmvdTxt:
+ buttons.remove(button)
+ entries.clear()
+ for button in buttons:
+ entries.append(button['text'])
+ for entry in entries:
+ reload.append(entry)
+ entries.clear()
+ buttons.clear()
+ for widget in rframe.winfo_children():
+ widget.destroy()
+ for item in reload:
+ inPut.insert(0,item)
+ add()
+
+def hitenter(event):
+ add()
+
+inPut=ttk.Entry(uframe,textvariable=content,style='admin.TEntry')
+inPut.grid(row=0,column=0,columnspan=2,sticky='ew')
+inPut.focus_set()
+
+inPut.bind('<Return>',hitenter)
+aDd=ttk.Button(uframe,text='add',command=add,style='admin.TButton')
+aDd.grid(row=1,column=0,sticky='nsew')
+
+deLete=ttk.Button(uframe,text='delete',
+command=delete,style='admin.TButton')
+deLete.grid(row=1,column=1,sticky='nsew')
+
+# make menu bar and drop down items
+menubar=tk.Menu(window, background='SlateBlue2',
+ activebackground='slate blue',disabledforeground='blue4')
+optionsmenu=tk.Menu(window,tearoff=0)
+optionsmenu.add_command(background='SlateBlue2',
+ activebackground='slate blue',label='reset ALL',command=lambda x=buttons :reset(x))
+optionsmenu.add_command(background='SlateBlue2',
+ activebackground='slate blue',label='load',command=load)
+optionsmenu.add_command(background='SlateBlue2',
+ activebackground='slate blue',label='save',command=save)
+optionsmenu.add_command(background='SlateBlue2',
+ activebackground='slate blue',label='exit',command=window.destroy)
+menubar.add_cascade(label='options',menu=optionsmenu)
+datemenu=tk.Menu(window,tearoff=0)
+menubar.add_cascade(label=((datetime.date.today()).strftime("%d-%m-%Y")),
+ state='disabled',menu=datemenu)
+window.config(background='medium purple',menu=menubar)
+
+window.mainloop()
\ No newline at end of file