<commit_before>
###############################################################################
# STconverter 2 allows you to execute Python scripts written for SimpleGUI on 
# a machine configured with Tkinter GUI instead. 
# 
# STconverter 2 is the successor of STconverter, and is different in such ways 
# it has been entirely rewritten to handle with a totally different approach 
# the "conversion". 
# While the first version of STconverter was converting each SimpleGUI operation 
# in the user code to be executable by Tkinter, STconverter 2 is an API between 
# SimpleGUI operations and Tkinter. 
# 
# "Tkinter is Python's de-facto standard GUI (Graphical User Interface) package"
# (http://wiki.python.org/moin/TkInter)
# "SimpleGUI is a custom Python graphical user interface (GUI) module implemented 
# directly in CodeSkulptor that provides an easy to learn interface for building 
# interactive programs in Python" (http://www.codeskulptor.org) used for the 
# online Coursera course "An Introduction to Interactive Programming in Python" 
# by <NAME>, <NAME>, <NAME>, and <NAME> (Rice University) 
# 
# I want to thank <NAME> for his comments and suggestions on how to improve 
# STconverter, which lead to the development of STconverter 2
# 
# For the latest version of STConverter 2 visit the repository on Github: 
# https://github.com/jem-gh/STconverter-2
# 
# STconverter 2 is developed by <NAME>
###############################################################################



import Tkinter



CANVAS_REFRESH_RATE = 66 # in ms (66ms~15fps; 33ms~30fps; 17ms~60fps)

BUTTON_SIZE_RATIO = 0.09
INPUT_SIZE_RATIO = 0.12



class __init__:
    """ Initialize the root window the first time simplegui2tkinter is called """
    window_root = Tkinter.Tk()



class create_frame(__init__):
    """ Set the root window title, create a frame widget, and handle all user's 
        code methods associated to the frame ("frame.xxx"). 
        Called from the user's code with the "simplegui.create_frame" method. 
        A canvas widget is created only if required by using the method 
        "frame.set_draw_handler". """
    
    def __init__(self, title, canvas_width, canvas_height, control_width = 200):
        """ Set the root window title and create the frame widget """
        
        # set the root window title
        self.window_root.title(title)
        
        # create the frame
        self.frame = Tkinter.Frame(self.window_root)
        self.frame.pack()
        
        # variables used by other methods
        self.canvas_width = canvas_width        # by canvas
        self.canvas_height = canvas_height      # by canvas
        self.control_width = control_width      # by label, button, input
    
    
    def start(self):
        """ Initiate the loop event of the root window """
        self.window_root.mainloop()
    
    
    def set_draw_handler(self, draw_handler):
        """ Create the canvas widget by calling the ST_canvas class. 
            Call the canvas methods to set the drawing handler and to refresh 
            the drawing. """
        
        # create the canvas
        self.canvas = ST_canvas(self.frame, self.canvas_width, self.canvas_height)
        
        # call the canvas method to set the canvas drawing handler
        self.canvas.set_draw_handler(draw_handler)
        
        # start the refresh
        t = STconverter_timer(self.window_root, CANVAS_REFRESH_RATE, 
                              self.canvas.refresh_canvas)
        t.set_status(True)
    
    
    def set_canvas_background(self, color):
        """ Call the canvas method to set a new background """
        self.canvas.new_background_color(color)
    
    
    def add_button(self, text, button_handler, width = 0):
        """ Call the button class to add a button on the frame """
        
        # adjust the control width in case the button is larger 
        if self.control_width < width:
            self.control_width = width
        
        Frame_button(self.frame, text, button_handler, width)
    
    
    def add_input(self, text, input_handler, width):
        """ Call the input and label classes to add an input on the frame and 
            its corresponding label """
        
        # adjust the control width in case the input is larger 
        if self.control_width < width:
            self.control_width = width
        
        label_width = self.control_width if self.control_width > width else width
        
        Frame_label(self.frame, text, label_width)
        Frame_input(self.frame, input_handler, width)



class create_timer(__init__):
    """ Create and control a timer with its associated handler by calling the 
        STconverter_timer class. 
        Called from the user's code with the "simplegui.create_timer" method. """
    
    def __init__(self, interval, timer_handler):
        self.t = STconverter_timer(self.window_root, interval, timer_handler)
    
    def start(self):
        self.t.set_status(True)
    
    def stop(self):
        self.t.set_status(False)



class ST_canvas:
    """ Create a canvas widget on the right side of the frame, and handle all 
        user's code methods associated to the canvas ("canvas.xxx"). 
        Called by a redirect from the "create_frame" class which was called from 
        the user's code with the "frame.set_draw_handler" method. """
    
    def __init__(self, frame, canvas_width, canvas_height):
        """ Create a canvas on the right side of the frame with a default black 
            background """
        
        self.canvas = Tkinter.Canvas(frame, width = int(canvas_width), 
                                     height = int(canvas_height))
        self.canvas.pack(side = 'right')
        self.canvas.configure(background = "Black")
    
    
    def new_background_color(self, color):
        """ Set a new background color for the canvas """
        self.canvas.configure(background = color)
    
    
    def set_draw_handler(self, draw_handler):
        """ Set the default drawing handler """
        self.draw_handler = draw_handler
    
    
    def refresh_canvas(self):
        """ Refresh the canvas widget """
        self.canvas.delete('all')
        self.draw_handler(self)
    
    
    def draw_text(self, text, position, font_size, font_color):
        """ Call the text class to add a text item on the canvas """
        Canvas_text(self.canvas, text, position, font_size, font_color)
    
    
    def draw_circle(self, center, radius, line_width, line_color, fill_color=""):
        """ Call the oval class to add a circle/oval item on the canvas """
        Canvas_oval(self.canvas, center, radius, line_width, line_color, fill_color)
    
    
    def draw_line(self, point1, point2, line_width, line_color):
        """ Call the line class to add a line item on the canvas """
        Canvas_line(self.canvas, (point1, point2), line_width, line_color)
    
    
    def draw_polygon(self, points, line_width, line_color, fill_color = ""):
        """ Call the polygon class to add a polygon item on the canvas """
        Canvas_polygon(self.canvas, points, line_width, line_color, fill_color)



class Frame_label:
    """ Add a label widget on the left side of the frame """
    
    def __init__(self, frame, text, width):
        self = Tkinter.Label(frame, text = text, wraplength = int(width))
        self.pack()



class Frame_button:
    """ Add a button widget on the left side of the frame """
    
    def __init__(self, frame, text, button_handler, width):
        self = Tkinter.Button(frame, text = text, command = button_handler)
        self.config(width = int(width * BUTTON_SIZE_RATIO))
        self.pack()



class Frame_input:
    """ Add an input widget on the left side of the frame """
    
    def __init__(self, frame, input_handler, width):
        
        self.input_handler = input_handler
        
        self.input = Tkinter.Entry(frame)
        self.input.bind('<Return>', self.call_handler)
        self.input.config(width = int(width * INPUT_SIZE_RATIO))
        self.input.pack()
    <commit_msg>API: add support label.set_text<commit_after>
###############################################################################
# STconverter 2 allows you to execute Python scripts written for SimpleGUI on 
# a machine configured with Tkinter GUI instead. 
# 
# STconverter 2 is the successor of STconverter, and is different in such ways 
# it has been entirely rewritten to handle with a totally different approach 
# the "conversion". 
# While the first version of STconverter was converting each SimpleGUI operation 
# in the user code to be executable by Tkinter, STconverter 2 is an API between 
# SimpleGUI operations and Tkinter. 
# 
# "Tkinter is Python's de-facto standard GUI (Graphical User Interface) package"
# (http://wiki.python.org/moin/TkInter)
# "SimpleGUI is a custom Python graphical user interface (GUI) module implemented 
# directly in CodeSkulptor that provides an easy to learn interface for building 
# interactive programs in Python" (http://www.codeskulptor.org) used for the 
# online Coursera course "An Introduction to Interactive Programming in Python" 
# by <NAME>, <NAME>, <NAME>, and <NAME> (Rice University) 
# 
# I want to thank <NAME> for his comments and suggestions on how to improve 
# STconverter, which lead to the development of STconverter 2
# 
# For the latest version of STConverter 2 visit the repository on Github: 
# https://github.com/jem-gh/STconverter-2
# 
# STconverter 2 is developed by <NAME>
###############################################################################



import Tkinter



CANVAS_REFRESH_RATE = 66 # in ms (66ms~15fps; 33ms~30fps; 17ms~60fps)

# SimpleGUI and  Tkinter use different units for Buttons and Inputs
# adjust Button and Input size ratio
BUTTON_SIZE_RATIO = 0.09
INPUT_SIZE_RATIO = 0.12



class __init__:
    """ Initialize the root window the first time simplegui2tkinter is called """
    window_root = Tkinter.Tk()



class create_frame(__init__):
    """ Set the root window title, create a frame widget, and handle all user's 
        code methods associated to the frame ("frame.xxx"). 
        Called from the user's code with the "simplegui.create_frame" method. 
        A canvas widget is created only if required by using the method 
        "frame.set_draw_handler". """
    
    def __init__(self, title, canvas_width, canvas_height, control_width = 200):
        """ Set the root window title and create the frame widget """
        
        # set the root window title
        self.window_root.title(title)
        
        # create the frame
        self.frame = Tkinter.Frame(self.window_root)
        self.frame.pack()
        
        # variables used by other methods
        self.canvas_width = canvas_width        # by canvas
        self.canvas_height = canvas_height      # by canvas
        self.control_width = control_width      # by label, button, input
    
    
    def start(self):
        """ Initiate the loop event of the root window """
        self.window_root.mainloop()
    
    
    def set_draw_handler(self, draw_handler):
        """ Create the canvas widget by calling the ST_canvas class. 
            Call the canvas methods to set the drawing handler and to refresh 
            the drawing. """
        
        # create the canvas
        self.canvas = ST_canvas(self.frame, self.canvas_width, self.canvas_height)
        
        # call the canvas method to set the canvas drawing handler
        self.canvas.set_draw_handler(draw_handler)
        
        # start the refresh
        t = STconverter_timer(self.window_root, CANVAS_REFRESH_RATE, 
                              self.canvas.refresh_canvas)
        t.set_status(True)
    
    
    def set_canvas_background(self, color):
        """ Call the canvas method to set a new background """
        self.canvas.new_background_color(color)
    
    
    def add_label(self, text):
        """ Call the label class to add a label on the frame """
        
        return Frame_label(self.frame, text, self.control_width)
    
    
    def add_button(self, text, button_handler, width = 0):
        """ Call the button class to add a button on the frame """
        
        # adjust the width if its larger than the expected control width 
        width = self.control_width if self.control_width < width else width
        
        Frame_button(self.frame, text, button_handler, width)
    
    
    def add_input(self, text, input_handler, width):
        """ Call the input and label classes to add an input on the frame and 
            its corresponding label """
        
        # adjust the width if its larger than the expected control width 
        width = self.control_width if self.control_width < width else width
        
        Frame_label(self.frame, text, self.control_width)
        Frame_input(self.frame, input_handler, width)



class create_timer(__init__):
    """ Create and control a timer with its associated handler by calling the 
        STconverter_timer class. 
        Called from the user's code with the "simplegui.create_timer" method. """
    
    def __init__(self, interval, timer_handler):
        self.t = STconverter_timer(self.window_root, interval, timer_handler)
    
    def start(self):
        self.t.set_status(True)
    
    def stop(self):
        self.t.set_status(False)



class ST_canvas:
    """ Create a canvas widget on the right side of the frame, and handle all 
        user's code methods associated to the canvas ("canvas.xxx"). 
        Called by a redirect from the "create_frame" class which was called from 
        the user's code with the "frame.set_draw_handler" method. """
    
    def __init__(self, frame, canvas_width, canvas_height):
        """ Create a canvas on the right side of the frame with a default black 
            background """
        
        self.canvas = Tkinter.Canvas(frame, width = int(canvas_width), 
                                     height = int(canvas_height))
        self.canvas.pack(side = 'right')
        self.canvas.configure(background = "Black")
    
    
    def new_background_color(self, color):
        """ Set a new background color for the canvas """
        self.canvas.configure(background = color)
    
    
    def set_draw_handler(self, draw_handler):
        """ Set the default drawing handler """
        self.draw_handler = draw_handler
    
    
    def refresh_canvas(self):
        """ Refresh the canvas widget """
        self.canvas.delete('all')
        self.draw_handler(self)
    
    
    def draw_text(self, text, position, font_size, font_color):
        """ Call the text class to add a text item on the canvas """
        Canvas_text(self.canvas, text, position, font_size, font_color)
    
    
    def draw_circle(self, center, radius, line_width, line_color, fill_color=""):
        """ Call the oval class to add a circle/oval item on the canvas """
        Canvas_oval(self.canvas, center, radius, line_width, line_color, fill_color)
    
    
    def draw_line(self, point1, point2, line_width, line_color):
        """ Call the line class to add a line item on the canvas """
        Canvas_line(self.canvas, (point1, point2), line_width, line_color)
    
    
    def draw_polygon(self, points, line_width, line_color, fill_color = ""):
        """ Call the polygon class to add a polygon item on the canvas """
        Canvas_polygon(self.canvas, points, line_width, line_color, fill_color)



class Frame_label:
    """ Add a label widget on the left side of the frame """
    
    def __init__(self, frame, text, width):
        self.label_text = Tkinter.StringVar()
        self.label_text.set(text)
        self.label = Tkinter.Label(frame, textvariable = self.label_text, 
                                   wraplength = int(width))
        self.label.pack()
    
    
    def set_text(self, text):
        """ Update the label text """
        
        self.label_text.set(text)



class Frame_button:
    """ Add a button widget on the left side of the frame """
    
    def __init__(self, frame, text, button_handler, width):
        self = Tkinter.Button(frame, text = text, command = button_handler)
        self.config(width = int(width * BUTTON_SIZE_RATIO))
        self.pack()



class Frame_input:
    """ Add an input widget on the left side of the frame """
    
    def __init__(self, frame, input_handler, width):
        
        self.input_handler = input_handler
        
        self.input = Tkinter.Entry(frame)
        self.input.bind('<Return>', self.call_handler)
        self.input.config(width = int(width * INPUT_SIZE_RATIO))
        self.input.pack()
    
{'fraction_non_alphanumeric': 0.09816207184628237, 'fraction_numerical': 0.004296455424274973, 'mean_word_length': 2.6527898866608544, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7578041', 'n_tokens_mistral': 4733, 'n_tokens_neox': 4561, 'n_words': 1605}