hello, this should have been sent to the list... so my answer forwarded to here. ----- Forwarded message from oliver@xxxxxxxxxxxxxxxxxx ----- Date: Sun, 1 Aug 2010 23:40:45 +0200 From: oliver@xxxxxxxxxxxxxxxxxx To: LightningIsMyName <lightningismyname@xxxxxxxxx> Subject: Re: small Wishlist regarding Guides User-Agent: Mutt/1.5.20 (2009-06-14) Hi, On Sun, Aug 01, 2010 at 06:42:00PM +0300, LightningIsMyName wrote: > Hello > > > - non-rectangle-bound guides: > > Guides that can be enabled to have any angle, which means that they do [...] > I think we have seen this request already several times and I > definitely agree it could be useful. Your request made me take a look > at the code (app/display/gimpdisplayshell-draw.c, > app/core/gimpimage-guides.c, /app/core/gimpguide.c) and it actually > seems possible. I'll add it to my to-try list for when I have some > more time. Fine :) [...] > > - boundary guides, instead of middle.guides: > > Guides, where the outer boundary of a drawing tool snaps to the guide (instead the middle of the > > drawing tool snapping to the guide). > > > > This would be helpful for drawing in general, and correcting pictures: the color will > > not pass this line of the guide, which means, you can be sure no color enters a certain region. > > This does not seem trivial to code - in fact with how I remember the > paint core works, this is going to be one very hard hack... > Also, I think that if the purpose is just to stay inside of the lines > you can use a selection (create it using the guides and freeform [...] The selection does not has the magnetic behaviour as a guide has. Maybe even a freely definable guide would help here, or a magnetic selection, or something like this.... ?! [...] > > - Adding Multiple Guides > > (there is a Script for this on www.meetthegimp.org, but native would be nice) > > > > This feature is good for some repetitive tasks, where a lot of Guides will be needed, > > something like a guide-grid. > > Can you give a direct link to the script? I didn't found the link by myself, but I have the script local on my machine and can attach it. It's not writen by me. But I may look for the original link later (or ask the admin). > I definitely agree this > sounds useful - it's worth checking if we can simply include this > script with GIMP The GUI/behaviour could be enhanced, and could be more Gimp-like. But it's already useful and has saved me a lot of time in some tasks. > (or at least if you give us a link to it, we'll be > able to write something similar with extra features if needed). I will attach it here. I hope attachements are not blocked here. Ciao, Oliver import os from gimpfu import * import os.path import pygtk import gtk gettext.install("gimp20-python", gimp.locale_directory, unicode=True) def debugMessage(Message): dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, Message) dialog.run() dialog.hide() def findMaxDimensionOfImage(Image, Direction): if (Direction == 0): limit_value = pdb.gimp_image_height(Image) -1 else: limit_value = pdb.gimp_image_width(Image) -1 return limit_value # This defines the class class addMultipleGuidesDialog: # Things to do with the image reference imageRef = 0 def set_imageRef(self,Image): self.imageRef = Image def get_imageRef(self): return self.imageRef # Things to do with the guides we create thisGuide = 0 def set_thisGuide(self, guideRef): self.thisGuide = guideRef def get_thisGuide(self): return self.thisGuide # RadioGroup radio_group = [] def set_radioGroup(self, radioGroup): self.radio_group = radioGroup def get_radioGroup(self): return self.radio_group # Adjustment the_adjustment = 0 def set_adjustment(self, newAdjustment): self.the_adjustment = newAdjustment; def get_adjustment(self): return self.the_adjustment # Labels (possible to change later for translation purposes) Labels = ["Horizontal", "Vertical", "Add", "Close", "Remove Last"] # Labels = ["H", "V", "A", "C"] def get_Labels(self, labelIndex): return self.Labels[labelIndex] # This is a callback function. The data arguments are ignored # in this example. More on callbacks below. def hello(self, widget, data=None): print "Finished" def findActiveRadioButton(self): active = [r for r in self.get_radioGroup() if r.get_active()][0] return active.get_label() # call back for the Add button def add_guide(self, widget, Data): activeLabel = self.findActiveRadioButton() position = Data.get_value() if (activeLabel == self.get_Labels(0)): currentGuide = pdb.gimp_image_add_hguide(self.get_imageRef(), position) else: currentGuide = pdb.gimp_image_add_vguide(self.get_imageRef(), position) self.set_thisGuide(currentGuide) def remove_last_guide(self, widget, Data): thisGuide = self.get_thisGuide() if (thisGuide != 0): pdb.gimp_image_delete_guide(self.get_imageRef(), thisGuide) # Limit the upper value for the spin button def limit_spin(self, widget, Data): # find out which radio button is selected activeLabel = self.findActiveRadioButton() if (activeLabel == self.get_Labels(0)): # horizontal selected limit_value = findMaxDimensionOfImage(self.get_imageRef(), 0) else: # vertical selected limit_value = findMaxDimensionOfImage(self.get_imageRef(), 1) # get the current value of the spinbutton adjustment = self.get_adjustment() current_value = adjustment.get_value() # if the current value is greater than the new limit, force the value to be the new limit if (current_value > limit_value): current_value = limit_value adjustment.set_all(current_value, 0, limit_value, 1, 10, 0) # set the new value and upper limit def delete_event(self, widget, event, data=None): # If you return FALSE in the "delete_event" signal handler, # GTK will emit the "destroy" signal. Returning TRUE means # you don't want the window to be destroyed. # This is useful for popping up 'are you sure you want to quit?' # type dialogs. print "delete event occurred" # Change FALSE to TRUE and the main window will not be destroyed # with a "delete_event". return False # Another callback def destroy(self, widget, data=None): Image = self.get_imageRef() Image.undo_group_end() gtk.main_quit() # things to do after the instance has been created but before doing any work def setup(self, widget, Data): Image = Data[0] self.set_imageRef(Image) # set the image reference self.limit_spin(None,None) # set the max value allowed for position based on image size Image.undo_group_start() def __init__(self): # create a new window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title("Add Multiple Guides") # When the window is given the "delete_event" signal (this is given # by the window manager, usually by the "close" option, or on the # titlebar), we ask it to call the delete_event () function # as defined above. The data passed to the callback # function is NULL and is ignored in the callback function. self.window.connect("delete_event", self.delete_event) # Here we connect the "destroy" event to a signal handler. # This event occurs when we call gtk_widget_destroy() on the window, # or if we return FALSE in the "delete_event" callback. self.window.connect("destroy", self.destroy) # Sets the border width of the window. self.window.set_border_width(10) # We create a box to pack widgets into. This is described in detail # in the "packing" section. The box is not really visible, it # is just used as a tool to arrange widgets. self.window_box = gtk.VBox(False, 0) self.window.add(self.window_box) self.box1 = gtk.HBox(False, 0) self.box2 = gtk.HBox(False, 0) self.box3 = gtk.HBox(False, 0) self.window_box.pack_start(self.box1, True, True, 10) self.window_box.pack_start(self.box3, True, True, 10) self.window_box.pack_start(self.box2, True, True, 10) # Creates a new button with the label "Close". self.button1 = gtk.Button(self.get_Labels(3)) # When the button receives the "clicked" signal, it will call the # function hello() passing it None as its argument. The hello() # function is defined above. self.button1.connect("clicked", self.hello, None) # This will cause the window to be destroyed by calling # gtk_widget_destroy(window) when "clicked". Again, the destroy # signal could come from here, or the window manager. self.button1.connect_object("clicked", gtk.Widget.destroy, self.window) # This packs the button into the window (a GTK container). self.box2.pack_start(self.button1, True, True, 10) # The final step is to display this newly created widget. self.button1.show() # Create the first radio button widget self.radio1 = gtk.RadioButton(None, self.get_Labels(0), False) # Create the second radio button, passing a ref to the first to define the group self.radio2 = gtk.RadioButton(self.radio1, self.get_Labels(1), False) # pack them into a box self.box1.pack_start(self.radio1, True, True, 5) self.box1.pack_start(self.radio2, True, True, 5) # and make them visible self.radio1.show() self.radio2.show() self.set_radioGroup(self.radio1.get_group()) # create an adjustment for the spin widget # At the moment the upper value is set the same as the standard new guide dialog # value lower upper step_incr, page_incr, page_size limit_value = 1000 # limit_value = findMaxValue(self.get_imageRef(), 0) self.adjustment = gtk.Adjustment(0, 0, limit_value, 1, 10, 0) self.set_adjustment(gtk.Adjustment(0, 0, limit_value, 1, 10, 0)) # create a spin widget to alow user to set the position required self.spin_button = gtk.SpinButton(self.get_adjustment(), climb_rate=0.0, digits=0) # pack the spinbutton into the box self.box1.pack_start(self.spin_button, True, True, 5) self.spin_button.show() # Create a button to add the guide when pressed self.button2 = gtk.Button(self.get_Labels(2)) self.button2.connect("clicked", self.add_guide, self.spin_button) self.box1.pack_start(self.button2, True, True, 10) self.button2.show() # create a button to remove the last guide self.button3 = gtk.Button(self.get_Labels(4)) self.button3.connect("clicked", self.remove_last_guide, None) self.box3.pack_end(self.button3, False, False, 10) self.button3.show() # connect the radio buttons to a call back self.radio1.connect("released", self.limit_spin, self.adjustment) self.radio2.connect("released", self.limit_spin, self.adjustment) # Show everything self.box1.show() self.box2.show() self.box3.show() self.window_box.show() self.window.show() def main(self): # All PyGTK applications must have a gtk.main(). Control ends here # and waits for an event to occur (like a key press or mouse event). gtk.main() # The important stuff starts here def pygtk_addMultipleGuides(img, drw): hello = addMultipleGuidesDialog() # create an instance of the dialog hello.setup(None,[img,drw]) # initialise some important things hello.main() # start the gui register( "python-fu-pygtk_addMultipleGuides", "Add Multiple Guides", "(Version 0.1)", "Meetthegimp-Community http://forum.meetthegimp.org", "GPL License", "2009", "<Image>/contributed/Add Multiple Guides", "*", [], [], pygtk_addMultipleGuides) main() ----- End forwarded message ----- _______________________________________________ Gimp-developer mailing list Gimp-developer@xxxxxxxxxxxxxxxxxxxxxx https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer