<commit_before>#!/usr/bin/env python
# coding: utf-8
#
# > How to get tkinter canvas to dynamically resize to window width?
# http://stackoverflow.com/questions/22835289/how-to-get-tkinter-canvas-to-dynamically-resize-to-window-width
#
# > Canvas tutoril
# http://www.tkdocs.com/tutorial/canvas.html
#
# > Canvas API reference
# http://effbot.org/tkinterbook/canvas.htm
#
# > Tutorial canvas tk
# http://www.tutorialspoint.com/python/tk_canvas.htm

import threading
import Tkinter as tk
import tkSimpleDialog
import tkFileDialog
from Queue import Queue

import atx
from PIL import Image, ImageTk


def insert_code(filename, code, save=True, marker='# ATX CODE'):
    """ Auto append code """
    content = ''
    for line in open(filename, 'rb'):
        if line.strip() == marker:
            cnt = line.find(marker)
            content += line[:cnt] + code
        content += line
    if save:
        with open(filename, 'wb') as f:
            f.write(content)
    return content

class CropIDE(object):
    def __init__(self, title='AirtestX Basic GUI', device=None):
        self._device = device
        self._root = tk.Tk()
        self._root.title(title)
        self._queue = Queue()

        self._refresh_text = tk.StringVar()
        self._refresh_text.set("Refresh")
        self._gencode_text = tk.StringVar()
        self._attachfile_text = tk.StringVar()

        self._init_items()
        self._init_thread()

        self._lastx = 0
        self._lasty = 0
        self._bounds = None # crop area
        self._center = (0, 0) # center point
        self._offset = (0, 0) # offset to image center
        self._size = (90, 90)
        self._moved = False # click or click and move
        self._color = 'red' # draw color
        self._tkimage = None # keep reference
        self._image = None
        self._ratio = 0.5

    def _init_items(self):
        root = self._root
        root.resizable(0, 0)

        frm_control = tk.Frame(root, bg='#bbb')
        frm_control.grid(column=0, row=0, padx=5, sticky=tk.NW)
        frm_screen = tk.Frame(root, bg='#aaa')
        frm_screen.grid(column=1, row=0)

        frm_ctrl_btns = tk.Frame(frm_control)
        frm_ctrl_btns.grid(column=0, row=0, sticky=tk.W)
        tk.Label(frm_control, text='-'*30).grid(column=0, row=1, sticky=tk.EW)
        frm_ctrl_code = tk.Frame(frm_control)
        frm_ctrl_code.grid(column=0, row=2, sticky=tk.EW)

        tk.Button(frm_ctrl_btns, textvariable=self._refresh_text, command=self._redraw).grid(column=0, row=0, sticky=tk.W)
        tk.Button(frm_ctrl_btns, text="Wakeup", command=self._device.wakeup).grid(column=0, row=1, sticky=tk.W)
        tk.Button(frm_ctrl_btns, text="Save cropped", command=self._save_crop).grid(column=0, row=2, sticky=tk.W)

        tk.Label(frm_ctrl_code, text='Generated code').grid(column=0, row=0, sticky=tk.W)
        tk.Entry(frm_ctrl_code, textvariable=self._gencode_text, width=30).grid(column=0, row=1, sticky=tk.W)
        tk.Button(frm_ctrl_code, text='Run code', command=self._run_code).grid(column=0, row=2, sticky=tk.W)
        tk.Button(frm_ctrl_code, text='Insert and Run', command=self._run_and_insert).grid(column=0, row=3, sticky=tk.W)
        tk.Button(frm_ctrl_code, text='Select File', command=self._run_selectfile).grid(column=0, row=4, sticky=tk.W)
        tk.Label(frm_ctrl_code, textvariable=self._attachfile_text).grid(column=0, row=5, sticky=tk.W)

        self.canvas = tk.Canvas(frm_screen, bg="blue", bd=0, highlightthickness=0, relief='ridge')
        self.canvas.grid(column=0, row=0, padx=10, pady=10)
        self.canvas.bind("<Button-1>", self._stroke_start)
        self.canvas.bind("<B1-Motion>", self._stroke_move)
        self.canvas.bind("<B1-ButtonRelease>", self._stroke_done)

    def _worker(self):
        que = self._queue
        while True:
            (func, args, kwargs) = que.get()
            try:
                func(*args, **kwargs)
            except Exception as e:
                print e
            finally:
                que.task_done()
    
    def _run_async(self, func, args=(), kwargs={}):
        self._queue.put((func, args, kwargs))

    def _init_thread(self):
        th = threading.Thread(name='thread', target=self._worker)
        th.daemon = True
        th.start()

    def _fix_bounds(self, bounds):
        bounds = [x/self._ratio for x in bounds]
        (x0, y0, x1, y1) = bounds
        if x0 > x1:
            x0, y0, x1, y1 = x1, y1, x0, y0
        # in case of out of bounds
        w, h = self._size
        x0 = max(0, x0)
        y0 = max(0, y0)
        x1 = min(w, x1)
        y1 = min(h, y1)
        return map(int, [x0, y0, x1, y1])

    def _save_crop(self):
        print self._bounds
        if self._bounds is None:
            return
        bounds = self._fix_bounds(self._bounds)
        print bounds
        save_to = tkSimpleDialog.askstring("Save cropped image", "Enter filename")
        if save_to:
            if save_to.find('.') == -1:
                save_to += '.png'
            print('Save to:', save_to)
            self._image.crop(bounds).save(save_to)
            if self._offset == (0, 0):
                self._gencode_text.set('click_image("%s")' % save_to)
            else:
                code = 'click_image(atx.Pattern("{name}", offset=({x}, {y})))'.format(
                    name=save_to, x=self._offset[0], y=self._offset[1])
                self._gencode_text.set(code)

    def _run_code(self):
        code = 'self._device.'+self._gencode_text.get()
        exec(code)

    def _run_and_insert(self):
        self._run_code()<commit_msg>add screenshot button and d.<commit_after>#!/usr/bin/env python
# coding: utf-8
#
# > How to get tkinter canvas to dynamically resize to window width?
# http://stackoverflow.com/questions/22835289/how-to-get-tkinter-canvas-to-dynamically-resize-to-window-width
#
# > Canvas tutoril
# http://www.tkdocs.com/tutorial/canvas.html
#
# > Canvas API reference
# http://effbot.org/tkinterbook/canvas.htm
#
# > Tutorial canvas tk
# http://www.tutorialspoint.com/python/tk_canvas.htm

import threading
import Tkinter as tk
import tkSimpleDialog
import tkFileDialog
from Queue import Queue

import atx
from PIL import Image, ImageTk


def insert_code(filename, code, save=True, marker='# ATX CODE'):
    """ Auto append code """
    content = ''
    for line in open(filename, 'rb'):
        if line.strip() == marker:
            cnt = line.find(marker)
            content += line[:cnt] + code
        content += line
    if save:
        with open(filename, 'wb') as f:
            f.write(content)
    return content

class CropIDE(object):
    def __init__(self, title='AirtestX Basic GUI', device=None):
        self._device = device
        self._root = tk.Tk()
        self._root.title(title)
        self._queue = Queue()

        self._refresh_text = tk.StringVar()
        self._refresh_text.set("Refresh")
        self._gencode_text = tk.StringVar()
        self._attachfile_text = tk.StringVar()

        self._init_items()
        self._init_thread()

        self._lastx = 0
        self._lasty = 0
        self._bounds = None # crop area
        self._center = (0, 0) # center point
        self._offset = (0, 0) # offset to image center
        self._size = (90, 90)
        self._moved = False # click or click and move
        self._color = 'red' # draw color
        self._tkimage = None # keep reference
        self._image = None
        self._ratio = 0.5

    def _init_items(self):
        root = self._root
        root.resizable(0, 0)

        frm_control = tk.Frame(root, bg='#bbb')
        frm_control.grid(column=0, row=0, padx=5, sticky=tk.NW)
        frm_screen = tk.Frame(root, bg='#aaa')
        frm_screen.grid(column=1, row=0)

        frm_ctrl_btns = tk.Frame(frm_control)
        frm_ctrl_btns.grid(column=0, row=0, sticky=tk.W)
        tk.Label(frm_control, text='-'*30).grid(column=0, row=1, sticky=tk.EW)
        frm_ctrl_code = tk.Frame(frm_control)
        frm_ctrl_code.grid(column=0, row=2, sticky=tk.EW)

        tk.Button(frm_ctrl_btns, textvariable=self._refresh_text, command=self._redraw).grid(column=0, row=0, sticky=tk.W)
        tk.Button(frm_ctrl_btns, text="Wakeup", command=self._device.wakeup).grid(column=0, row=1, sticky=tk.W)
        tk.Button(frm_ctrl_btns, text="Save cropped", command=self._save_crop).grid(column=0, row=2, sticky=tk.W)
        tk.Button(frm_ctrl_btns, text="Save screenshot", command=self._save_screenshot).grid(column=0, row=3, sticky=tk.W)

        tk.Label(frm_ctrl_code, text='Generated code').grid(column=0, row=0, sticky=tk.W)
        tk.Entry(frm_ctrl_code, textvariable=self._gencode_text, width=30).grid(column=0, row=1, sticky=tk.W)
        tk.Button(frm_ctrl_code, text='Run code', command=self._run_code).grid(column=0, row=2, sticky=tk.W)
        tk.Button(frm_ctrl_code, text='Insert and Run', command=self._run_and_insert).grid(column=0, row=3, sticky=tk.W)
        tk.Button(frm_ctrl_code, text='Select File', command=self._run_selectfile).grid(column=0, row=4, sticky=tk.W)
        tk.Label(frm_ctrl_code, textvariable=self._attachfile_text).grid(column=0, row=5, sticky=tk.W)

        self.canvas = tk.Canvas(frm_screen, bg="blue", bd=0, highlightthickness=0, relief='ridge')
        self.canvas.grid(column=0, row=0, padx=10, pady=10)
        self.canvas.bind("<Button-1>", self._stroke_start)
        self.canvas.bind("<B1-Motion>", self._stroke_move)
        self.canvas.bind("<B1-ButtonRelease>", self._stroke_done)

    def _worker(self):
        que = self._queue
        while True:
            (func, args, kwargs) = que.get()
            try:
                func(*args, **kwargs)
            except Exception as e:
                print e
            finally:
                que.task_done()
    
    def _run_async(self, func, args=(), kwargs={}):
        self._queue.put((func, args, kwargs))

    def _init_thread(self):
        th = threading.Thread(name='thread', target=self._worker)
        th.daemon = True
        th.start()

    def _fix_bounds(self, bounds):
        bounds = [x/self._ratio for x in bounds]
        (x0, y0, x1, y1) = bounds
        if x0 > x1:
            x0, y0, x1, y1 = x1, y1, x0, y0
        # in case of out of bounds
        w, h = self._size
        x0 = max(0, x0)
        y0 = max(0, y0)
        x1 = min(w, x1)
        y1 = min(h, y1)
        return map(int, [x0, y0, x1, y1])

    def _save_screenshot(self):
        save_to = tkSimpleDialog.askstring("Save screenshot", "Enter filename")
        if not save_to:
            return
        if save_to.find('.') == -1:
            save_to += '.png'
        print('Save to:', save_to)
        self._image.save(save_to)    

    def _save_crop(self):
        print self._bounds
        if self._bounds is None:
            return
        bounds = self._fix_bounds(self._bounds)
        print bounds
        save_to = tkSimpleDialog.askstring("Save cropped image", "Enter filename")
        if save_to:
            if save_to.find('.') == -1:
                save_to += '.png'
            print('Save to:', save_to)
            self._image.crop(bounds).save(save_to)
            if self._offset == (0, 0):
                self._gencode_text.set('d.click_image("%s")' % save_to)
            else:
                code = 'd.click_image(atx.Pattern("{name}", offset=({x}, {y})))'.format(
                    name=save_to, x=self._offset[0], y=self._offset[1])
                self._gencode_text.set(code)

    def _run_code(self):
        code = 'self._device.'+self._gencode_text.get()
        exec(code)

    def _run_and_insert(self):
        self._run_code()
{'fraction_non_alphanumeric': 0.13786591123701605, 'fraction_numerical': 0.017426388531204394, 'mean_word_length': 2.464168896818317, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7166403', 'n_tokens_mistral': 4148, 'n_tokens_neox': 3988, 'n_words': 807}