For clarity, the previous question I asked was closed so I made this one, its now reopened and both are asking basically the same question.
I have a fixed list of RGB values which I want to display to the user inside a panel, when they click on a color I need to run an operator. In a previous question I asked (which was poorly formulated by me) I got a reply from @pyCod3R which showed a palette item which visually looks like what I want but has a few limitations.
Image showing the template_node_socket
and palette created by the code below
- The list is a fixed length, in the palette there are
+
,-
signs allowing the user to add/remove indices to the list which would need to be disabled for it to be a viable option in this case - When a color is clicked by the user I need to run an operator, which doesn't seem to be possible with a palette
- Ideally the coloured squares would be larger than the small circles created by
template_node_socket
, the palette squares are perfect in size
This code is adapted from the answer @pyCod3R gave in the previous question:
import bpy
import random
class ColorDemoPanel(bpy.types.Panel):
"""Creates a Panel in the 3d viewport"""
bl_label = "Color List Display"
bl_idname = "MATERIAL_PT_colorlist"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
def draw(self, context):
layout = self.layout
#the template_node_socket way to display a color is very limited
#the color is a small circle and cant be clicked so I have to add a separate button
for i in range(5):
row = layout.row(align = True)
r = random.random()
g = random.random()
b = random.random()
row.template_node_socket(color=(r, g, b, 1.0))
#just a demo operator, not what I'd actually use
row.operator("object.transform_apply", text = "Color")
#the palette way is a lot cleaner visually but I need the list to be of fixed length
#buttons allowing the user to add or remove indices from the list isnt possible to remove afaik
#there doesnt seem to be a way to call a function when a color is clicked either, which I need
ts = context.tool_settings
palette = ts.image_paint.palette
sel_r, sel_g, sel_b = palette.colors.active.color
if ts.image_paint.palette:
layout.template_palette(ts.image_paint, "palette", color=True)
def register():
bpy.utils.register_class(ColorDemoPanel)
def unregister():
bpy.utils.unregister_class(ColorDemoPanel)
if __name__ == "__main__":
register()
# Add a new pallete
pal = bpy.data.palettes.get("CustomPalette")
if pal is None:
pal = bpy.data.palettes.new("CustomPalette")
# Add a single color
red = pal.colors.new()
red.color = (1, 0, 0)
# Add random colors to the palette
from random import random
for i in range(10):
col = pal.colors.new()
col.color = (random(), random(), random())
# Make red the active/selected color
pal.colors.active = red
ts = bpy.context.tool_settings
ts.image_paint.palette = pal
Is there some way to adapt a palette or template_node_socket
to my needs or is there some other way to display clickable RGB squares that I've missed?