diff --git a/btn4ws.py b/btn4ws.py index f728430..624d107 100644 --- a/btn4ws.py +++ b/btn4ws.py @@ -30,7 +30,7 @@ port of the older gimp-perl version to python. (c) 2007 Jan Dittberner """ import os, urllib, logging, sys -import gimp, gimpplugin +import gimp, gimpplugin, gimpui, gimpcolor import pygtk pygtk.require('2.0') import gtk @@ -44,6 +44,13 @@ logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', stream=sys.stderr) +def parsefont(font): + """ + Parses a font into its fontname and size parts. + """ + parts = font.split(" ") + return (" ".join(parts[:-1]), parts[-1]) + class text_to_name_mapper: """ Text string to name mapper class. This class provides mappings for several target @@ -149,40 +156,426 @@ class text_to_name_mapper: return os.path.join(dirname, fname) return fname -class Btn4wsDialog: +class IntEntry(gtk.Entry): + """Input field for integer numbers.""" + + def __init__(self, max = 0): + gtk.Entry.__init__(self, max) + self.set_property("truncate-multiline", True) + self.connect("insert-text", self._cb_int_field_insert) + + def _cb_int_field_insert(self, w, new_text, new_text_length, position): + """Allow integer input only.""" + if not new_text.isdigit(): + w.stop_emission("insert-text") + +class Btn4wsDialog(gtk.Assistant): """This class is the input dialog field for btn4ws""" - def delete_event(self, widget, event, data = None): + def _cb_delete_event(self, widget, event, data = None): + logging.debug("delete_event") return False - def destroy(self, widget, data = None): - gtk.main_quit() + def __init__(self, **kwargs): + self.data = kwargs + self.pages = {} + logging.debug("kwargs: " + str(kwargs)) + gtk.Assistant.__init__(self) - def __init__(self, filename, outdir, font, - strcolor, transparency, bgcolor, - glow, glowcolor, - usepattern, pattern, - buttoncolor, roundradius, - padding, glowsize, bevelwidth, - nova, novasparkles, novaradius, - novacolor, writexcf, makeinactive, - makeactive, makepressed, makejscript): - self.window = gtk.Assistant() - self.window.connect("delete_event", self.delete_event) - self.window.connect("destroy", self.destroy) - self.window.show() + self._addIntroPage() + #self._addPathSelectionPage() + #self._addBasicSettingsPage() + self._addLayoutPage() + self._addEffectsPage() + self._addLastPage() + self.show() + self.connect("delete_event", self._cb_delete_event) - def main(self): - gtk.main() + for pagename in self.pages.iterkeys(): + self.checkcompletion(pagename) + + def _addIntroPage(self): + label = gtk.Label("""Buttons for website allows you to produce a series of buttons for use on a website. On the next pages you may choose several options to change the content and the look of the buttons.""") + label.set_line_wrap(True) + label.show() + self.append_page(label) + self.set_page_title(label, "Introduction") + self.set_page_complete(label, True) + + def _addPathSelectionPage(self): + page = gtk.VBox(False, 5) + self.pages["pathselection"] = page + page.set_border_width(5) + page.show() + self.append_page(page) + self.set_page_title(page, + "Select the input file and output directory") + self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT) + + label = gtk.Label("Please choose the file containing your button labels and the directory where the generated files should be put.") + label.set_line_wrap(True) + label.show() + page.pack_start(label, True, True, 0) + + table = gtk.Table(rows=2, columns=2, homogeneous=False) + table.show() + label = gtk.Label("Button label file") + label.show() + table.attach(label, 0, 1, 0, 1) + button = gtk.FileChooserButton("Choose file") + button.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) + button.connect("selection-changed", self._cb_file_selected) + button.show() + table.attach(button, 1, 2, 0, 1) + + label = gtk.Label("Output directory") + label.show() + table.attach(label, 0, 1, 1, 2) + button = gtk.FileChooserButton("Choose directory") + button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) + button.connect("selection-changed", self._cb_dir_selected) + button.show() + table.attach(button, 1, 2, 1, 2) + + page.pack_end(table) + + def _addBasicSettingsPage(self): + page = gtk.VBox(False, 5) + self.pages["basicsettings"] = page + page.set_border_width(5) + page.show() + self.append_page(page) + self.set_page_title(page, + "Select the basic button settings") + self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT) + + label = gtk.Label("Please choose the basic layout settings of your buttons.") + label.set_line_wrap(True) + label.show() + page.pack_start(label, True, True, 0) + + table = gtk.Table(rows=4, columns=2, homogeneous=False) + table.show() + + # font + label = gtk.Label("Button text font") + label.show() + table.attach(label, 0, 1, 0, 1) + fontsel = gtk.FontButton() + fontsel.set_show_size(True) + if self.data["font"]: + fontsel.set_font_name(self.data["font"]) + fontsel.show() + fontsel.connect("font-set", self._cb_set_font) + table.attach(fontsel, 1, 2, 0, 1) + + # strcolor + label = gtk.Label("Button text color") + label.show() + table.attach(label, 0, 1, 1, 2) + colorsel = gimpui.ColorSelector() + if self.data["strcolor"]: + colorsel.set_color(self.data["strcolor"]) + colorsel.show() + colorsel.connect("color-changed", self._cb_set_color, "strcolor", + "basicsettings") + table.attach(colorsel, 1, 2, 1, 2) + + # background toggle + bgtoggle = gtk.CheckButton("Use a pattern for button") + bgtoggle.set_active(self.data["usepattern"]) + bgtoggle.show() + table.attach(bgtoggle, 1, 2, 2, 3) + + # background color / pattern + if self.data["usepattern"]: + label = gtk.Label("Button pattern") + else: + label = gtk.Label("Button color") + label.show() + patternsel = gimpui.PatternSelectButton() + if self.data["pattern"]: + patternsel.set_pattern(self.data["pattern"]) + patternsel.connect("pattern-set", self._cb_set_pattern) + colorsel = gimpui.ColorSelector() + if self.data["buttoncolor"]: + colorsel.set_pattern(self.data["buttoncolor"]) + colorsel.connect("color-changed", self._cb_set_color, "buttoncolor", + "basicsettings") + bgtoggle.connect("toggled", self._cb_bgtoggle_toggle, label, + "Button pattern", patternsel, + "Button color", colorsel) + if self.data["usepattern"]: + patternsel.show() + else: + colorsel.show() + + table.attach(label, 0, 1, 3, 4) + table.attach(patternsel, 1, 2, 3, 4) + table.attach(colorsel, 1, 2, 3, 4) + + page.pack_end(table) + + def _addLayoutPage(self): + page = gtk.VBox(False, 5) + self.pages["layout"] = page + page.set_border_width(5) + page.show() + self.append_page(page) + self.set_page_title(page, + "Select the layout settings") + self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT) + + label = gtk.Label("Select the layout options for your buttons") + label.set_line_wrap(True) + label.show() + page.pack_start(label, True, True, 0) + + table = gtk.Table(rows=4, columns=2, homogeneous=False) + table.show() + + #roundradius + label = gtk.Label("Round radius") + label.show() + entry = IntEntry(max = 2) + if self.data["roundradius"]: + entry.set_text(str(self.data["roundradius"])) + entry.connect("changed", self._cb_set_intvalue, "roundradius", + "layout") + entry.show() + table.attach(label, 0, 1, 0, 1) + table.attach(entry, 1, 2, 0, 1) + + #bevelwidth + label = gtk.Label("Bevel width") + label.show() + entry = IntEntry(max = 2) + entry.connect("changed", self._cb_set_intvalue, "bevelwidth", + "layout") + entry.show() + table.attach(label, 0, 1, 1, 2) + table.attach(entry, 1, 2, 1, 2) + + #transparency + transp = gtk.CheckButton("Transparent button background") + transp.set_active(self.data["transparency"]) + transp.show() + transp.connect("toggled", self._cb_toggle_simple, "transparency", + "layout") + table.attach(transp, 1, 2, 2, 3) + + #bgcolor + label = gtk.Label("Background color") + label.show() + colorsel = gimpui.ColorSelector() + if self.data["buttoncolor"]: + colorsel.set_pattern(self.data["bgcolor"]) + colorsel.connect("color-changed", self._cb_set_color, "bgcolor", + "layout") + colorsel.show() + table.attach(label, 0, 1, 3, 4) + table.attach(colorsel, 1, 2, 3, 4) + + page.pack_end(table) + + def _addEffectsPage(self): + page = gtk.VBox(False, 5) + self.pages["effects"] = page + page.set_border_width(5) + page.show() + self.append_page(page) + self.set_page_title(page, + "Select the effect settings") + self.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT) + + table = gtk.Table(rows=6, columns=2, homogeneous=False) + table.show() + + #nova + novatoggle = gtk.CheckButton("Enable nova effect") + novatoggle.set_active(self.data["nova"]) + novatoggle.show() + table.attach(novatoggle, 1, 2, 0, 1) + + #novacolor + label = gtk.Label("Nova color") + label.show() + novacolor = gimpui.ColorSelector() + if self.data["novacolor"]: + novacolor.set_pattern(self.data["novacolor"]) + novacolor.connect("color-changed", self._cb_set_color, "novacolor", + "effects") + novacolor.set_sensitive(self.data["nova"]) + novacolor.show() + table.attach(label, 0, 1, 1, 2) + table.attach(novacolor, 1, 2, 1, 2) + + #novaradius + novaradius = IntEntry(max = 2) + if self.data["novaradius"] is not None: + novaradius.set_text(str(self.data["novaradius"])) + novaradius.connect("changed", self._cb_set_intvalue, "novaradius", + "effects") + novaradius.set_sensitive(self.data["nova"]) + novaradius.show() + table.attach(novaradius, 1, 2, 2, 3) + + #novasparkles + novasparkles = IntEntry(max = 2) + if self.data["novasparkles"] is not None: + novasparkles.set_text(str(self.data["novasparkles"])) + novasparkles.connect("changed", self._cb_set_intvalue, "novasparkles", + "effects") + novasparkles.set_sensitive(self.data["nova"]) + novasparkles.show() + table.attach(novasparkles, 1, 2, 3, 4) + novatoggle.connect("toggled", self._cb_nova_toggle, novacolor, + novaradius, novasparkles) + + #glow + #glowcolor + + page.pack_end(table) + + def _addLastPage(self): + page = gtk.VBox(False, 5) + self.pages["output"] = page + page.set_border_width(5) + page.show() + self.append_page(page) + self.set_page_title(page, + "Output formats") + self.set_page_type(page, gtk.ASSISTANT_PAGE_CONFIRM) + + label = gtk.Label("Choose the output data.") + label.show() + page.pack_start(label) + + #makejscript + toggle = gtk.CheckButton("Make HTML, CSS and JavaScript") + toggle.set_active(self.data["makejscript"]) + toggle.connect("toggled", self._cb_toggle_simple, "makejscript", + "output") + toggle.show() + page.pack_start(toggle) + + #makeinactive + toggle = gtk.CheckButton("Make inactive buttons") + toggle.set_active(self.data["makeinactive"]) + toggle.connect("toggled", self._cb_toggle_simple, "makeinactive", + "output") + toggle.show() + page.pack_start(toggle) + + #makeactive + toggle = gtk.CheckButton("Make active buttons") + toggle.set_active(self.data["makeactive"]) + toggle.connect("toggled", self._cb_toggle_simple, "makeactive", + "output") + toggle.show() + page.pack_start(toggle) + + #makepressed + toggle = gtk.CheckButton("Make pressed buttons") + toggle.set_active(self.data["makepressed"]) + toggle.connect("toggled", self._cb_toggle_simple, "makepressed", + "output") + toggle.show() + page.pack_start(toggle) + + #writexcf + toggle = gtk.CheckButton("Write the XCF file") + toggle.set_active(self.data["writexcf"]) + toggle.connect("toggled", self._cb_toggle_simple, "writexcf", + "output") + toggle.show() + page.pack_start(toggle) + + def checkcompletion(self, pagename): + logging.debug(str(self.data)) + criteriamatched = False + if pagename == "pathselection": + criteriamatched = self.data["filename"] and self.data["outdir"] + elif pagename == "basicsettings": + criteriamatched = self.data["font"] and self.data["strcolor"] \ + and ((self.data["usepattern"] and self.data["pattern"]) or \ + (not self.data["usepattern"] and \ + self.data["buttoncolor"])) + elif pagename == "layout": + criteriamatched = self.data["roundradius"] is not None and \ + self.data["bevelwidth"] is not None and \ + (self.data["transparency"] or self.data["bgcolor"] is not None) + elif pagename == "output": + criteriamatched = self.data["makejscript"] is not None and \ + self.data["makeinactive"] is not None and \ + self.data["makeactive"] is not None and \ + self.data["makepressed"] is not None + if criteriamatched: + self.set_page_complete(self.pages[pagename], True) + else: + self.set_page_complete(self.pages[pagename], False) + + def _cb_set_intvalue(self, w, fieldname, pagename): + try: + self.data[fieldname] = int (w.get_text()) + except ValueError: + pass + self.checkcompletion(pagename) + + def _cb_toggle_simple(self, w, datafield, pagename): + self.data[datafield] = w.get_active() + self.checkcompletion(pagename) + + def _cb_file_selected(self, w, filesel): + self.data["filename"] = w.get_filename() + self.checkcompletion("pathselection") + + def _cb_dir_selected(self, w, dirsel): + self.data["outdir"] = w.get_filename() + self.checkcompletion("pathselection") + + def _cb_set_font(self, w): + self.data["font"] = w.get_font_name() + self.checkcompletion("basicsettings") + + def _cb_set_color(self, w, fieldname, pagename): + self.data[fieldname] = w.get_color() + self.checkcompletion(pagename) + + def _cb_set_pattern(self, w, patternname, width, height, bpp, mask_data, + finished): + if finished: + self.data["pattern"] = patternname + self.checkcompletion("basicsettings") + + def _cb_bgtoggle_toggle(self, w, label, patterntext, patternsel, + colortext, colorsel): + if w.get_active(): + self.data["usepattern"] = True + colorsel.hide() + patternsel.show() + label.set_text(patterntext) + else: + self.data["usepattern"] = False + patternsel.hide() + colorsel.show() + label.set_text(colortext) + self.checkcompletion("basicsettings") + + def _cb_nova_toggle(self, w, colorfield, radiusfield, sparksfield): + if w.get_active(): + self.data["nova"] = True + colorfield.set_sensitive(True) + radiusfield.set_sensitive(True) + sparksfield.set_sensitive(True) + else: + self.data["nova"] = False + colorfield.set_sensitive(False) + radiusfield.set_sensitive(False) + sparksfield.set_sensitive(False) + self.checkcompletion("effects") class btn4wsplugin(gimpplugin.plugin): """This is the btn4ws gimp plugin.""" - def parsefont(font): - """ - Parses a font into its fontname and size parts. - """ - parts = font.split(" ") - return (" ".join(parts[:-1]), parts[-1]) - def gimp2html_color(color): """ Converts a color tuple to a hex encoded color for CSS. @@ -300,8 +693,18 @@ class btn4wsplugin(gimpplugin.plugin): False, False, False, False, True) gimp.delete(imgcopy) + def _cb_destroy(self, widget, data = None): + logging.debug("destroy") + gtk.main_quit() + + def _cb_apply(self, widget): + self.data = widget.data + + def __init__(self): + self.data = {} + def btn4ws(self, runmode, filename = None, outdir = None, font = None, - strcolor = None, transparency = None, bgcolor = None, + strcolor = None, transparency = False, bgcolor = None, glow = False, glowcolor = None, usepattern = False, pattern = None, buttoncolor = None, roundradius = None, padding = None, glowsize = None, bevelwidth = None, @@ -314,14 +717,28 @@ class btn4wsplugin(gimpplugin.plugin): """ if runmode == RUN_INTERACTIVE: logging.debug("runmode interactive") - dialog = Btn4wsDialog(filename, outdir, font, strcolor, - transparency, bgcolor, glow, glowcolor, - usepattern, pattern, buttoncolor, - roundradius, padding, glowsize, bevelwidth, - nova, novasparkles, novaradius, novacolor, - writexcf, makeinactive, makeactive, - makepressed, makejscript) - dialog.main() + dialog = Btn4wsDialog(filename = filename, outdir = outdir, + font = font, strcolor = strcolor, + transparency = transparency, + bgcolor = bgcolor, glow = glow, + glowcolor = glowcolor, + usepattern = usepattern, pattern = pattern, + buttoncolor = buttoncolor, + roundradius = roundradius, padding = padding, + glowsize = glowsize, bevelwidth = bevelwidth, + nova = nova, novasparkles = novasparkles, + novaradius = novaradius, + novacolor = novacolor, + writexcf = writexcf, + makeinactive = makeinactive, + makeactive = makeactive, + makepressed = makepressed, + makejscript = makejscript) + dialog.connect("close", self._cb_destroy) + dialog.connect("cancel", self._cb_destroy) + dialog.connect("destroy", self._cb_destroy) + dialog.connect("apply", self._cb_apply) + gtk.main() elif runmode == RUN_NONINTERACTIVE: logging.debug("runmode noninteractive") elif runmode == RUN_WITH_LASTVALS: diff --git a/gtktest.py b/gtktest.py deleted file mode 100644 index 2cb31a1..0000000 --- a/gtktest.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import pygtk -pygtk.require('2.0') -import gtk - -class AssistantTest: - def delete_event(self, widget, event, data = None): - return False - - def destroy(self, widget, data = None): - gtk.main_quit() - - def __init__(self): - self.data = { - "filename" : None, - "outputdir" : None} - self.ass = gtk.Assistant() - - self.ass.connect("delete_event", self.delete_event) - self.ass.connect("close", self.destroy) - self.ass.connect("cancel", self.destroy) - - # Construct page 0 - label = gtk.Label("""Buttons for website allows you to produce a series of buttons for use on a website. On the next pages you may choose several options to change the content and the look of the buttons.""") - label.set_line_wrap(True) - label.show() - self.ass.append_page(label) - self.ass.set_page_title(label, "Introduction to buttons for website") - self.ass.set_page_type(label, gtk.ASSISTANT_PAGE_INTRO) - self.ass.set_page_complete(label, True) - - # Construct page 1 - self.page1 = gtk.VBox(False, 5) - self.page1.set_border_width(5) - self.page1.show() - self.ass.append_page(self.page1) - self.ass.set_page_title(self.page1, - "Select the input file and output directory") - self.ass.set_page_type(self.page1, gtk.ASSISTANT_PAGE_CONTENT) - - label = gtk.Label("Please choose the file containing your button labels and the directory where the generated files should be put.") - label.set_line_wrap(True) - label.show() - self.page1.pack_start(label, True, True, 0) - - table = gtk.Table(rows=2, columns=2, homogeneous=False) - table.show() - label = gtk.Label("Button label file") - label.show() - table.attach(label, 0, 1, 0, 1) - button = gtk.FileChooserButton("Choose file") - button.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) - button.connect("selection-changed", self.cb_file_selected, button) - button.show() - table.attach(button, 1, 2, 0, 1) - - label = gtk.Label("Output directory") - label.show() - table.attach(label, 0, 1, 1, 2) - button = gtk.FileChooserButton("Choose directory") - button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) - button.connect("selection-changed", self.cb_dir_selected, button) - button.show() - table.attach(button, 1, 2, 1, 2) - - self.page1.pack_end(table) - - # Construct page 2 - label = gtk.Label('Thanks for using btn4ws') - label.set_line_wrap(True) - label.show() - self.ass.append_page(label) - self.ass.set_page_title(label, 'Page 1: The end') - self.ass.set_page_type(label, gtk.ASSISTANT_PAGE_SUMMARY) - - self.ass.show() - - def checkpage1completion(self): - print str(self.data) - if self.data["filename"] and self.data["outputdir"]: - self.ass.set_page_complete(self.page1, True) - else: - self.ass.set_page_complete(self.page1, False) - - def cb_file_selected(self, w, filesel): - self.data["filename"] = filesel.get_filename() - self.checkpage1completion() - - def cb_dir_selected(self, w, dirsel): - self.data["outputdir"] = dirsel.get_filename() - self.checkpage1completion() - - def main(self): - gtk.main() - -if __name__ == "__main__": - assi = AssistantTest() - assi.main()