Add/remove EnumProperty items?

I see some people seek for same answers I was seeking before. Here simple (relatively) addon with two buttons for adding/removing enum items.

Just save this as .py file and install as addon, you will have tab on N panel “Example Enum”. I also left descriptions in code, hope it will help you seeker.

bl_info = {
	"name": "Enum Example Addon",
	"author": "IIIFGIII",
	"version": (1),
	"blender": (2, 83, 0),
	"location": "Viev3D > N panel > Example Enum",
	"description": "",
	"warning": "",
	"wiki_url": "",
	"category": "",
}

import bpy, mathutils
bpr = bpy.props

data_for_enum = []

	# data_for_enum - variable to store data for enum items. 
	# in this example I used list with tuples of string and object location vector (because why not)
	# name will be used to manage enum and show in UI, location value will be used for description popup

	# it actually can be anything you want to use in your particular case to generate tuples for enum
	# literally any thing you find handy in your case to use - solid string, list, list of lists, dictionary... any


def enum_items_generator(self,context):
	enum_items = []
	for e,d in enumerate(data_for_enum):
		enum_items.append((d[0], d[0], 'Position value = ' + str(d[1]), e))
		# as you see for each tuple in my list I use [0] item to generate enum value/name and [1] item for description + integer from enumerate for id
	return enum_items

	# key thing here is you want to output list of tuples [(),(),(),()]
	# that contain proper data ('string','string','string',integer)
	# first  - value you can get later (when I do later in my addon eea.presets) when you want to get your current enum value
	# second - display name of enum item, can be different that first string
	# third  - description (can be empty, just '')
	# fourth - id for blender


def report(self,message): # Just to report errors
	self.report({'ERROR'}, message)
	return{'CANCELLED'}

class EEA_PT_Example_Enum_Panel(bpy.types.Panel):
	bl_label = 'Example Enum Panel'
	bl_idname = 'EEA_PT_Example_Enum_Panel'
	bl_space_type = 'VIEW_3D'
	bl_region_type = 'UI'
	bl_category = 'Example Enum'

	def draw(self, context):
		layout = self.layout
		col = layout.column(align=True)
		eea = context.scene.eea_props

		col.prop(eea, 'presets', text= '')
		row = col.row(align=True)
		row.operator('eea.eea_enum_add', text= 'Add')
		row.operator('eea.eea_enum_remove', text= 'Remove')



class EEA_OT_Enum_Add(bpy.types.Operator):
	bl_idname = 'eea.eea_enum_add'
	bl_label = 'EEA_OT_Enum_Add'
	bl_description = 'Add new enum item'

	new_name: bpy.props.StringProperty(default= 'Preset name', name = 'Preset name ')

	def execute(self, context):
		global data_for_enum

		eea = context.scene.eea_props
		aob = context.view_layer.objects.active

		if aob == None: # For case when there is no active object
			return report(self,'No active object selected!!!')

		data_for_enum.append((self.new_name, mathutils.Vector(aob.matrix_world.col[3][:3]))) # here I append to data_for_enum new tuple
		data_for_enum = sorted(data_for_enum, key=lambda e : e[0]) # a bit of sorting by name

		eea.presets = self.new_name # here I set my preset value to match value I just added (will refresh when mouse over panel UI)

		return{'FINISHED'}

	def invoke(self, context, event):
		return context.window_manager.invoke_props_dialog(self, width=200)




class EEA_OT_Enum_Remove(bpy.types.Operator):
	bl_idname = 'eea.eea_enum_remove'
	bl_label = 'EEA_OT_Enum_Remove'
	bl_description = 'Remove current enum item'

	def execute(self, context):
		global data_for_enum

		eea = context.scene.eea_props

		if len(data_for_enum) != 0:
			did = [x[0] for x in data_for_enum].index(eea.presets) # I search for index of current enum in my list [0] items of my tuples 
			data_for_enum.pop(did) # I pop out item with this index from my list

			# at this moment my list is already changed and enum already regenereted

			if did>len(data_for_enum)-1 and data_for_enum != []: # here I set enum to value of my list last item in case when I remove last enum item, othervise active enum become empty :)
				eea.presets = data_for_enum[len(data_for_enum)-1][0]

		else: return report(self,'No more items to remove')
		return{'FINISHED'}

class EEA_PR_Properties(bpy.types.PropertyGroup):

		presets: bpr.EnumProperty(items = enum_items_generator, name = 'Position Preset')


ctr = [
	EEA_PT_Example_Enum_Panel,
	EEA_OT_Enum_Add,
	EEA_OT_Enum_Remove,
	EEA_PR_Properties
]

def register():
	for cls in ctr: 
		bpy.utils.register_class(cls)
	bpy.types.Scene.eea_props = bpy.props.PointerProperty(type= EEA_PR_Properties)

def unregister():
	for cls in reversed(ctr): 
		bpy.utils.unregister_class(cls)
	del bpy.types.Scene.eea_props
2 Likes