Thu Jan 23, 2014 1:22 pm
Thu Jan 23, 2014 1:54 pm
Thu Jan 23, 2014 2:49 pm
Thu Jan 23, 2014 3:46 pm
Thu Jan 23, 2014 3:54 pm
okyl168 wrote:Hi, I wrote a simple plugin in to do some artistic transform (see attachement) and would like to change the parameter while looking at the effect applied on the image without leaving the dialog box.
Any sample code that I can follow? Thanks.
Thu Jan 23, 2014 4:57 pm
Fri Jan 24, 2014 6:18 am
Fri Jan 24, 2014 7:25 am
okyl168 wrote:
ofnuts/canon, yes, I know, but I don't see any PF_CHECKBOX in the document. If you point me to the document, that would be great.
Fri Jan 24, 2014 8:59 am
Sat Jan 25, 2014 6:54 am
#@gimp Jobs colors : gimp_jobs_colors, gimp_jobs_colors_preview
#@gimp : Gamma = float(0,-2,2)
#@gimp : Equalize = bool(0)
#@gimp : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate horizontal","Duplicate vertical")
#@gimp : sep = separator(), note = note("<small>Author: <i>Oberon Leung</i>. Latest update: <i>2014/01/25</i>.</small>")
gimp_jobs_colors :
-n 0,255 -if $2 -equalize 256 -endif
-luminance -apply_gamma {10^$1} -n 0,9 -round
(22,187,20,36,235,240,245,243,247,209^18,97,147,157,79,110,121,142,170,200^19,158,192,60,67,65,64,64,64,185)
-map[^-1] [-1] -rm[-1]
gimp_jobs_colors_preview :
-gimp_split_preview "-gimp_jobs_colors $*",$-1
Sat Jan 25, 2014 10:13 am
Ronounours wrote:Hi.
I've transcribed your python script into a G'MIC filter, you can already access it by updating your filters.
I've put this filter in Testing / Okyl168 /
For information, here is what I wrote for doing this (13 lines in total) :
Let me know if this is what intended.
Tue Nov 07, 2023 10:35 am
#!/usr/bin/env python
from gimpfu import *
import gtk
# Global variables to store the parameters used for our effect/work to show preview or actual layer when user OK it
global_param1 = 300 #in this example it's radius
global_param2 = 4 #in this example it's samples
global_param3 = 10 #in this example it's iterations
global_param4 = 0 #in this example it's enhance_shadows
image = 0 #we'll set these when dialog() is called so that we can access them later
drawable = 0
has_preview = False
preview_layer = 0
def apply_effect(layer): #function to do work on either preview layer or actual drawable when user clicks OK
global image
width = 200
height = global_param1
pdb.gimp_ellipse_select(image,image.width/2-width/2,image.height/2-height/2,width,height,CHANNEL_OP_REPLACE,TRUE,FALSE,0)
pdb.gimp_drawable_invert(layer,TRUE)
pdb.gimp_selection_none(image)
gimp.displays_flush()
def apply_final(layer): #wrapper to apply effect on final and remove preview_layer meant to be called by on_ok_button_clicked
global preview_layer
if has_preview:
pdb.gimp_image_remove_layer(image,preview_layer)
pdb.gimp_image_undo_enable(image) #so that user can undo this next step
pdb.gimp_image_undo_group_start(image) #so it's undone in Ctrl+Z
apply_effect(layer)
pdb.gimp_image_undo_group_end(image)
# Function to update the live preview
def update_live_preview(): #this is called everytime some parameter changes
global global_param1, global_param2, global_param3, global_param4
global image,drawable
global has_preview,preview_layer #deal with preview layer
# Apply your plugin's effect using the current parameters
# Use global_param1 and global_param2 to access the user's inputs
if not has_preview: #create a preview layer
#pdb.gimp_message("Creating preview")
preview_layer = pdb.gimp_layer_new_from_drawable(drawable,image)
pdb.gimp_image_insert_layer(image,preview_layer,None,0) #insert top most so we see it
has_preview = True #now set it true so we can deal with existing layer in later calls
else: # already have preview layer
#pdb.gimp_message("Removing existing and creating new Preview")
pdb.gimp_image_remove_layer(image,preview_layer) #remove it to create a new one to work on
preview_layer = pdb.gimp_layer_new_from_drawable(drawable,image)
pdb.gimp_image_insert_layer(image,preview_layer,None,0) #insert top most so we see it
#debug message
#pdb.gimp_message(str(global_param1)+","+str(global_param2)+","+str(global_param3)+","+str(global_param4))
apply_effect(preview_layer)
# Update the live preview layer with the modified image
def dialog(image_, drawable_):
global image, drawable
#save these for updates
image = image_
pdb.gimp_image_undo_disable(image) #for speed and also when user undo it doesn't see our preview creations/deletions
drawable = drawable_
dialog = gtk.Dialog("My Live Dialog Test Window", None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
dialog.set_default_size(600, 100)
# Create an HBox to hold the label and slider -------------------------------------------------------------
hbox = gtk.HBox()
dialog.vbox.pack_start(hbox, expand=True, fill=True)
# Create a label on the left-hand side
label1 = gtk.Label("radius:")
hbox.pack_start(label1, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment1 = gtk.Adjustment(value=50, lower=2, upper=1000, step_incr=1, page_incr=0)
param1_scale = gtk.HScale(adjustment=adjustment1)
param1_scale.set_digits(0) # Display only integers
hbox.pack_start(param1_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param1_scale.connect("value-changed", on_param1_changed)
# Create an HBox to hold the label and slider -------------------------------------------------------------
hbox2 = gtk.HBox()
dialog.vbox.pack_start(hbox2, expand=True, fill=True)
# Create a label on the left-hand side
label2 = gtk.Label("samples:")
hbox2.pack_start(label2, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment2 = gtk.Adjustment(value=4, lower=3, upper=17, step_incr=1, page_incr=0)
param2_scale = gtk.HScale(adjustment=adjustment2)
param2_scale.set_digits(0) # Display only integers
hbox2.pack_start(param2_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param2_scale.connect("value-changed", on_param2_changed)
# Create an HBox to hold the label and slider -------------------------------------------------------------
hbox3 = gtk.HBox()
dialog.vbox.pack_start(hbox3, expand=True, fill=True)
# Create a label on the left-hand side
label3 = gtk.Label("iterations:")
hbox3.pack_start(label3, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment3 = gtk.Adjustment(value=10, lower=1, upper=30, step_incr=1, page_incr=0)
param3_scale = gtk.HScale(adjustment=adjustment3)
param3_scale.set_digits(0) # Display only integers
hbox3.pack_start(param3_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param3_scale.connect("value-changed", on_param3_changed)
# Add an OK button
ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
ok_button.connect("clicked", on_ok_button_clicked)
# Show the dialog
dialog.show_all()
dialog.run()
# Callback function for updating the live preview when param1 changes
def on_param1_changed(scale):
global global_param1
global_param1 = scale.get_value()
update_live_preview()
# Callback function for updating the live preview when param2 changes
def on_param2_changed(scale):
global global_param2
global_param2 = scale.get_value()
update_live_preview()
def on_param3_changed(scale):
global global_param3
global_param3 = scale.get_value()
update_live_preview()
# Callback function for the OK button
def on_ok_button_clicked(button, data=None):
global drawable
apply_final(drawable)
button.get_toplevel().destroy() #destroys the gtk dialog window
# Register the Python-Fu plugin
register(
"python_fu_live_preview_test",
"Live Preview Plugin",
"Create a live preview of an effect",
"Your Name",
"Your Name",
"2023",
"<Image>/Python-Fu/Live Preview/Test 1", # Menu location
"*", # Image type
[],
[],
dialog
)
main()
Tue Nov 07, 2023 10:39 am
Tue Nov 07, 2023 3:15 pm
Tue Nov 07, 2023 4:43 pm
Sat Nov 25, 2023 1:26 am
Sat Nov 25, 2023 2:01 am
Sat Nov 25, 2023 9:37 am
MareroQ wrote:I'm very surprised by the lack of interest in this great feature - now you can preview plugins directly.
My first attempt of course with G'mic (I know it has its preview, but not on canvas...)
Tin:
Do you know how to change the slider type?
#!/usr/bin/env python
#grow-shrink-live.py
# Creator: TT
# This should allow user to adjust grow/shrink current selection with live preview
# Open Source
from gimpfu import *
import gtk
# Global variables to store the parameters used for our effect/work to show preview or actual layer when user OK it
global_param1 = 0 #in this example it's shrinkgrow radius
global_param2 = 0 #in this example it's feather_radius
global_param3 = 10 #in this example it's iterations
global_param4 = 0 #in this example it's enhance_shadows
chosen_color = 0
sample_integer = 13
image = 0 #we'll set these when dialog() is called so that we can access them later
drawable = 0
has_preview = False
preview_layer = 0
#for this operation
selection_channel = 0
def apply_effect(layer): #function to do work on either preview layer or actual drawable when user clicks OK
global image
radius = global_param1
feather_radius = global_param2
pdb.gimp_image_select_item(image,CHANNEL_OP_REPLACE,selection_channel) #first we selected the original saved channel
if radius < 0:
pdb.gimp_selection_shrink(image,-radius)
else:
pdb.gimp_selection_grow(image,radius)
pdb.gimp_selection_feather(image,feather_radius)
#do something to it to show it's effect so that user can distinguish between selected area or not
pdb.gimp_drawable_edit_fill(layer,FILL_FOREGROUND)
#pdb.gimp_ellipse_select(image,image.width/2-width/2,image.height/2-height/2,width,height,CHANNEL_OP_REPLACE,TRUE,FALSE,0)
#pdb.gimp_drawable_invert(layer,TRUE)
#pdb.gimp_selection_none(image)
gimp.displays_flush()
def apply_final(layer): #wrapper to apply effect on final and remove preview_layer meant to be called by on_ok_button_clicked
global preview_layer
#pdb.gimp_image_undo_group_start(image) #so it's undone in Ctrl+Z
pdb.gimp_image_undo_enable(image) #so that user can undo this next step
apply_effect(preview_layer)
#pdb.gimp_image_undo_group_end(image)
if has_preview:
pdb.gimp_image_remove_channel(image,selection_channel) #so that we don't leave a saved channel laying around
pdb.gimp_image_remove_layer(image,preview_layer)
pdb.gimp_image_set_active_layer(image,drawable)
pdb.gimp_context_set_foreground(save_foreground)
gimp.displays_flush()
# Function to update the live preview
def update_live_preview(): #this is called everytime some parameter changes
global global_param1, global_param2, global_param3, global_param4
global image,drawable
global has_preview,preview_layer #deal with preview layer
global selection_channel #this will save our current selection
# Apply your plugin's effect using the current parameters
# Use global_param1 and global_param2 to access the user's inputs
if not has_preview: #create a preview layer
#pdb.gimp_message("Creating preview")
preview_layer = pdb.gimp_layer_new(image,image.width,image.height,RGBA_IMAGE,"preview",70,LAYER_MODE_NORMAL)
pdb.gimp_image_insert_layer(image,preview_layer,None,0) #insert top most so we see it
non_empty,x1,y1,x2,y2 = pdb.gimp_selection_bounds(image)
if non_empty == TRUE:
pass #there's already a selection
else:
pdb.gimp_selection_all(image) #if there's no selection we just select the whole image and work with that
selection_channel = pdb.gimp_selection_save(image)
has_preview = True #now set it true so we can deal with existing layer in later calls
else: # already have preview layer
pass
#pdb.gimp_message("Removing existing and creating new Preview")
pdb.gimp_image_remove_layer(image,preview_layer) #remove it to create a new one to work on
preview_layer = pdb.gimp_layer_new(image,image.width,image.height,RGBA_IMAGE,"preview",50,LAYER_MODE_NORMAL)
pdb.gimp_image_insert_layer(image,preview_layer,None,0) #insert top most so we see it
pdb.gimp_image_set_active_layer(image,preview_layer)
#debug message
#pdb.gimp_message(str(global_param1)+","+str(global_param2)+","+str(global_param3)+","+str(global_param4))
apply_effect(preview_layer)
# Update the live preview layer with the modified image
save_foreground = 0
hilightcolor = (255,0,0)
def dialog(image_, drawable_):
global image, drawable, save_foreground
if chosen_color==0:
global chosen_color
chosen_color = (0, 128, 255) # Set default color
#save these for updates
image = image_
pdb.gimp_image_undo_disable(image) #for speed and also when user undo it doesn't see our preview creations/deletions
drawable = drawable_
save_foreground = pdb.gimp_context_get_foreground()
pdb.gimp_context_set_foreground(hilightcolor)
dialog = gtk.Dialog("Shrink/Grow Feather Selection Live Preview", None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
dialog.set_default_size(600, 100)
#color_selection.ok_button.connect("clicked", on_color_ok_button_clicked)
# Create an HBox to hold the label and slider -------------------------------------------------------------
hbox = gtk.HBox()
dialog.vbox.pack_start(hbox, expand=True, fill=True)
# Create a label on the left-hand side
label1 = gtk.Label("Shrink/Grow Radius:")
hbox.pack_start(label1, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment1 = gtk.Adjustment(value=0, lower=-400, upper=400, step_incr=1, page_incr=0)
param1_scale = gtk.HScale(adjustment=adjustment1)
param1_scale.set_digits(0) # Display only integers
hbox.pack_start(param1_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param1_scale.connect("value-changed", on_param1_changed)
# # Create an HBox to hold the label and slider -------------------------------------------------------------
hbox2 = gtk.HBox()
dialog.vbox.pack_start(hbox2, expand=True, fill=True)
# Create a label on the left-hand side
label2 = gtk.Label("Feather Radius:")
hbox2.pack_start(label2, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment2 = gtk.Adjustment(value=0, lower=0, upper=400, step_incr=1, page_incr=0)
param2_scale = gtk.HScale(adjustment=adjustment2)
param2_scale.set_digits(0) # Display only integers
hbox2.pack_start(param2_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param2_scale.connect("value-changed", on_param2_changed)
# Create an HBox to hold the label and integer/float input box =====================================================
hbox4 = gtk.HBox()
dialog.vbox.pack_start(hbox4, expand=True, fill=True)
# Create a label for the integer input
label4 = gtk.Label("Sample Integer:")
hbox4.pack_start(label4, expand=False, fill=False, padding=5)
# Create a text entry for the integer input
entry4 = gtk.Entry()
entry4.set_text(str(sample_integer))
entry4.set_width_chars(5) # Adjust the width of input box as needed
entry4.connect("changed", on_sample_integer_changed)
hbox4.pack_start(entry4, expand=False, fill=False, padding=5)
# Create an HBox to hold the label and color picker button =================
hbox5 = gtk.HBox()
dialog.vbox.pack_start(hbox5, expand=True, fill=True)
# Create a label for the color picker
label5 = gtk.Label("Color Picker:")
hbox5.pack_start(label5, expand=False, fill=False, padding=5)
# Create a color picker button
color_button = gtk.ColorButton()
color_button.set_use_alpha(False) # Set to True if you want to include alpha channel
#default_color = gtk.gdk.Color(65535, 0, 0) # Red in RGB, where values are between 0 and 65535
pdb.gimp_message("set:" + str(chosen_color[0]))
color_button.set_color(gtk.gdk.Color(chosen_color[0]*256, chosen_color[1]*256, chosen_color[2]*256))
color_button.connect("color-set", on_color_changed)
hbox5.pack_start(color_button, expand=False, fill=False, padding=5)
# color_selection.show_all()
# color_selection = gtk.ColorSelectionDialog("Select Color")
# # Run the dialog
# response = color_selection.run()
# # Connect the "clicked" signal after the dialog has been shown
# color_selection.ok_button.connect("clicked", on_color_ok_button_clicked)
# # Check the response and destroy the dialog
# if response == gtk.RESPONSE_OK:
# on_color_ok_button_clicked(color_selection)
# else:
# color_selection.destroy()
# hbox3 = gtk.HBox()
# dialog.vbox.pack_start(hbox3, expand=True, fill=True)
# # Create a label on the left-hand side
# label3 = gtk.Label("iterations:")
# hbox3.pack_start(label3, expand=False, fill=False, padding=5)
# # Create an adjustment for the HScale (slider) with a range from 10 to 90
# adjustment3 = gtk.Adjustment(value=10, lower=1, upper=30, step_incr=1, page_incr=0)
# param3_scale = gtk.HScale(adjustment=adjustment3)
# param3_scale.set_digits(0) # Display only integers
# hbox3.pack_start(param3_scale, expand=True, fill=True, padding=5)
# # Connect callback functions for user interaction
# param3_scale.connect("value-changed", on_param3_changed)
# Add an OK button
ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
ok_button.connect("clicked", on_ok_button_clicked)
# Show the dialog
dialog.show_all()
update_live_preview() #call this once so we see effect
dialog.run()
def on_sample_integer_changed(entry):
global sample_integer
try:
sample_integer = float(entry.get_text()) #int(entry.get_text())
pdb.gimp_message(sample_integer)
update_live_preview()
except ValueError:
# Handle the case where the input is not a valid integer
pass
#need these 2 functions for color picker(s)
def on_color_changed(widget, data=None):
global chosen_color
pdb.gimp_message("ran color")
color = widget.get_color()
chosen_color = (int(color.red/256), int(color.green/256), int(color.blue/256))
pdb.gimp_message(str(chosen_color[0]))
update_live_preview()
# def on_color_ok_button_clicked(dialog, data=None):
# pdb.gimp_message("color clicked")
# global selected_color
# color = color_selection.get_current_color()
# selected_color = (int(color.red * 255), int(color.green * 255), int(color.blue * 255))
# pdb.gimp_message(selected_color[0])
# update_live_preview()
# dialog.destroy()
# Callback function for updating the live preview when param1 changes
def on_param1_changed(scale):
global global_param1
global_param1 = scale.get_value()
update_live_preview()
# Callback function for updating the live preview when param2 changes
def on_param2_changed(scale):
global global_param2
global_param2 = scale.get_value()
update_live_preview()
def on_param3_changed(scale):
global global_param3
global_param3 = scale.get_value()
update_live_preview()
# Callback function for the OK button
def on_ok_button_clicked(button, data=None):
global drawable
apply_final(preview_layer) #preview layer because we don't want to apply the invert to final layer it's just for viewing
button.get_toplevel().destroy() #destroys the gtk dialog window
# Register the Python-Fu plugin
register(
"python_fu_grow_shrink_live",
"Grow/Shrink Current Selection with Live Preview",
"Grow/Shrink Current Selection with Live Preview",
"TT",
"TT",
"NAME",
"<Image>/Python-Fu/Live Preview/Grow-Shrink Live", # Menu location
"*", # Image type
[],
[],
dialog
)
main()
Sun Nov 26, 2023 12:32 am
Sun Nov 26, 2023 10:06 am
#!/usr/bin/env python
#grow-shrink-live.py
# Creator: TT
# This should allow user to adjust grow/shrink current selection with live preview
# Open Source
from gimpfu import *
import gtk
# Global variables to store the parameters used for our effect/work to show preview or actual layer when user OK it
global_param1 = 0 #in this example it's shrinkgrow radius
global_param2 = 0 #in this example it's feather_radius
global_param3 = 10 #in this example it's iterations
global_param4 = 0 #in this example it's enhance_shadows
chosen_color = 0
sample_integer = 13
image = 0 #we'll set these when dialog() is called so that we can access them later
drawable = 0
has_preview = False
preview_layer = 0
#for this operation
selection_channel = 0
proceed_with_changes = False
def apply_effect(layer): #function to do work on either preview layer or actual drawable when user clicks OK
global image
radius = global_param1
feather_radius = global_param2
pdb.gimp_image_select_item(image,CHANNEL_OP_REPLACE,selection_channel) #first we selected the original saved channel
if radius < 0:
pdb.gimp_selection_shrink(image,-radius)
else:
pdb.gimp_selection_grow(image,radius)
pdb.gimp_selection_feather(image,feather_radius)
#do something to it to show it's effect so that user can distinguish between selected area or not
pdb.gimp_drawable_edit_fill(layer,FILL_FOREGROUND)
#pdb.gimp_ellipse_select(image,image.width/2-width/2,image.height/2-height/2,width,height,CHANNEL_OP_REPLACE,TRUE,FALSE,0)
#pdb.gimp_drawable_invert(layer,TRUE)
#pdb.gimp_selection_none(image)
gimp.displays_flush()
def apply_final(layer): #wrapper to apply effect on final and remove preview_layer meant to be called by on_ok_button_clicked
global preview_layer
#pdb.gimp_image_undo_group_start(image) #so it's undone in Ctrl+Z
pdb.gimp_image_undo_enable(image) #so that user can undo this next step
apply_effect(preview_layer)
#pdb.gimp_image_undo_group_end(image)
if has_preview:
pdb.gimp_image_remove_channel(image,selection_channel) #so that we don't leave a saved channel laying around
pdb.gimp_image_remove_layer(image,preview_layer)
pdb.gimp_image_set_active_layer(image,drawable)
pdb.gimp_context_set_foreground(save_foreground)
gimp.displays_flush()
# Function to update the live preview
def update_live_preview(): #this is called everytime some parameter changes
global global_param1, global_param2, global_param3, global_param4
global image,drawable
global has_preview,preview_layer #deal with preview layer
global selection_channel #this will save our current selection
# Apply your plugin's effect using the current parameters
# Use global_param1 and global_param2 to access the user's inputs
if not has_preview: #create a preview layer
#pdb.gimp_message("Creating preview")
preview_layer = pdb.gimp_layer_new(image,image.width,image.height,RGBA_IMAGE,"preview",70,LAYER_MODE_NORMAL)
pdb.gimp_image_insert_layer(image,preview_layer,None,0) #insert top most so we see it
non_empty,x1,y1,x2,y2 = pdb.gimp_selection_bounds(image)
if non_empty == TRUE:
pass #there's already a selection
else:
pdb.gimp_selection_all(image) #if there's no selection we just select the whole image and work with that
selection_channel = pdb.gimp_selection_save(image)
has_preview = True #now set it true so we can deal with existing layer in later calls
else: # already have preview layer
pass
#pdb.gimp_message("Removing existing and creating new Preview")
pdb.gimp_image_remove_layer(image,preview_layer) #remove it to create a new one to work on
preview_layer = pdb.gimp_layer_new(image,image.width,image.height,RGBA_IMAGE,"preview",50,LAYER_MODE_NORMAL)
pdb.gimp_image_insert_layer(image,preview_layer,None,0) #insert top most so we see it
pdb.gimp_image_set_active_layer(image,preview_layer)
#debug message
#pdb.gimp_message(str(global_param1)+","+str(global_param2)+","+str(global_param3)+","+str(global_param4))
apply_effect(preview_layer)
# Update the live preview layer with the modified image
save_foreground = 0
hilightcolor = (255,0,0)
def dialog(image_, drawable_):
global image, drawable, save_foreground
if chosen_color==0:
global chosen_color
chosen_color = (0, 128, 255) # Set default color
#save these for updates
image = image_
pdb.gimp_image_undo_disable(image) #for speed and also when user undo it doesn't see our preview creations/deletions
drawable = drawable_
save_foreground = pdb.gimp_context_get_foreground()
pdb.gimp_context_set_foreground(hilightcolor)
dialog = gtk.Dialog("Shrink/Grow Feather Selection Live Preview", None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
dialog.set_default_size(600, 100)
#color_selection.ok_button.connect("clicked", on_color_ok_button_clicked)
# Create an HBox to hold the label and slider -------------------------------------------------------------
hbox = gtk.HBox()
dialog.vbox.pack_start(hbox, expand=True, fill=True)
# Create a label on the left-hand side
label1 = gtk.Label("Shrink/Grow Radius:")
hbox.pack_start(label1, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment1 = gtk.Adjustment(value=0, lower=-400, upper=400, step_incr=1, page_incr=0)
param1_scale = gtk.HScale(adjustment=adjustment1)
param1_scale.set_digits(0) # Display only integers
hbox.pack_start(param1_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param1_scale.connect("value-changed", on_param1_changed)
# # Create an HBox to hold the label and slider -------------------------------------------------------------
hbox2 = gtk.HBox()
dialog.vbox.pack_start(hbox2, expand=True, fill=True)
# Create a label on the left-hand side
label2 = gtk.Label("Feather Radius:")
hbox2.pack_start(label2, expand=False, fill=False, padding=5)
# Create an adjustment for the HScale (slider) with a range from 10 to 90
adjustment2 = gtk.Adjustment(value=0, lower=0, upper=400, step_incr=1, page_incr=0)
param2_scale = gtk.HScale(adjustment=adjustment2)
param2_scale.set_digits(0) # Display only integers
hbox2.pack_start(param2_scale, expand=True, fill=True, padding=5)
# Connect callback functions for user interaction
param2_scale.connect("value-changed", on_param2_changed)
# Create an HBox to hold the label and integer/float input box =====================================================
hbox4 = gtk.HBox()
dialog.vbox.pack_start(hbox4, expand=True, fill=True)
# Create a label for the integer input
label4 = gtk.Label("Sample Integer:")
hbox4.pack_start(label4, expand=False, fill=False, padding=5)
# Create a text entry for the integer input
entry4 = gtk.Entry()
entry4.set_text(str(sample_integer))
entry4.set_width_chars(5) # Adjust the width of input box as needed
entry4.connect("changed", on_sample_integer_changed)
hbox4.pack_start(entry4, expand=False, fill=False, padding=5)
# Create an HBox to hold the label and color picker button =================
hbox5 = gtk.HBox()
dialog.vbox.pack_start(hbox5, expand=True, fill=True)
# Create a label for the color picker
label5 = gtk.Label("Color Picker:")
hbox5.pack_start(label5, expand=False, fill=False, padding=5)
# Create a color picker button
color_button = gtk.ColorButton()
color_button.set_use_alpha(False) # Set to True if you want to include alpha channel
#default_color = gtk.gdk.Color(65535, 0, 0) # Red in RGB, where values are between 0 and 65535
pdb.gimp_message("set:" + str(chosen_color[0]))
color_button.set_color(gtk.gdk.Color(chosen_color[0]*256, chosen_color[1]*256, chosen_color[2]*256))
color_button.connect("color-set", on_color_changed)
hbox5.pack_start(color_button, expand=False, fill=False, padding=5)
#toggle button ==============
hbox6 = gtk.HBox()
dialog.vbox.pack_start(hbox6, expand=True, fill=True)
label6 = gtk.Label("Sample Toggle:")
hbox6.pack_start(label6, expand=False, fill=False, padding=5)
toggle_button = gtk.ToggleButton()
# Set initial label
update_toggle_button_label(toggle_button)
# Connect the toggle event
toggle_button.connect("toggled", on_toggle_button_toggled)
hbox6.pack_start(toggle_button, expand=False, fill=False, padding=5)
#Combo box ===================================
hbox7 = gtk.HBox()
dialog.vbox.pack_start(hbox7, expand=True, fill=True)
label7 = gtk.Label("Sample Choice:")
hbox7.pack_start(label7, expand=False, fill=False, padding=5)
toggle_button = gtk.ToggleButton()
# Create a ComboBox
combo_box = gtk.ComboBox()
hbox7.pack_start(combo_box, expand=False, fill=False, padding=5)
# Create a ListStore model for ComboBox
list_store = gtk.ListStore(str)
options = ["Option 1", "Option 2", "Option 3"] # Add your options here
for option in options:
list_store.append([option])
# Set the model for ComboBox
combo_box.set_model(list_store)
# Create a CellRendererText to render the text in the ComboBox
cell_renderer = gtk.CellRendererText()
# Pack the CellRendererText into the ComboBox
combo_box.pack_start(cell_renderer, True)
combo_box.add_attribute(cell_renderer, 'text', 0)
# Set up the "changed" signal handler
combo_box.connect("changed", on_combobox_changed)
# Set the default option to "Option 1" ======================================
default_option = "Option 1"
default_iter = list_store.get_iter_first()
while default_iter is not None:
if list_store.get_value(default_iter, 0) == default_option:
combo_box.set_active_iter(default_iter)
break
default_iter = list_store.iter_next(default_iter)
#===========================================================================
# color_selection.show_all()
# color_selection = gtk.ColorSelectionDialog("Select Color")
# # Run the dialog
# response = color_selection.run()
# # Connect the "clicked" signal after the dialog has been shown
# color_selection.ok_button.connect("clicked", on_color_ok_button_clicked)
# # Check the response and destroy the dialog
# if response == gtk.RESPONSE_OK:
# on_color_ok_button_clicked(color_selection)
# else:
# color_selection.destroy()
# hbox3 = gtk.HBox()
# dialog.vbox.pack_start(hbox3, expand=True, fill=True)
# # Create a label on the left-hand side
# label3 = gtk.Label("iterations:")
# hbox3.pack_start(label3, expand=False, fill=False, padding=5)
# # Create an adjustment for the HScale (slider) with a range from 10 to 90
# adjustment3 = gtk.Adjustment(value=10, lower=1, upper=30, step_incr=1, page_incr=0)
# param3_scale = gtk.HScale(adjustment=adjustment3)
# param3_scale.set_digits(0) # Display only integers
# hbox3.pack_start(param3_scale, expand=True, fill=True, padding=5)
# # Connect callback functions for user interaction
# param3_scale.connect("value-changed", on_param3_changed)
# Add an OK button
ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
ok_button.connect("clicked", on_ok_button_clicked)
# Show the dialog
dialog.show_all()
update_live_preview() #call this once so we see effect
dialog.run()
def on_combobox_changed(combobox):
global selected_option
model = combobox.get_model()
active_iter = combobox.get_active_iter()
if active_iter:
selected_option = model.get_value(active_iter, 0)
pdb.gimp_message("Selected option:" + str(selected_option))
def on_toggle_button_toggled(button):
global proceed_with_changes
proceed_with_changes = not proceed_with_changes
pdb.gimp_message("Sample toggle result:" + str(proceed_with_changes))
update_toggle_button_label(button)
def update_toggle_button_label(button):
label = "Yes" if proceed_with_changes else "No"
button.set_label(label)
def on_sample_integer_changed(entry):
global sample_integer
try:
sample_integer = float(entry.get_text()) #int(entry.get_text())
pdb.gimp_message(sample_integer)
update_live_preview()
except ValueError:
# Handle the case where the input is not a valid integer
pass
#need these 2 functions for color picker(s)
def on_color_changed(widget, data=None):
global chosen_color
pdb.gimp_message("ran color")
color = widget.get_color()
chosen_color = (int(color.red/256), int(color.green/256), int(color.blue/256))
pdb.gimp_message(str(chosen_color[0]))
update_live_preview()
# def on_color_ok_button_clicked(dialog, data=None):
# pdb.gimp_message("color clicked")
# global selected_color
# color = color_selection.get_current_color()
# selected_color = (int(color.red * 255), int(color.green * 255), int(color.blue * 255))
# pdb.gimp_message(selected_color[0])
# update_live_preview()
# dialog.destroy()
# Callback function for updating the live preview when param1 changes
def on_param1_changed(scale):
global global_param1
global_param1 = scale.get_value()
update_live_preview()
# Callback function for updating the live preview when param2 changes
def on_param2_changed(scale):
global global_param2
global_param2 = scale.get_value()
update_live_preview()
def on_param3_changed(scale):
global global_param3
global_param3 = scale.get_value()
update_live_preview()
# Callback function for the OK button
def on_ok_button_clicked(button, data=None):
global drawable
apply_final(preview_layer) #preview layer because we don't want to apply the invert to final layer it's just for viewing
button.get_toplevel().destroy() #destroys the gtk dialog window
# Register the Python-Fu plugin
register(
"python_fu_grow_shrink_live",
"Grow/Shrink Current Selection with Live Preview",
"Grow/Shrink Current Selection with Live Preview",
"TT",
"TT",
"NAME",
"<Image>/Python-Fu/Live Preview/Grow-Shrink Live", # Menu location
"*", # Image type
[],
[],
dialog
)
main()