#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# generated by wxGlade 0.9.6 on Wed Jul 22 19:31:45 2020
#
import threading
from copy import deepcopy
from math import ceil

import wx
from ..svgelements import Matrix, SVGImage

from ..image.imagetools import RasterScripts
from .icons import icons8_fantasy_50
from .laserrender import LaserRender
from .mwindow import MWindow
from .zmatrix import ZMatrix

_ = wx.GetTranslation


class RasterWizard(MWindow):
    def __init__(self, *args, script=None, **kwds):
        super().__init__(605, 636, *args, **kwds)
        if script is None:
            script = "Gravy"

        self._preview_panel_buffer = None

        self.matrix = Matrix()
        self.previous_window_position = None
        self.previous_scene_position = None

        self.svg_image = None
        self.pil_image = None
        self.matrix_image = None
        self.step_image = 1

        self.wx_bitmap_image = None
        self.image_width, self.image_height = None, None
        self.ops = dict()
        self.script = script
        self.selected_op = None
        self.wizard_thread = None
        self.needs_centering = True
        self.needs_update = True

        self.sizer_operation_panels = None

        self.panel_preview = wx.Panel(self, wx.ID_ANY)
        list_choices = []
        if self.ops is not None:
            list_choices = [_(op["name"]) for op in self.ops]
        self.list_operation = wx.ListBox(self, wx.ID_ANY, choices=list_choices)

        self.button_operations = wx.BitmapButton(
            self, wx.ID_ANY, icons8_fantasy_50.GetBitmap()
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_LISTBOX, self.on_list_operation, self.list_operation)
        self.Bind(wx.EVT_BUTTON, self.on_buttons_operations, self.button_operations)
        # end wxGlade

        self.panel_preview.Bind(wx.EVT_PAINT, self.on_preview_panel_paint)
        self.panel_preview.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)

        self.panel_preview.Bind(wx.EVT_MOTION, self.on_preview_mouse_move)
        self.panel_preview.Bind(wx.EVT_MOUSEWHEEL, self.on_preview_mousewheel)
        self.panel_preview.Bind(wx.EVT_MIDDLE_UP, self.on_preview_mouse_middle_up)
        self.panel_preview.Bind(wx.EVT_MIDDLE_DOWN, self.on_preview_mouse_middle_down)
        self.panel_preview.Bind(wx.EVT_LEFT_DOWN, self.on_preview_mouse_left_down)
        self.panel_preview.Bind(wx.EVT_LEFT_UP, self.on_preview_mouse_left_up)
        self.panel_preview.Bind(wx.EVT_RIGHT_DOWN, self.on_preview_mouse_right_down)
        self.panel_preview.Bind(
            wx.EVT_ENTER_WINDOW, lambda event: self.panel_preview.SetFocus()
        )  # Focus follows mouse.

        self.on_size(None)
        self.Bind(wx.EVT_SIZE, self.on_size, self)
        self.thread_update_lock = threading.Lock()

    def set_wizard_script(self, name=None, ops=None):
        if name is None:
            if ops is None:
                return
            self.ops = ops
        else:
            self.ops = deepcopy(
                self.context._kernel.registered["raster_script/%s" % name]
            )
        self.list_operation.Clear()
        if self.ops is not None:
            list_choices = [_(op["name"]) for op in self.ops]
            for c in list_choices:
                self.list_operation.Append(c)
        self.needs_update = True
        self.wiz_img()
        self.Layout()
        self.Refresh()
        self.on_size()

    def restore(self, *args, script=None, **kwargs):
        if script is not None:
            self.script = script
            self.set_wizard_script(script)

    def window_open(self):
        if self.script is not None:
            self.set_wizard_script(self.script)

        context_root = self.context.get_context("/")
        context_root.listen("emphasized", self.on_emphasis_change)
        self.context.listen(
            "RasterWizard-Refresh", self.on_raster_wizard_refresh_signal
        )
        self.context.listen("RasterWizard-Image", self.on_raster_wizard_image_signal)
        self.context.signal("RasterWizard-Image")

    def window_close(self):
        context_root = self.context.get_context("/")
        context_root.unlisten("emphasized", self.on_emphasis_change)
        self.context.unlisten(
            "RasterWizard-Refresh", self.on_raster_wizard_refresh_signal
        )
        self.context.unlisten("RasterWizard-Image", self.on_raster_wizard_image_signal)

    def __set_properties(self):
        _icon = wx.NullIcon
        _icon.CopyFromBitmap(icons8_fantasy_50.GetBitmap())
        self.SetIcon(_icon)
        # begin wxGlade: RasterWizard.__set_properties
        self.SetTitle(_("Raster Wizard"))
        self.panel_preview.SetToolTip(_("Processed image preview"))
        self.list_operation.SetToolTip(
            _("Image operations applied in order to generate a raster image.")
        )
        self.button_operations.SetBackgroundColour(wx.Colour(0, 255, 0))
        self.button_operations.SetToolTip(_("Process Image and Export"))
        self.button_operations.SetSize(self.button_operations.GetBestSize())

        self.panel_select_op()
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: RasterWizard.__do_layout
        sizer_frame = wx.BoxSizer(wx.VERTICAL)
        sizer_main = wx.BoxSizer(wx.HORIZONTAL)
        self.sizer_operation_panels = wx.BoxSizer(wx.VERTICAL)
        sizer_list = wx.BoxSizer(wx.VERTICAL)
        sizer_frame.Add(self.panel_preview, 2, wx.EXPAND, 0)
        sizer_list.Add(self.list_operation, 1, wx.EXPAND, 0)
        sizer_list.Add(self.button_operations, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        w, h = self.button_operations.Size
        self.list_operation.SetMinSize(
            (-1, 301 - h)
        )  # 301 is the height of Tone Panel.
        self.list_operation.SetMaxSize((-1, 301 - h))
        sizer_main.Add(sizer_list, 0, wx.EXPAND, 0)

        sizer_main.Add(self.sizer_operation_panels, 1, wx.EXPAND, 0)
        sizer_frame.Add(sizer_main, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_frame)
        self.Layout()
        # end wxGlade

    def wiz_img(self):
        if self.svg_image is None:
            with self.thread_update_lock:
                self.wizard_thread = None
            return
        while self.needs_update:
            self.needs_update = False
            if self.ops is None:
                self.pil_image = self.svg_image.image
            else:
                self.pil_image, self.matrix_image, step = RasterScripts.wizard_image(
                    self.svg_image, self.ops
                )
                if step is not None:
                    self.step_image = step
            self.wx_bitmap_image = None
            if self.context is None:
                with self.thread_update_lock:
                    self.wizard_thread = None
                return
            self.context.signal("RasterWizard-Refresh")
        if self.pil_image is not None and self.needs_centering:
            self.focus_viewport_scene(
                self.pil_image.getbbox(), self._preview_panel_buffer.Size
            )
            self.needs_centering = False
        with self.thread_update_lock:
            self.wizard_thread = None

    def on_emphasis_change(self, *args):
        for e in self.context.elements.elems(emphasized=True):
            if isinstance(e, SVGImage):
                self.svg_image = e
                self.pil_image = None
                self.matrix_image = e.transform
                try:
                    self.step_image = e.values["raster_step"]
                except KeyError:
                    self.step_image = 1
                self.context.signal("RasterWizard-Image")
                if self.ops is not None:
                    self.panel_select_op()
                self.needs_centering = True
                break

    def panel_select_op(self):
        if self.sizer_operation_panels is None:
            return
        self.sizer_operation_panels.Clear(True)

        select = self.list_operation.GetSelection()
        try:
            self.selected_op = self.ops[select]
        except KeyError:
            pass
        op = self.selected_op
        name_op = op["name"]
        panel = None
        if name_op == "crop":
            panel = CropPanel(self, wx.ID_ANY)
        elif name_op == "resample":
            panel = ResamplePanel(self, wx.ID_ANY)
        elif name_op == "grayscale":
            panel = GrayscalePanel(self, wx.ID_ANY)
        elif name_op == "tone":
            panel = ToneCurvePanel(self, wx.ID_ANY)
        elif name_op == "gamma":
            panel = GammaPanel(self, wx.ID_ANY)
        elif name_op == "unsharp_mask":
            panel = SharpenPanel(self, wx.ID_ANY)
        elif name_op == "dither":
            panel = DitherPanel(self, wx.ID_ANY)
        elif name_op == "output":
            panel = OutputPanel(self, wx.ID_ANY)
        elif name_op == "contrast":
            panel = ContrastPanel(self, wx.ID_ANY)
        elif name_op == "halftone":
            panel = HalftonePanel(self, wx.ID_ANY)
        else:
            panel = BasicPanel(self, wx.ID_ANY)
        if panel is None:
            return
        self.sizer_operation_panels.Add(panel, 1, wx.EXPAND, 0)
        panel.set_operation(self.context, op, svg_image=self.svg_image)
        self.Layout()

    def on_size(self, event=None):
        self.Layout()
        width, height = self.panel_preview.Size
        if width <= 0:
            width = 1
        if height <= 0:
            height = 1
        self._preview_panel_buffer = wx.Bitmap(width, height)
        self.update_in_gui_thread()
        self.Layout()
        self.Refresh()
        self.Update()

    def on_preview_panel_paint(self, event):
        try:
            wx.BufferedPaintDC(self.panel_preview, self._preview_panel_buffer)
        except RuntimeError:
            pass

    def update_in_gui_thread(self):
        self.on_update_buffer()
        try:
            self.Refresh(True)
            self.Update()
        except RuntimeError:
            pass

    def on_update_buffer(self, event=None):
        if self.context is None or self.svg_image is None or self.pil_image is None:
            dc = wx.MemoryDC()
            dc.SelectObject(self._preview_panel_buffer)
            dc.Clear()
            gc = wx.GraphicsContext.Create(dc)
            gc.SetBrush(wx.WHITE_BRUSH)
            w, h = self._preview_panel_buffer.GetSize()
            gc.DrawRectangle(0, 0, w, h)
            font = wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)
            gc.SetFont(font, wx.BLACK)
            if self.wizard_thread is not None and self.wizard_thread.is_alive():
                gc.DrawText(_("Processing..."), 0, 0)
            else:
                gc.DrawText(_("No image..."), 0, 0)
            gc.Destroy()
            return
        dc = wx.MemoryDC()
        dc.SelectObject(self._preview_panel_buffer)
        dc.Clear()
        gc = wx.GraphicsContext.Create(dc)
        gc.PushState()
        gc.SetTransform(wx.GraphicsContext.CreateMatrix(gc, ZMatrix(self.matrix)))
        wx_bitmap = self.wx_bitmap_image
        if wx_bitmap is None:
            renderer = LaserRender(self.context)
            self.wx_bitmap_image = renderer.make_thumbnail(self.pil_image)
        width, height = self.pil_image.size
        gc.DrawBitmap(self.wx_bitmap_image, 0, 0, width, height)
        gc.PopState()
        font = wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)
        gc.SetFont(font, wx.BLACK)
        if self.wizard_thread is not None:
            gc.DrawText(_("Processing..."), 0, 0)
        gc.Destroy()
        del dc

    def convert_scene_to_window(self, position):
        point = self.matrix.point_in_matrix_space(position)
        return point[0], point[1]

    def convert_window_to_scene(self, position):
        point = self.matrix.point_in_inverse_space(position)
        return point[0], point[1]

    def on_preview_mouse_move(self, event):
        if self.previous_window_position is None:
            return
        pos = event.GetPosition()
        window_position = pos.x, pos.y
        scene_position = self.convert_window_to_scene(
            [window_position[0], window_position[1]]
        )
        sdx = scene_position[0] - self.previous_scene_position[0]
        sdy = scene_position[1] - self.previous_scene_position[1]
        wdx = window_position[0] - self.previous_window_position[0]
        wdy = window_position[1] - self.previous_window_position[1]
        self.scene_post_pan(wdx, wdy)
        self.previous_window_position = window_position
        self.previous_scene_position = scene_position

    def on_preview_mousewheel(self, event):
        rotation = event.GetWheelRotation()
        mouse = event.GetPosition()
        if self.context.mouse_zoom_invert:
            rotation = -rotation
        if rotation > 1:
            self.scene_post_scale(1.1, 1.1, mouse[0], mouse[1])
        elif rotation < -1:
            self.scene_post_scale(0.9, 0.9, mouse[0], mouse[1])

    def on_preview_mouse_right_down(self, event):
        gui = self
        menu = wx.Menu()
        sub_menu = wx.Menu()
        try:
            for script_name in self.context.match("raster_script", True):
                gui.Bind(
                    wx.EVT_MENU,
                    self.set_script(script_name),
                    sub_menu.Append(wx.ID_ANY, script_name, "", wx.ITEM_NORMAL),
                )
            menu.Append(wx.ID_ANY, _("Raster Script"), sub_menu)
        except KeyError:
            pass
        if menu.MenuItemCount != 0:
            gui.PopupMenu(menu)
            menu.Destroy()

    def set_script(self, name):
        def script(event):
            self.set_wizard_script(name)

        return script

    def on_preview_mouse_left_down(self, event):
        self.previous_window_position = event.GetPosition()
        self.previous_scene_position = self.convert_window_to_scene(
            self.previous_window_position
        )

    def on_preview_mouse_left_up(self, event):
        self.previous_window_position = None
        self.previous_scene_position = None

    def on_preview_mouse_middle_down(self, event):
        self.previous_window_position = event.GetPosition()
        self.previous_scene_position = self.convert_window_to_scene(
            self.previous_window_position
        )

    def on_preview_mouse_middle_up(self, event):
        self.previous_window_position = None
        self.previous_scene_position = None

    def focus_viewport_scene(
        self, new_scene_viewport, scene_size, buffer=0.0, lock=True
    ):
        """
        Focus on the given viewport in the scene.

        :param new_scene_viewport: Viewport to have after this process within the scene.
        :param scene_size: Size of the scene in which this viewport is active.
        :param buffer: Amount of buffer around the edge of the new viewport.
        :param lock: lock the scalex, scaley.
        :return:
        """
        window_width, window_height = scene_size
        left = new_scene_viewport[0]
        top = new_scene_viewport[1]
        right = new_scene_viewport[2]
        bottom = new_scene_viewport[3]
        viewport_width = right - left
        viewport_height = bottom - top

        left -= viewport_width * buffer
        right += viewport_width * buffer
        top -= viewport_height * buffer
        bottom += viewport_height * buffer

        if right == left:
            scale_x = 100
        else:
            scale_x = window_width / float(right - left)
        if bottom == top:
            scale_y = 100
        else:
            scale_y = window_height / float(bottom - top)

        cx = (right + left) / 2
        cy = (top + bottom) / 2
        self.matrix.reset()
        self.matrix.post_translate(-cx, -cy)
        if lock:
            scale = min(scale_x, scale_y)
            if scale != 0:
                self.matrix.post_scale(scale)
        else:
            if scale_x != 0 and scale_y != 0:
                self.matrix.post_scale(scale_x, scale_y)
        self.matrix.post_translate(window_width / 2.0, window_height / 2.0)

    def scene_post_pan(self, px, py):
        self.matrix.post_translate(px, py)
        self.context.signal("RasterWizard-Refresh")

    def scene_post_scale(self, sx, sy=None, ax=0, ay=0):
        self.matrix.post_scale(sx, sy, ax, ay)
        self.context.signal("RasterWizard-Refresh")

    def on_raster_wizard_image_signal(self, *args):
        """Processes the refresh. Runs through a signal to prevent mass refresh stacking."""
        with self.thread_update_lock:
            self.needs_update = True
            if self.wizard_thread is None:
                self.wizard_thread = self.context._kernel.threaded(self.wiz_img)
                self.context.signal("RasterWizard-Refresh")

    def on_raster_wizard_refresh_signal(self, *args):
        """Processes the refresh. Runs through a signal to prevent mass refresh stacking."""
        if wx.IsMainThread():
            self.update_in_gui_thread()
        else:
            wx.CallAfter(self.update_in_gui_thread)

    def on_list_operation(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.panel_select_op()

    def on_buttons_operations(self, event):  # wxGlade: RasterWizard.<event_handler>
        if self.wizard_thread is not None:
            return
        if self.svg_image is not None:
            self.svg_image.image = self.pil_image
            self.svg_image.values["raster_step"] = self.step_image
            self.svg_image.transform = self.matrix_image
            (
                self.svg_image.image_width,
                self.svg_image.image_height,
            ) = self.pil_image.size
            self.svg_image.lock = True
            try:
                self.svg_image.node.object = self.svg_image
                self.svg_image.node.altered()
            except AttributeError:
                pass
        self.Close()


# end of class RasterWizard


class DitherPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: DitherPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_dither = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.combo_dither = wx.ComboBox(
            self,
            wx.ID_ANY,
            choices=[
                "Floyd-Steinberg",
                "Jarvis, Judice, Ninke",
                "Stucki",
                "Atkinson",
                "Burkes",
                "Sierra",
                "Ordered 4x4",
                "Ordered 8x8",
            ],
            style=wx.CB_DROPDOWN,
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_dither, self.check_enable_dither
        )
        self.Bind(wx.EVT_COMBOBOX, self.on_combo_dither_type, self.combo_dither)
        self.Bind(wx.EVT_TEXT_ENTER, self.on_combo_dither_type, self.combo_dither)
        self.context = None
        self.op = None
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: DitherPanel.__set_properties
        self.check_enable_dither.SetToolTip(_("Enable Dither"))
        self.check_enable_dither.SetValue(1)
        self.combo_dither.SetToolTip(_("Select dither algorithm to use"))
        self.combo_dither.SetSelection(0)
        self.combo_dither.Enable(False)
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: DitherPanel.__do_layout
        sizer_dither_main = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Dither")), wx.VERTICAL
        )
        sizer_dither_main.Add(self.check_enable_dither, 0, 0, 0)
        sizer_dither_main.Add(self.combo_dither, 0, 0, 0)
        self.SetSizer(sizer_dither_main)
        sizer_dither_main.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_dither.SetValue(op["enable"])
        self.combo_dither.SetSelection(op["type"])

    def on_check_enable_dither(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["enable"] = self.check_enable_dither.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_combo_dither_type(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["type"] = self.combo_dither.GetSelection()
        self.context.signal("RasterWizard-Image")


# end of class DitherPanel


class CropPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: CropPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self._crop_panel_buffer = None
        self.check_enable_crop = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.button_reset_crop = wx.Button(self, wx.ID_ANY, _("Reset"))
        self.image_view_panel = wx.Panel(self, wx.ID_ANY)

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_CHECKBOX, self.on_check_enable_crop, self.check_enable_crop)
        self.Bind(wx.EVT_BUTTON, self.on_button_reset_crop, self.button_reset_crop)
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: CropPanel.__set_properties
        self.check_enable_crop.SetToolTip(_("Enable Cropping"))
        self.check_enable_crop.SetValue(1)
        self.button_reset_crop.SetToolTip(_("Reset Cropping"))
        self.image_view_panel.SetToolTip(_("Crop field"))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: CropPanel.__do_layout
        sizer_crop = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Crop")), wx.VERTICAL
        )
        sizer_crop_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_crop_main.Add(self.check_enable_crop, 0, 0, 0)
        sizer_crop_main.Add(self.button_reset_crop, 0, 0, 0)
        sizer_crop.Add(sizer_crop_main, 0, wx.EXPAND, 0)
        sizer_crop.Add(self.image_view_panel, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_crop)
        sizer_crop.Fit(self)
        self.Layout()
        # end wxGlade

    def update_in_gui_thread(self):
        # self.on_update_buffer()
        # self.on_update_tone()
        try:
            self.Refresh(True)
            self.Update()
        except RuntimeError:
            pass

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_crop.SetValue(op["enable"])
        self.Layout()
        width, height = self.image_view_panel.Size
        if width <= 0:
            width = 1
        if height <= 0:
            height = 1
        self._crop_panel_buffer = wx.Bitmap(width, height)
        self.update_in_gui_thread()

        self.check_enable_crop.SetValue(op["enable"])

    def on_check_enable_crop(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["enable"] = self.check_enable_crop.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_button_reset_crop(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["bounds"] = (0, 0, 100, 100)
        self.context.signal("RasterWizard-Image")


# end of class CropPanel


class ResamplePanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: ResamplePanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_resample = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.text_resample_width = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.check_resample_maintain_aspect = wx.CheckBox(
            self, wx.ID_ANY, _("Maintain Aspect Ratio")
        )
        self.text_resample_height = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.combo_resample_units = wx.ComboBox(
            self,
            wx.ID_ANY,
            choices=[_("pixels"), _("percent"), _("inches"), _("mm"), _("cm")],
            style=wx.CB_DROPDOWN,
        )
        self.text_resample_pixels = wx.TextCtrl(
            self, wx.ID_ANY, "1000 x 1000 pixels", style=wx.TE_READONLY
        )
        self.combo_resample_step = wx.ComboBox(
            self,
            wx.ID_ANY,
            choices=["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
            style=wx.CB_DROPDOWN,
        )
        self.combo_resample_dpi = wx.ComboBox(
            self,
            wx.ID_ANY,
            choices=[
                "1000",
                "500",
                "333",
                "250",
                "200",
                "167",
                "143",
                "125",
                "111",
                "100",
            ],
            style=wx.CB_DROPDOWN,
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_resample, self.check_enable_resample
        )
        self.Bind(wx.EVT_TEXT, self.on_text_resample_width, self.text_resample_width)
        self.Bind(
            wx.EVT_TEXT_ENTER, self.on_text_resample_width, self.text_resample_width
        )
        self.Bind(
            wx.EVT_CHECKBOX,
            self.on_check_resample_maintain_aspect,
            self.check_resample_maintain_aspect,
        )
        self.Bind(wx.EVT_TEXT, self.on_text_resample_height, self.text_resample_height)
        self.Bind(
            wx.EVT_TEXT_ENTER, self.on_text_resample_height, self.text_resample_height
        )
        self.Bind(
            wx.EVT_COMBOBOX, self.on_combo_resample_units, self.combo_resample_units
        )
        self.Bind(
            wx.EVT_COMBOBOX, self.on_combo_resample_step, self.combo_resample_step
        )
        self.Bind(
            wx.EVT_TEXT_ENTER, self.on_combo_resample_step, self.combo_resample_step
        )
        self.Bind(wx.EVT_COMBOBOX, self.on_combo_resample_dpi, self.combo_resample_dpi)
        self.Bind(
            wx.EVT_TEXT_ENTER, self.on_combo_resample_dpi, self.combo_resample_dpi
        )
        # end wxGlade
        self.context = None
        self.op = None
        self.svg_image = None

    def __set_properties(self):
        # begin wxGlade: ResamplePanel.__set_properties
        self.check_enable_resample.SetToolTip(_("Enable Resampling"))
        self.check_enable_resample.SetValue(1)
        self.text_resample_width.SetToolTip(_("Image Width"))
        self.check_resample_maintain_aspect.SetToolTip(
            _("Maintain Aspect Ratio for Resample")
        )
        self.check_resample_maintain_aspect.SetValue(1)
        self.text_resample_height.SetToolTip(_("Image Height"))
        self.combo_resample_units.SetSelection(0)
        self.combo_resample_step.SetToolTip(_("Image resample step"))
        self.combo_resample_step.SetSelection(1)
        self.combo_resample_dpi.SetToolTip(_("Image resample DPI at given step"))
        self.combo_resample_dpi.SetSelection(1)
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: ResamplePanel.__do_layout
        sizer_resample = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Resample")), wx.VERTICAL
        )
        sizer_resample_step = wx.BoxSizer(wx.HORIZONTAL)
        sizer_resample_height = wx.BoxSizer(wx.HORIZONTAL)
        sizer_resample_width = wx.BoxSizer(wx.HORIZONTAL)
        sizer_resample_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_resample_main.Add(self.check_enable_resample, 0, 0, 0)
        sizer_resample.Add(sizer_resample_main, 0, wx.EXPAND, 0)
        label_width = wx.StaticText(self, wx.ID_ANY, _("Width"))
        label_width.SetMinSize((50, 16))
        sizer_resample_width.Add(label_width, 0, 0, 0)
        sizer_resample_width.Add(self.text_resample_width, 0, 0, 0)
        sizer_resample_width.Add(self.check_resample_maintain_aspect, 0, 0, 0)
        sizer_resample.Add(sizer_resample_width, 0, wx.EXPAND, 0)
        label_height = wx.StaticText(self, wx.ID_ANY, _("Height"))
        label_height.SetMinSize((50, 16))
        sizer_resample_height.Add(label_height, 0, 0, 0)
        sizer_resample_height.Add(self.text_resample_height, 0, 0, 0)
        sizer_resample_height.Add(self.combo_resample_units, 0, 0, 0)
        sizer_resample.Add(sizer_resample_height, 0, wx.EXPAND, 0)
        sizer_resample.Add(self.text_resample_pixels, 0, 0, 0)
        sizer_resample.Add((20, 20), 0, 0, 0)
        label_step = wx.StaticText(self, wx.ID_ANY, _("Step"))
        label_step.SetMinSize((50, 16))
        sizer_resample_step.Add(label_step, 0, 0, 0)
        sizer_resample_step.Add(self.combo_resample_step, 0, 0, 0)
        sizer_resample_step.Add(self.combo_resample_dpi, 0, 0, 0)
        label_ppi = wx.StaticText(self, wx.ID_ANY, _("pixels/in"))
        sizer_resample_step.Add(label_ppi, 11, 0, 0)
        sizer_resample.Add(sizer_resample_step, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_resample)
        sizer_resample.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.svg_image = svg_image
        self.check_enable_resample.SetValue(op["enable"])
        self.combo_resample_step.SetSelection(op["step"] - 1)
        self.combo_resample_dpi.SetSelection(op["step"] - 1)
        self.combo_resample_units.SetSelection(op["units"])
        self.check_resample_maintain_aspect.SetValue(op["aspect"])
        self.refresh_dims()
        if svg_image is not None:
            self.text_resample_pixels.SetValue(
                "%d x %d pixels" % (svg_image.image_height, svg_image.image_width)
            )

    def refresh_dims(self):
        if self.svg_image is None:
            return
        image = self.svg_image.image
        matrix = Matrix(self.svg_image.transform)
        try:
            step = self.svg_image.values["raster_step"]
        except KeyError:
            step = 1
        boundary_points = []
        box = image.getbbox()
        top_left = matrix.point_in_matrix_space([box[0], box[1]])
        top_right = matrix.point_in_matrix_space([box[2], box[1]])
        bottom_left = matrix.point_in_matrix_space([box[0], box[3]])
        bottom_right = matrix.point_in_matrix_space([box[2], box[3]])
        boundary_points.append(top_left)
        boundary_points.append(top_right)
        boundary_points.append(bottom_left)
        boundary_points.append(bottom_right)
        xmin = min([e[0] for e in boundary_points])
        ymin = min([e[1] for e in boundary_points])
        xmax = max([e[0] for e in boundary_points])
        ymax = max([e[1] for e in boundary_points])
        bbox = xmin, ymin, xmax, ymax

        tx = bbox[0]
        ty = bbox[1]
        px_width = int(ceil(bbox[2] - bbox[0]))
        px_height = int(ceil(bbox[3] - bbox[1]))

        px_width *= step
        px_height *= step

        units = self.op["units"]
        width = str(px_width)
        height = str(px_height)
        if units == 1:
            width = "100"
            height = "100"
        elif units == 2:
            px_width /= 1000.0
            px_height /= 1000.0
            width = str(px_width)
            height = str(px_height)
        elif units == 3:
            px_width /= 39.3701
            px_height /= 39.3701
            width = str(px_width)
            height = str(px_height)
        elif units == 4:
            px_width /= 393.701
            px_height /= 393.701
            width = str(px_width)
            height = str(px_height)
        self.text_resample_height.SetValue(width)
        self.text_resample_width.SetValue(height)

    def on_check_enable_resample(self, event):  # wxGlade: ResamplePanel.<event_handler>
        self.op["enable"] = self.check_enable_resample.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_text_resample_width(self, event):  # wxGlade: ResamplePanel.<event_handler>
        pass
        # self.kernel.signal("RasterWizard-Image")

    def on_check_resample_maintain_aspect(
        self, event
    ):  # wxGlade: ResamplePanel.<event_handler>
        self.op["aspect"] = self.check_resample_maintain_aspect.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_text_resample_height(self, event):  # wxGlade: ResamplePanel.<event_handler>
        pass
        # self.kernel.signal("RasterWizard-Image")

    def on_combo_resample_units(self, event):  # wxGlade: ResamplePanel.<event_handler>
        self.op["units"] = self.combo_resample_units.GetSelection()
        self.refresh_dims()

    def on_combo_resample_step(self, event):  # wxGlade: ResamplePanel.<event_handler>
        if self.combo_resample_step.GetSelection() != self.op["step"] + 1:
            self.combo_resample_dpi.SetSelection(
                self.combo_resample_step.GetSelection()
            )
            self.op["step"] = self.combo_resample_step.GetSelection() + 1
            self.context.signal("RasterWizard-Image")

    def on_combo_resample_dpi(self, event):  # wxGlade: ResamplePanel.<event_handler>
        if (
            self.combo_resample_dpi.GetSelection()
            != self.combo_resample_step.GetSelection()
        ):
            self.combo_resample_step.SetSelection(
                self.combo_resample_dpi.GetSelection()
            )


# end of class ResamplePanel


class GammaPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: GammaPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_gamma = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.button_reset_gamma = wx.Button(self, wx.ID_ANY, _("Reset"))
        self.slider_gamma_factor = wx.Slider(
            self, wx.ID_ANY, 100, 0, 500, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_gamma_factor = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_READONLY)

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_CHECKBOX, self.on_check_enable_gamma, self.check_enable_gamma)
        self.Bind(wx.EVT_BUTTON, self.on_button_reset_gamma, self.button_reset_gamma)
        self.Bind(wx.EVT_SLIDER, self.on_slider_gamma_factor, self.slider_gamma_factor)
        self.Bind(wx.EVT_TEXT, self.on_text_gamma_factor, self.text_gamma_factor)
        # end wxGlade
        self.context = None
        self.op = None
        self.last_x = None

    def __set_properties(self):
        # begin wxGlade: GammaPanel.__set_properties
        self.check_enable_gamma.SetToolTip(_("Enable Gamma Shift"))
        self.check_enable_gamma.SetValue(1)
        self.button_reset_gamma.SetToolTip(_("Reset Gamma Shift"))
        self.slider_gamma_factor.SetToolTip(_("Gamma factor slider"))
        self.text_gamma_factor.SetToolTip(_("Amount of gamma factor"))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: GammaPanel.__do_layout
        sizer_gamma = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Gamma")), wx.VERTICAL
        )
        sizer_gamma_factor = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Gamma Factor")), wx.HORIZONTAL
        )
        sizer_gamma_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_gamma_main.Add(self.check_enable_gamma, 0, 0, 0)
        sizer_gamma_main.Add(self.button_reset_gamma, 0, 0, 0)
        sizer_gamma.Add(sizer_gamma_main, 0, wx.EXPAND, 0)
        sizer_gamma_factor.Add(self.slider_gamma_factor, 5, wx.EXPAND, 0)
        sizer_gamma_factor.Add(self.text_gamma_factor, 1, 0, 0)
        sizer_gamma.Add(sizer_gamma_factor, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_gamma)
        sizer_gamma.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.text_gamma_factor.SetValue(str(op["factor"]))
        self.slider_gamma_factor.SetValue(op["factor"] * 100.0)
        self.check_enable_gamma.SetValue(op["enable"])

    def on_check_enable_gamma(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["enable"] = self.check_enable_gamma.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_button_reset_gamma(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["factor"] = 3.5
        self.slider_gamma_factor.SetValue(self.op["factor"] * 100.0)
        self.text_gamma_factor.SetValue(str(self.op["factor"]))
        self.context.signal("RasterWizard-Image")

    def on_slider_gamma_factor(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["factor"] = self.slider_gamma_factor.GetValue() / 100.0
        self.text_gamma_factor.SetValue(str(self.op["factor"]))
        self.context.signal("RasterWizard-Image")

    def on_text_gamma_factor(self, event):  # wxGlade: RasterWizard.<event_handler>
        pass


# end of class GammaPanel


class GrayscalePanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: GrayscalePanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_grayscale = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.check_invert_grayscale = wx.CheckBox(self, wx.ID_ANY, _("Invert"))
        self.slider_grayscale_red = wx.Slider(
            self, wx.ID_ANY, 0, -1000, 1000, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_grayscale_red = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_READONLY)
        self.slider_grayscale_green = wx.Slider(
            self, wx.ID_ANY, 0, -1000, 1000, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_grayscale_green = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_grayscale_blue = wx.Slider(
            self, wx.ID_ANY, 0, -1000, 1000, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_grayscale_blue = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_grayscale_lightness = wx.Slider(
            self, wx.ID_ANY, 500, 0, 1000, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_grayscale_lightness = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_grayscale, self.check_enable_grayscale
        )
        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_invert_grayscale, self.check_invert_grayscale
        )
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_grayscale_component,
            self.slider_grayscale_lightness,
        )
        self.Bind(
            wx.EVT_SLIDER, self.on_slider_grayscale_component, self.slider_grayscale_red
        )
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_grayscale_component,
            self.slider_grayscale_green,
        )
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_grayscale_component,
            self.slider_grayscale_blue,
        )
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: GrayscalePanel.__set_properties
        self.check_enable_grayscale.SetToolTip(_("Enable Grayscale Convert"))
        self.check_enable_grayscale.SetValue(1)
        self.check_invert_grayscale.SetToolTip(_("Invert Grayscale"))
        self.slider_grayscale_red.SetToolTip(_("Red component amount"))
        self.text_grayscale_red.SetToolTip(_("Red Factor"))
        self.slider_grayscale_green.SetToolTip(_("Green component control"))
        self.text_grayscale_green.SetToolTip(_("Green Factor"))
        self.slider_grayscale_blue.SetToolTip(_("Blue component control"))
        self.text_grayscale_blue.SetToolTip(_("Blue Factor"))
        # end wxGlade

    def __do_layout(self):
        sizer_grayscale = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Grayscale")), wx.VERTICAL
        )
        sizer_grayscale_lightness = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Lightness")), wx.HORIZONTAL
        )
        sizer_grayscale_blue = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Blue")), wx.HORIZONTAL
        )
        sizer_grayscale_green = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Green")), wx.HORIZONTAL
        )
        sizer_grayscale_red = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Red")), wx.HORIZONTAL
        )
        sizer_grayscale.Add(self.check_enable_grayscale, 0, 0, 0)
        sizer_grayscale.Add(self.check_invert_grayscale, 0, 0, 0)
        sizer_grayscale_red.Add(self.slider_grayscale_red, 5, wx.EXPAND, 0)
        sizer_grayscale_red.Add(self.text_grayscale_red, 1, 0, 0)
        sizer_grayscale.Add(sizer_grayscale_red, 0, wx.EXPAND, 0)
        sizer_grayscale_green.Add(self.slider_grayscale_green, 5, wx.EXPAND, 0)
        sizer_grayscale_green.Add(self.text_grayscale_green, 1, 0, 0)
        sizer_grayscale.Add(sizer_grayscale_green, 0, wx.EXPAND, 0)
        sizer_grayscale_blue.Add(self.slider_grayscale_blue, 5, wx.EXPAND, 0)
        sizer_grayscale_blue.Add(self.text_grayscale_blue, 1, 0, 0)
        sizer_grayscale.Add(sizer_grayscale_blue, 0, wx.EXPAND, 0)
        sizer_grayscale_lightness.Add(self.slider_grayscale_lightness, 5, wx.EXPAND, 0)
        sizer_grayscale_lightness.Add(self.text_grayscale_lightness, 1, 0, 0)
        sizer_grayscale.Add(sizer_grayscale_lightness, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_grayscale)
        sizer_grayscale.Fit(self)
        self.Layout()

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_grayscale.SetValue(op["enable"])
        self.check_invert_grayscale.SetValue(op["invert"])

        self.slider_grayscale_red.SetValue(int(op["red"] * 500.0))
        self.text_grayscale_red.SetValue(str(self.op["red"]))

        self.slider_grayscale_green.SetValue(int(op["green"] * 500.0))
        self.text_grayscale_green.SetValue(str(self.op["green"]))

        self.slider_grayscale_blue.SetValue(int(op["blue"] * 500.0))
        self.text_grayscale_blue.SetValue(str(self.op["blue"]))

        self.slider_grayscale_lightness.SetValue(int(op["lightness"] * 500.0))
        self.text_grayscale_lightness.SetValue(str(self.op["lightness"]))

    def on_check_enable_grayscale(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["enable"] = self.check_enable_grayscale.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_check_invert_grayscale(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["invert"] = self.check_invert_grayscale.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_slider_grayscale_component(
        self, event
    ):  # wxGlade: GrayscalePanel.<event_handler>
        self.op["red"] = float(int(self.slider_grayscale_red.GetValue()) / 500.0)
        self.text_grayscale_red.SetValue(str(self.op["red"]))

        self.op["green"] = float(int(self.slider_grayscale_green.GetValue()) / 500.0)
        self.text_grayscale_green.SetValue(str(self.op["green"]))

        self.op["blue"] = float(int(self.slider_grayscale_blue.GetValue()) / 500.0)
        self.text_grayscale_blue.SetValue(str(self.op["blue"]))

        self.op["lightness"] = float(
            int(self.slider_grayscale_lightness.GetValue()) / 500.0
        )
        self.text_grayscale_lightness.SetValue(str(self.op["lightness"]))

        self.context.signal("RasterWizard-Image")


# end of class GrayscalePanel


class ToneCurvePanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: ToneCurvePanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self._tone_panel_buffer = None
        self.check_enable_tone = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.button_reset_tone = wx.Button(self, wx.ID_ANY, _("Reset"))
        self.curve_panel = wx.Panel(self, wx.ID_ANY)

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_CHECKBOX, self.on_check_enable_tone, self.check_enable_tone)
        self.Bind(wx.EVT_BUTTON, self.on_button_reset_tone, self.button_reset_tone)
        # end wxGlade
        self.curve_panel.Bind(wx.EVT_PAINT, self.on_tone_panel_paint)
        self.curve_panel.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)
        self.curve_panel.Bind(wx.EVT_MOTION, self.on_curve_mouse_move)
        self.curve_panel.Bind(wx.EVT_LEFT_DOWN, self.on_curve_mouse_left_down)
        self.curve_panel.Bind(wx.EVT_LEFT_UP, self.on_curve_mouse_left_up)
        self.context = None
        self.op = None
        self.point = -1

    def __set_properties(self):
        # begin wxGlade: ToneCurvePanel.__set_properties
        self.check_enable_tone.SetToolTip(_("Enable Tone Curve"))
        self.check_enable_tone.SetValue(1)
        self.button_reset_tone.SetToolTip(_("Reset Tone Curve"))
        self.curve_panel.SetMinSize((256, 256))
        self.curve_panel.SetBackgroundColour(wx.Colour(255, 255, 255))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: ToneCurvePanel.__do_layout
        sizer_tone = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Tone Curve")), wx.VERTICAL
        )
        sizer_tone_curve = wx.BoxSizer(wx.HORIZONTAL)
        sizer_tone_curve.Add(self.check_enable_tone, 0, 0, 0)
        sizer_tone_curve.Add(self.button_reset_tone, 0, 0, 0)
        sizer_tone.Add(sizer_tone_curve, 0, wx.EXPAND, 0)
        sizer_tone.Add(self.curve_panel, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_tone)
        sizer_tone.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_tone.SetValue(op["enable"])
        self.Layout()
        width, height = self.curve_panel.Size
        if width <= 0:
            width = 1
        if height <= 0:
            height = 1
        self._tone_panel_buffer = wx.Bitmap(width, height)
        self.update_in_gui_thread()

    def update_in_gui_thread(self):
        self.on_update_tone()
        try:
            self.Refresh(True)
            self.Update()
        except RuntimeError:
            pass

    def on_tone_panel_paint(self, event):
        try:
            wx.BufferedPaintDC(self.curve_panel, self._tone_panel_buffer)
        except RuntimeError:
            pass

    def on_curve_mouse_move(self, event):
        if self.curve_panel.HasCapture():
            pos = event.GetPosition()
            try:
                v = 255 - pos[1]
                if self.op["type"] == "point":
                    current_x = pos[0]
                    if 0 <= current_x <= 255:
                        self.op["values"][pos[0]] = (pos[0], v)
                else:
                    self.op["values"][self.point] = (pos[0], v)
                self.context.signal("RasterWizard-Image")
                self.update_in_gui_thread()
            except (KeyError, IndexError):
                pass

    def on_curve_mouse_left_down(self, event):
        if not self.curve_panel.HasCapture():
            self.curve_panel.CaptureMouse()
        distance = float("inf")
        pos = event.GetPosition()
        if self.op["type"] == "point":
            v = 255 - pos[1]
            self.point = pos[0]
            self.op["values"][pos[0]] = (pos[0], v)
            self.update_in_gui_thread()
        else:
            for i, q in enumerate(self.op["values"]):
                dx = pos[0] - q[0]
                dy = (255 - pos[1]) - q[1]
                d = dx * dx + dy * dy
                if d < distance:
                    distance = d
                    self.point = i

    def on_curve_mouse_left_up(self, event):
        if self.curve_panel.HasCapture():
            self.curve_panel.ReleaseMouse()

    def on_update_tone(self, event=None):
        if self._tone_panel_buffer is None:
            return
        dc = wx.MemoryDC()
        dc.SelectObject(self._tone_panel_buffer)
        dc.Clear()
        dc.SetBackground(wx.GREEN_BRUSH)
        gc = wx.GraphicsContext.Create(dc)
        gc.PushState()
        gc.SetPen(wx.BLACK_PEN)
        tone_values = self.op["values"]
        if self.op["type"] == "spline":
            spline = RasterScripts.spline(tone_values)
            starts = [(i, 255 - spline[i]) for i in range(255)]
            ends = [(i, 255 - spline[i]) for i in range(1, 256)]
        else:
            tone_values = [q for q in tone_values if q is not None]
            spline = RasterScripts.line(tone_values)
            starts = [(i, 255 - spline[i]) for i in range(255)]
            ends = [(i, 255 - spline[i]) for i in range(1, 256)]
        gc.StrokeLineSegments(starts, ends)
        gc.PopState()
        gc.Destroy()
        del dc

    def on_check_enable_tone(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["enable"] = self.check_enable_tone.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_button_reset_tone(self, event):  # wxGlade: RasterWizard.<event_handler>
        tone_values = [[0, 0], [100, 150], [255, 255]]
        self.op["values"] = tone_values
        self.op["type"] = "spline"
        self.context.signal("RasterWizard-Image")
        self.update_in_gui_thread()


# end of class ToneCurvePanel


class SharpenPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: SharpenPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_sharpen = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.button_reset_sharpen = wx.Button(self, wx.ID_ANY, _("Reset"))
        self.slider_sharpen_percent = wx.Slider(
            self, wx.ID_ANY, 500, 0, 1000, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_sharpen_percent = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_sharpen_radius = wx.Slider(
            self, wx.ID_ANY, 20, 0, 50, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_sharpen_radius = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_sharpen_threshold = wx.Slider(
            self, wx.ID_ANY, 6, 0, 50, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_sharpen_threshold = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_sharpen, self.check_enable_sharpen
        )
        self.Bind(
            wx.EVT_BUTTON, self.on_button_reset_sharpen, self.button_reset_sharpen
        )
        self.Bind(
            wx.EVT_SLIDER, self.on_slider_sharpen_percent, self.slider_sharpen_percent
        )
        self.Bind(wx.EVT_TEXT, self.on_text_sharpen_percent, self.text_sharpen_percent)
        self.Bind(
            wx.EVT_SLIDER, self.on_slider_sharpen_radius, self.slider_sharpen_radius
        )
        self.Bind(wx.EVT_TEXT, self.on_text_sharpen_radius, self.text_sharpen_radius)
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_sharpen_threshold,
            self.slider_sharpen_threshold,
        )
        self.Bind(
            wx.EVT_TEXT, self.on_text_sharpen_threshold, self.text_sharpen_threshold
        )
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: SharpenPanel.__set_properties
        self.check_enable_sharpen.SetToolTip(_("Enable Sharpen"))
        self.check_enable_sharpen.SetValue(1)
        self.button_reset_sharpen.SetToolTip(_("Sharpen Reset"))
        self.slider_sharpen_percent.SetToolTip(_("Strength of sharpening in percent"))
        self.text_sharpen_percent.SetToolTip(_("amount of sharpening in %"))
        self.slider_sharpen_radius.SetToolTip(
            _("Blur radius for the sharpening operation")
        )
        self.text_sharpen_radius.SetToolTip(_("Sharpen radius amount"))
        self.slider_sharpen_threshold.SetToolTip(
            _("Threshold controls the minimum brighteness change to be sharpened.")
        )
        self.text_sharpen_threshold.SetToolTip(_("Sharpen Threshold Amount"))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: SharpenPanel.__do_layout
        sizer_sharpen = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Sharpen")), wx.VERTICAL
        )
        sizer_sharpen_threshold = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Threshold")), wx.HORIZONTAL
        )
        sizer_sharpen_radius = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Radius")), wx.HORIZONTAL
        )
        sizer_sharpen_percent = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Percent")), wx.HORIZONTAL
        )
        sizer_sharpen_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_sharpen_main.Add(self.check_enable_sharpen, 0, 0, 0)
        sizer_sharpen_main.Add(self.button_reset_sharpen, 0, 0, 0)
        sizer_sharpen.Add(sizer_sharpen_main, 0, wx.EXPAND, 0)
        sizer_sharpen_percent.Add(self.slider_sharpen_percent, 5, wx.EXPAND, 0)
        sizer_sharpen_percent.Add(self.text_sharpen_percent, 1, 0, 0)
        sizer_sharpen.Add(sizer_sharpen_percent, 0, wx.EXPAND, 0)
        sizer_sharpen_radius.Add(self.slider_sharpen_radius, 5, wx.EXPAND, 0)
        sizer_sharpen_radius.Add(self.text_sharpen_radius, 1, 0, 0)
        sizer_sharpen.Add(sizer_sharpen_radius, 0, wx.EXPAND, 0)
        sizer_sharpen_threshold.Add(self.slider_sharpen_threshold, 5, wx.EXPAND, 0)
        sizer_sharpen_threshold.Add(self.text_sharpen_threshold, 1, 0, 0)
        sizer_sharpen.Add(sizer_sharpen_threshold, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_sharpen)
        sizer_sharpen.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_sharpen.SetValue(op["enable"])
        self.slider_sharpen_percent.SetValue(op["percent"])
        self.slider_sharpen_radius.SetValue(op["radius"])
        self.slider_sharpen_threshold.SetValue(op["threshold"])
        self.text_sharpen_percent.SetValue(str(op["percent"]))
        self.text_sharpen_radius.SetValue(str(op["radius"]))
        self.text_sharpen_threshold.SetValue(str(op["threshold"]))

    def on_check_enable_sharpen(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["enable"] = self.check_enable_sharpen.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_button_reset_sharpen(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["percent"] = 500
        self.op["radius"] = 20
        self.op["threshold"] = 6
        self.slider_sharpen_percent.SetValue(self.op["percent"])
        self.slider_sharpen_radius.SetValue(self.op["radius"])
        self.slider_sharpen_threshold.SetValue(self.op["threshold"])
        self.text_sharpen_percent.SetValue(str(self.op["percent"]))
        self.text_sharpen_radius.SetValue(str(self.op["radius"]))
        self.text_sharpen_threshold.SetValue(str(self.op["threshold"]))
        self.context.signal("RasterWizard-Image")

    def on_slider_sharpen_percent(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["percent"] = int(self.slider_sharpen_percent.GetValue())
        self.text_sharpen_percent.SetValue(str(self.op["percent"]))
        self.context.signal("RasterWizard-Image")

    def on_text_sharpen_percent(self, event):  # wxGlade: RasterWizard.<event_handler>
        pass

    def on_slider_sharpen_radius(self, event):  # wxGlade: RasterWizard.<event_handler>
        self.op["radius"] = int(self.slider_sharpen_radius.GetValue())
        self.text_sharpen_radius.SetValue(str(self.op["radius"]))
        self.context.signal("RasterWizard-Image")

    def on_text_sharpen_radius(self, event):  # wxGlade: RasterWizard.<event_handler>
        pass

    def on_slider_sharpen_threshold(
        self, event
    ):  # wxGlade: RasterWizard.<event_handler>
        self.op["threshold"] = int(self.slider_sharpen_threshold.GetValue())
        self.text_sharpen_threshold.SetValue(str(self.op["threshold"]))
        self.context.signal("RasterWizard-Image")

    def on_text_sharpen_threshold(self, event):  # wxGlade: RasterWizard.<event_handler>
        pass


# end of class SharpenPanel


class OutputPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: OutputPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_output = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.check_replace_output = wx.CheckBox(self, wx.ID_ANY, _("Replace Image"))

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_output, self.check_enable_output
        )
        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_replace_output, self.check_replace_output
        )
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: OutputPanel.__set_properties
        self.check_enable_output.SetToolTip(_("Enable Output"))
        self.check_enable_output.SetValue(1)
        self.check_replace_output.SetToolTip(_("Replace image with this output"))
        self.check_replace_output.SetValue(1)
        self.check_replace_output.Enable(False)
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: OutputPanel.__do_layout
        sizer_output = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Output")), wx.VERTICAL
        )
        sizer_output.Add(self.check_enable_output, 0, 0, 0)
        sizer_output.Add(self.check_replace_output, 0, 0, 0)
        self.SetSizer(sizer_output)
        sizer_output.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        try:
            self.check_enable_output.SetValue(self.op["enable"])
            self.check_replace_output.SetValue(self.op["replace"])
        except KeyError:
            pass

    def on_check_enable_output(self, event):  # wxGlade: OutputPanel.<event_handler>
        self.op["enable"] = self.check_enable_output.GetValue()

    def on_check_replace_output(self, event):  # wxGlade: OutputPanel.<event_handler>
        self.op["replace"] = self.check_replace_output.GetValue()


# end of class OutputPanel


class BasicPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: OutputPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable = wx.CheckBox(self, wx.ID_ANY, _("Enable"))

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_CHECKBOX, self.on_check_enable, self.check_enable)
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: OutputPanel.__set_properties
        self.check_enable.SetToolTip(_("Enable Operation"))
        self.check_enable.SetValue(1)
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: OutputPanel.__do_layout
        sizer_output = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Enable")), wx.VERTICAL
        )
        sizer_output.Add(self.check_enable, 0, 0, 0)
        self.SetSizer(sizer_output)
        sizer_output.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.check_enable.SetLabel(_("Enable %s") % op["name"])
        self.check_enable.SetValue(op["enable"])
        self.context = context
        self.op = op

    def on_check_enable(self, event):
        self.op["enable"] = self.check_enable.GetValue()
        self.context.signal("RasterWizard-Image")


# end of class OutputPanel


class ContrastPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: ContrastPanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_contrast = wx.CheckBox(self, wx.ID_ANY, _("Enable"))
        self.button_reset_contrast = wx.Button(self, wx.ID_ANY, _("Reset"))
        self.slider_contrast_contrast = wx.Slider(
            self, wx.ID_ANY, 0, -127, 127, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_contrast_contrast = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_contrast_brightness = wx.Slider(
            self, wx.ID_ANY, 0, -127, 127, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_contrast_brightness = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_contrast, self.check_enable_contrast
        )
        self.Bind(
            wx.EVT_BUTTON, self.on_button_reset_contrast, self.button_reset_contrast
        )
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_contrast_contrast,
            self.slider_contrast_contrast,
        )
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_contrast_brightness,
            self.slider_contrast_brightness,
        )
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: ContrastPanel.__set_properties
        self.check_enable_contrast.SetToolTip(_("Enable Contrast"))
        self.check_enable_contrast.SetValue(1)
        self.button_reset_contrast.SetToolTip(_("Reset Contrast"))
        self.slider_contrast_contrast.SetToolTip(_("Contrast amount"))
        self.text_contrast_contrast.SetToolTip(
            _("Contrast the lights and darks by how much?")
        )
        self.slider_contrast_brightness.SetToolTip(_("Brightness amount"))
        self.text_contrast_brightness.SetToolTip(
            _("Make the image how much more bright?")
        )
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: ContrastPanel.__do_layout
        sizer_contrast = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Contrast")), wx.VERTICAL
        )
        sizer_contrast_brightness = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Brightness Amount")), wx.HORIZONTAL
        )
        sizer_contrast_contrast = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Contrast Amount")), wx.HORIZONTAL
        )
        sizer_contrast_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_contrast_main.Add(self.check_enable_contrast, 0, 0, 0)
        sizer_contrast_main.Add(self.button_reset_contrast, 0, 0, 0)
        sizer_contrast.Add(sizer_contrast_main, 0, wx.EXPAND, 0)
        sizer_contrast_contrast.Add(self.slider_contrast_contrast, 5, wx.EXPAND, 0)
        sizer_contrast_contrast.Add(self.text_contrast_contrast, 1, 0, 0)
        sizer_contrast.Add(sizer_contrast_contrast, 0, wx.EXPAND, 0)
        sizer_contrast_brightness.Add(self.slider_contrast_brightness, 5, wx.EXPAND, 0)
        sizer_contrast_brightness.Add(self.text_contrast_brightness, 1, 0, 0)
        sizer_contrast.Add(sizer_contrast_brightness, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_contrast)
        sizer_contrast.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_contrast.SetValue(self.op["enable"])
        self.text_contrast_contrast.SetValue(str(self.op["contrast"]))
        self.text_contrast_brightness.SetValue(str(self.op["brightness"]))
        self.slider_contrast_contrast.SetValue(self.op["contrast"])
        self.slider_contrast_brightness.SetValue(self.op["brightness"])

    def on_check_enable_contrast(self, event):  # wxGlade: ContrastPanel.<event_handler>
        self.op["enable"] = self.check_enable_contrast.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_button_reset_contrast(self, event):  # wxGlade: ContrastPanel.<event_handler>
        self.op["contrast"] = 0
        self.op["brightness"] = 0
        self.text_contrast_contrast.SetValue(str(self.op["contrast"]))
        self.text_contrast_brightness.SetValue(str(self.op["brightness"]))
        self.slider_contrast_contrast.SetValue(self.op["contrast"])
        self.slider_contrast_brightness.SetValue(self.op["brightness"])
        self.context.signal("RasterWizard-Image")

    def on_slider_contrast_contrast(
        self, event
    ):  # wxGlade: ContrastPanel.<event_handler>
        self.op["contrast"] = int(self.slider_contrast_contrast.GetValue())
        self.text_contrast_contrast.SetValue(str(self.op["contrast"]))
        self.context.signal("RasterWizard-Image")

    def on_slider_contrast_brightness(
        self, event
    ):  # wxGlade: ContrastPanel.<event_handler>
        self.op["brightness"] = int(self.slider_contrast_brightness.GetValue())
        self.text_contrast_brightness.SetValue(str(self.op["brightness"]))
        self.context.signal("RasterWizard-Image")


# end of class ContrastPanel


class HalftonePanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: HalftonePanel.__init__
        kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.check_enable_halftone = wx.CheckBox(self, wx.ID_ANY, "Enable")
        self.button_reset_halftone = wx.Button(self, wx.ID_ANY, "Reset")
        self.check_halftone_black = wx.CheckBox(self, wx.ID_ANY, "Black")
        self.slider_halftone_sample = wx.Slider(
            self, wx.ID_ANY, 10, 0, 50, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_halftone_sample = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_halftone_angle = wx.Slider(
            self, wx.ID_ANY, 22, 0, 90, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_halftone_angle = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )
        self.slider_halftone_oversample = wx.Slider(
            self, wx.ID_ANY, 2, 0, 50, style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL
        )
        self.text_halftone_oversample = wx.TextCtrl(
            self, wx.ID_ANY, "", style=wx.TE_READONLY
        )

        self.__set_properties()
        self.__do_layout()

        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_enable_halftone, self.check_enable_halftone
        )
        self.Bind(
            wx.EVT_BUTTON, self.on_button_reset_halftone, self.button_reset_halftone
        )
        self.Bind(
            wx.EVT_CHECKBOX, self.on_check_halftone_black, self.check_halftone_black
        )
        self.Bind(
            wx.EVT_SLIDER, self.on_slider_halftone_sample, self.slider_halftone_sample
        )
        self.Bind(
            wx.EVT_SLIDER, self.on_slider_halftone_angle, self.slider_halftone_angle
        )
        self.Bind(
            wx.EVT_SLIDER,
            self.on_slider_halftone_oversample,
            self.slider_halftone_oversample,
        )
        # end wxGlade
        self.context = None
        self.op = None

    def __set_properties(self):
        # begin wxGlade: HalftonePanel.__set_properties
        self.check_enable_halftone.SetToolTip(_("Enable Halftone"))
        self.check_enable_halftone.SetValue(1)
        self.button_reset_halftone.SetToolTip(_("Halftone Reset"))
        self.check_halftone_black.SetToolTip(_("Use black rather than white dots"))
        self.slider_halftone_sample.SetToolTip(_("Sample size for halftone dots"))
        self.text_halftone_sample.SetToolTip(_("Halftone dot size"))
        self.slider_halftone_angle.SetToolTip(_("Angle for halftone dots"))
        self.text_halftone_angle.SetToolTip(_("Halftone dot angle"))
        self.slider_halftone_oversample.SetToolTip(
            _("Oversampling amount for halftone-dots")
        )
        self.text_halftone_oversample.SetToolTip(_("Halftone dot oversampling amount"))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: HalftonePanel.__do_layout
        sizer_halftone = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Halftone")), wx.VERTICAL
        )
        sizer_halftone_oversample = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Oversample")), wx.HORIZONTAL
        )
        sizer_halftone_angle = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Angle")), wx.HORIZONTAL
        )
        sizer_halftone_sample = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, _("Sample")), wx.HORIZONTAL
        )
        sizer_halftone_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_halftone_main.Add(self.check_enable_halftone, 0, 0, 0)
        sizer_halftone_main.Add(self.button_reset_halftone, 0, 0, 0)
        sizer_halftone_main.Add((20, 20), 0, 0, 0)
        sizer_halftone_main.Add(self.check_halftone_black, 0, 0, 0)
        sizer_halftone.Add(sizer_halftone_main, 0, wx.EXPAND, 0)
        sizer_halftone_sample.Add(self.slider_halftone_sample, 5, wx.EXPAND, 0)
        sizer_halftone_sample.Add(self.text_halftone_sample, 1, 0, 0)
        sizer_halftone.Add(sizer_halftone_sample, 0, wx.EXPAND, 0)
        sizer_halftone_angle.Add(self.slider_halftone_angle, 5, wx.EXPAND, 0)
        sizer_halftone_angle.Add(self.text_halftone_angle, 1, 0, 0)
        sizer_halftone.Add(sizer_halftone_angle, 0, wx.EXPAND, 0)
        sizer_halftone_oversample.Add(self.slider_halftone_oversample, 5, wx.EXPAND, 0)
        sizer_halftone_oversample.Add(self.text_halftone_oversample, 1, 0, 0)
        sizer_halftone.Add(sizer_halftone_oversample, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_halftone)
        sizer_halftone.Fit(self)
        self.Layout()
        # end wxGlade

    def set_operation(self, context, op, svg_image=None):
        self.context = context
        self.op = op
        self.check_enable_halftone.SetValue(self.op["enable"])
        self.check_halftone_black.SetValue(self.op["black"])
        self.text_halftone_sample.SetValue(str(self.op["sample"]))
        self.slider_halftone_sample.SetValue(self.op["sample"])
        self.text_halftone_angle.SetValue(str(self.op["angle"]))
        self.slider_halftone_angle.SetValue(self.op["angle"])
        self.text_halftone_oversample.SetValue(str(self.op["oversample"]))
        self.slider_halftone_oversample.SetValue(self.op["oversample"])

    def on_check_enable_halftone(self, event):  # wxGlade: HalftonePanel.<event_handler>
        self.op["enable"] = self.check_enable_halftone.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_button_reset_halftone(self, event):  # wxGlade: HalftonePanel.<event_handler>
        self.op["black"] = False
        self.op["sample"] = 10
        self.op["angle"] = 22.0
        self.op["oversample"] = 2
        self.check_enable_halftone.SetValue(self.op["enable"])
        self.check_halftone_black.SetValue(self.op["black"])
        self.text_halftone_sample.SetValue(str(self.op["sample"]))
        self.slider_halftone_sample.SetValue(self.op["sample"])
        self.text_halftone_angle.SetValue(str(self.op["angle"]))
        self.slider_halftone_angle.SetValue(self.op["angle"])
        self.text_halftone_oversample.SetValue(str(self.op["oversample"]))
        self.slider_halftone_oversample.SetValue(self.op["oversample"])

    def on_check_halftone_black(self, event):  # wxGlade: HalftonePanel.<event_handler>
        self.op["black"] = self.check_halftone_black.GetValue()
        self.context.signal("RasterWizard-Image")

    def on_slider_halftone_sample(
        self, event
    ):  # wxGlade: HalftonePanel.<event_handler>
        self.op["sample"] = int(self.slider_halftone_sample.GetValue())
        self.text_halftone_sample.SetValue(str(self.op["sample"]))
        self.context.signal("RasterWizard-Image")

    def on_slider_halftone_angle(self, event):  # wxGlade: HalftonePanel.<event_handler>
        self.op["angle"] = int(self.slider_halftone_angle.GetValue())
        self.text_halftone_angle.SetValue(str(self.op["angle"]))
        self.context.signal("RasterWizard-Image")

    def on_slider_halftone_oversample(
        self, event
    ):  # wxGlade: HalftonePanel.<event_handler>
        self.op["oversample"] = int(self.slider_halftone_oversample.GetValue())
        self.text_halftone_oversample.SetValue(str(self.op["oversample"]))
        self.context.signal("RasterWizard-Image")


# end of class HalftonePanel
