POC: Toggle operator with info

After using various toggling shortcuts for a while I found it difficult enough for not getting proper information about what is active or not.

So I tried to wrap the wm.context_toggle in a new notification operation for that reason.

As for example not getting proper information about the state of settings:

  • When the UI is not immediately redrawn | mirror x
  • When UI elements are well hidden | correct uvs transform
  • Sometimes you might get a clue about the state | sculpt falloff projected-sphere -or- transform origins

In any of these cases (you dont know / you guess) you just toggle the setting on-off and get informed right away.

bl_info = {
	'name'        : 'Extra Shortcuts',
	'description' : '',
	'location'    : 'System',
	'category'    : 'User',
	'author'      : 'const',
	'version'     : (0, 210814),
	'blender'     : (2, 93, 0),
}

import bpy

class ExtraShortcutSettings(bpy.types.AddonPreferences):
	bl_idname = __name__
	def draw(self, context):
		layout = self.layout
		row = layout.column(align=True)
		for km in Keymap.strings:
			row.label(text=km)

class ContextToggleInfo(bpy.types.Operator):
	bl_idname = 'wm.context_toggle_info'
	bl_label = 'Toggle Property Info'
	bl_description = 'Toggle property with info report'
	bl_context = 'scene'
	bl_options = {'INTERNAL'}

	data_path : bpy.props.StringProperty('Property')
	info : bpy.props.StringProperty('Info')
	value1 : bpy.props.StringProperty('Value1')
	value2 : bpy.props.StringProperty('Value2')
	
	def execute(self, context):
		if self.data_path == '': return {'FINISHED'}

		if len(self.value1) > 0 and len(self.value2) > 0:
			bpy.ops.wm.context_toggle_enum(data_path=self.data_path, value_1=self.value1, value_2=self.value2)
		else:
			bpy.ops.wm.context_toggle(data_path=self.data_path)

		info = self.info if len(self.info) > 0 else self.data_path.split('.')[-1]
		value = eval(f'context.{self.data_path}')
		message = info + ' : ' + str(value)
		self.report({'INFO'}, message)

		return {'FINISHED'}

class Keymap:
	registered_keymaps = []
	strings = []

	def register():
		wm = bpy.context.window_manager
		kc = wm.keyconfigs.addon
		strings = Keymap.strings

		strings.append('OBJECT')
		km = kc.keymaps.new(name='Object Mode')

		strings.append('alt+c : toggle object-origin transform')
		kmi = km.keymap_items.new('wm.context_toggle_info', 'C', 'PRESS', alt=True)
		kmi.properties.data_path = 'tool_settings.use_transform_data_origin'
		kmi.properties.info = 'Transform Only Origin'

		# ====

		strings.append('SCULPT')
		km = kc.keymaps.new(name='Sculpt')

		strings.append('alt+x : toggle mirror x')
		kmi = km.keymap_items.new('wm.context_toggle_info', 'X', 'PRESS', alt=True)
		kmi.properties.data_path = 'object.use_mesh_mirror_x'
		kmi.properties.info = 'Mirror X'
		
		strings.append('alt+s : toggle falloff shape')
		kmi = km.keymap_items.new('wm.context_toggle_info', 'S', 'PRESS', alt=True)
		kmi.properties.data_path = 'tool_settings.sculpt.brush.falloff_shape'
		kmi.properties.info = 'Falloff Shape'
		kmi.properties.value1 = 'SPHERE'
		kmi.properties.value2 = 'PROJECTED'
		
		# ====

		strings.append('MESH')
		km = kc.keymaps.new(name='Mesh')

		strings.append('alt+c : [object] toggle correct uv transform')
		kmi = km.keymap_items.new('wm.context_toggle_info', 'C', 'PRESS', alt=True)
		kmi.properties.data_path = 'tool_settings.use_transform_correct_face_attributes'
		kmi.properties.info = 'Correct UV'

		# ====

		Keymap.registered_keymaps.append((km, kmi))

	def unregister():
		for km, kmi in Keymap.registered_keymaps:
			km.keymap_items.remove(kmi)
		Keymap.registered_keymaps.clear()
		Keymap.strings.clear()

def register():
	bpy.utils.register_class(ContextToggleInfo)
	bpy.utils.register_class(ExtraShortcutSettings)
	Keymap.register()

def unregister():
	bpy.utils.unregister_class(ContextToggleInfo)
	bpy.utils.unregister_class(ExtraShortcutSettings)
	Keymap.unregister()

if __name__ == '__main__':
	register()

Only one downside you might consider is that your info log might get spammed, if you don’t prefer this happen you just switch to the default wm operators instead. One other possible solution would be to use a BGL onscreen message, though is just a matter of appearance, in terms of practicality it works fine as of now.

This message is only a hint so you can just consider trying it. I found this modification really helpful for my daily use and can’t go back. :slight_smile: