A boolean in IMAGE_EDITOR UI

okay…

gonna talk about shitty python interface.

In unity:
my_bool = the_interface.toggle(my_bool, the_format_i_wanna_the_interface_to_look_like);

1 line of code
in blender ?

sorry i cannot post a pile of shit :stuck_out_tongue:

i cannot believe this is not as simple in python as it is in unity C#
7 hours of struggling here and on the web and i was unable to find how to toggle a fuc**n flag in IMAGE_EDITOR UI !!!

please guys ! show me how stoopid i am with the 2… 3 ??? lines of code needed for this !

and remember !
simplicity is the best sophistication !

help !!!

happy blending !

There’s a lot involved in changing blender interface.
luckly you can just copy and paste a lot of code that dont ever change and just modify what you want.

Read this:
https://docs.blender.org/api/blender2.8/bpy.types.Panel.html

but before you must read this:
https://docs.blender.org/api/blender2.8/info_quickstart.html

after you get it all you can start digging into the functions avaliable at the UIlayout class:
https://docs.blender.org/api/blender2.8/bpy.types.UILayout.html

simple example:

def register():
    bpy.types.Scene.my_custom_boolean = bpy.props.BoolProperty()
def draw(self, context):
    ui_layout = self.layout
    ui_layout.prop(context.scene, "my_custom_boolean", toggle=If_i_want_it_to_look_like_a_toogle)

of course @Jeacom :slight_smile:
i wanna pilot an A380 airbus before i learned to walk :stuck_out_tongue:
i think it’s all my life’s story x))

i gonna dig on your links !!! for wich i thank you VERY MUCH !!!
python in itself is not a real problem for me. i used to learn languages specs quite easily in the past, and tho i’m becoming old, the mind is still there :stuck_out_tongue:

my prob is blender API. I confess i’m used with unity api wich is undecently well documented, clear and full of examples.

Am not sure the kind of simple thingie i wanna do can appeal curious ppl, but i’ll post the results of my struggles in another post that i started for askin help on changing the pic display in image editor window.

thanks a lot for your lines and links and be sure i be back soon !
grumbling or laughing :wink:

happy blending !

frankly…

blender doc is shitty.

In the past i used to write some doc for many things. The hardest thing was to make things clear and usefull. Blender docs is just a bunch of useless crap. sorry ^^
okay. take this one:
https://docs.blender.org/api/blender_python_api_2_77_0/bpy.types.UILayout.html
UILayout…
active
alert
aligment
enabled…
what is all this ?
member vars ? methods ? globals ? fruits i gotta buy at grocer’s ?
where and how to access this ?
no doubt i don’t know how devs organized theyr classes/data and no doubt they are properly defined but.
the doc ! is just a diarrhea of useless text filling a badly thought wiki/website ^^

PLEAAAAAAAAAAAAAAAAAAAASE !!! blender devs ! have a look at unity’s API !!! and take lessons !
tens of thousands pps write c# in unity. why ? because docs is usable and usefull. how many tens of thousands ppl write for blender ?
this pisses me off because a good API doc could propell blender far ahead.
okay. after the useless grumbling… :wink:

this:

import bpy


class SelectabilityTogglePanel:
    bl_label = "this is a stoopid label"
    bl_idname = "what is ID name used for ?"
    bl_space_type = 'IMAGE_EDITOR'
    bl_region_type = 'UI'

def draw(self, context):
    ui_layout = self.layout
    ui_layout.prop(context.scene, "my_custom_boolean", toggle=true)

def register():
    bpy.types.Scene.my_custom_boolean = bpy.props.BoolProperty()


if __name__ == "__main__":
    register()

just simply do nothing.

obviously am missing something, and above all API knowledge but. for beeing honest i just don’t wanna waste 6 months learning things from an obfuscated codex for just… a fuc**ng boolean !

if things cannot be done i blender ( because devs keep theyr voodoo ) no matter i’ll do it in unity ^^
IMHO it’s just a shame… but if it’s devs desire… i’ll conform.

I’ll still dig for some few time on this, beeing sure i’ll never search for doing nice things in blender ( as it’s just unwelcome ) but am not even sure that what i wanna do can be done without wasting time on obfuscated and uncatchable code.

I however cherish the hope am wrong. but without belief.

happy blending ( if you’re not coding ) !

calm down… your code is mostly correct but the four mistakes you made shows that you are still learning python so don’t worry, maybe you should try to learn about classes, inheritance, python stuff and maybe a bit of patience before diving into blender scripting.

First, you should be familiar with the following line:

using UnityEngine;

in blender there’s also an equivalent:

import bpy

bpy is the main blender module, you can think on it as the library that links python to blender and you cant call any bpy.something without importing bpy first.

Depending on what you are doing you might also want to import other modules like:

import math # math helper functions like sqrt() and round()
import mathutils # blender math stuff like Vector, Matrix, Geometry
import bmesh # mesh editing helper module
import numpy # module for fast parallel math used to vectorize lots of algorithms
import json # python's json dumper and loader
import os # operating system stuff like opening files, navigating through folders

Now that you get what imports are lets move on to the basics of identation:

As you might have guessed, since python don’t use brackets, indentation matters.

class A:
    variable_in_class = 5
    def my_method():
        print("I am inside class A")

class B:
    variable_in_class = 5
def my_method():
    print("I am not inside class B")

A.my_method() # prints: I am inside class A
B.my_method() # AttributeError: type object "B" has no attribute "my_method"

Basic inheritance

In python you can define a base class and use it to create other classes instead of repeating yourself over and over by writing the same thing

class Animal: # an generic animal class
  species = "Animal"
  sound = None
  eats = None

  def what_species(self):
    print("I'm a " + self.species)

  def talk(self):
    print(self.sound)

  def eat(self):
    print("yum Yumm, i'm eating " + self.eats)


class Monkey(Animal): # Monkey inherits animal methods and vars
  species = "Chimp"
  sound = "Hu Hhu Hu Ha"
  eats = "bananas"
  # No need to define methods here since Animal class already have

class Dog(Animal): # same as monkey but its a dog
  species = "Dog"
  sound = "Woof Woof"
  eats = "beef"
  # No need to define methods here since Animal class already have


my_monkey = Monkey()

my_monkey.what_species()
my_monkey.talk()
my_monkey.eat()

my_dog = Dog()

my_dog.what_species()
my_dog.talk()
my_dog.eat()


# output:
# I'm a Chimp
# Hu Hhu Hu Ha
# yum Yumm, i'm eating bananas
# I'm a Dog
# Woof Woof
# yum Yumm, i'm eating beef

Now that you get all this, you should be able to spot the difference from your code to the correct code:

import bpy # Never forget to import bpy

# class SelectabilityTogglePanel:

class SelectabilityTogglePanel(bpy.types.Panel): # It iherits from Panel Class
    bl_label = "this is a stoopid label"
    bl_idname = "MYADDON_PT_this_is_the_panel_id" # Its for internal organization
    bl_space_type = 'IMAGE_EDITOR'
    bl_region_type = 'UI'
    bl_category = 'Name Of My Tab'
    
    # Pay attention to indentation!
    def draw(self, context):
        ui_layout = self.layout
        # ui_layout.prop(context.scene, "my_custom_boolean", toggle=true)
        ui_layout.prop(context.scene, "my_custom_boolean", toggle=True) # True is uppercase T

def register():
    # You forgot to register your panel
    bpy.utils.register_class(SelectabilityTogglePanel) 

    bpy.types.Scene.my_custom_boolean = bpy.props.BoolProperty()


if __name__ == "__main__":
    register()

awww !!! i love this kind of lesson @Jeacom !!!

i’ll take time on your post and thank you much for it :))
i got OO languages knowledge but… i hardly catch untyped ones :confused:

i did ! and i confess this bothers me a lot XD
but okay… i’ll accept this :))
( just am wonderin how tabs and spaces are handled as they are not lookin the same in editors ^^
but okay… i’ll put spaces )

thx again ! call you soon and…

EDIT:
awwww…
noooob !!! am a damn noob :((
allright indentation imports and the code i posted is… a nonsense x))
i beg your pardon as i write code with brackets since 30 years :confused:

now… i just copied/pasted your few lines in blender, hit RUN and…

MAGIIIIIIIIIIIIIIC !!! a button appears in image_editor N bar !!!

great !!! this brings me bunch of questions !
I love this lil piece of code as it’s very simple :slight_smile:

questions:

  • what is the bl_category for ?
  • i guess bl_idname matters even if unused ( yet ) here
  • where do you find “SelectabilityTogglePanel” class, inheritance, members, statics, methods, etc ? ( i confess i did not catch all in the code i pasted ) am lost. sincerely ! in the docs of the bpy API
  • I hardly imagine a language that ‘interprets’ blah.blah.my_custom_boolean set up with thingie(parm1,parm2,“my_custom_boolean”, etc… ) ( ahah am too old i guess but it’s fun :stuck_out_tongue: )
    looks like some delegates but… shit ! i’m an assembly and C programmer ! XD
  • easy ( as i’ll look for this on myself ) question: how do you show the button as a toggle in UI ?
  • okay for the T of True ^^ —> lack of python knowledge…

@Jeacom i wonder how i can thank you !!! i learned more in 30 minutes with your 10 lines than in 2 days with all the web !!!
sincerely am as much ashamed as happy ! THANK YOU VERY VERY MUCH !
but be sure i’ll be back soon here :stuck_out_tongue:

have a very nice evening ! ( in france it’s evening atm )

EDIT:
Okay. as usual, many things are a matter of semantics :*(
i use to talk about ‘toggle’ and what i wanna have is a checkbox.
toggle is the ‘old’ name of this lil box with a check in it :confused: ( again… am too old and did not move with terms evolutions :confused: )
… still digging as i wanna understand all those basic thingies :wink:

happy blending :slight_smile:

bl_idname is used by blender to save the class in its internal types (bpy.types), if its not there blender won’t know how to use the class. it follows the pattern of:

"MY_ADDON_NAME_PT_panel_name" for panels
"MY_ADDON_NAME_MT_menu_name" for menus
"my_addon_name_OT_operator_name" for tools
https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API/Addons

I know this is weird but no one is gonna change it singe there’s a lot of backwards compatibility involved

in python the distinction between statics and class members kinda melts down so you don’t have to worry too much about it.
But about the members of the Panel class that SelectabilityTogglePanel inherits from, here it is:
https://docs.blender.org/api/blender2.8/bpy.types.Panel.html#bpy.types.Panel

bpy.types.Scene.my_custom_bool = bpy.props.BoolProperty()
Actually you can think as the following:
types.Scene is kinda a baseclass as any other which is instanced as an scene on a blend file a blend file can save multiple instances of the scene class.

what you are doing is altering the base Scene calss and adding your own custom member, as a variable called my_custom_bool and pointing it to an instance of a BoolProperty() type, this BoolProperty instance can take parameters that configure how it behaves, it can have a label for UI drawing, an update callback, get and set methods, a default value and other stuff.
https://docs.blender.org/api/blender2.8/bpy.props.html?highlight=boolproperty#bpy.props.BoolProperty

You might be talking about the toggle argument in the prop() call, try to set it to False

Yes, I had so much trouble with this too LOL.

And also, age generally is not the cause for struggling with python, I started with JS and when moving to python was also a pain deep in the soul, I took a whole 3 years to get used with it, I am 19 and still learning.

wow !
all this makes sense !!!
am feeling the ‘trigger’ coming, wich will make me feel the language and the structure underneath :))
this happened to me when i was 11 and understood the link between Hex data and assembly opcodes on an Amstrad CPC464 XD.
you’re a great teacher @Jeacom and you’re 19 XD
sincerely i bend my knee and thank you very much :))
i’m 49 and just like you are, still learning :slight_smile:

My hope is that all that we wrote here will serve/help ppl struggling in blender’s API forest :slight_smile:
thx again for your great and kind help and be sure i be back soon with lots of questions :stuck_out_tongue:

Best regards.

Happy blending !

1 Like

thx buddy.

This thread is just one more tree in the forest of google results about blender API too LOL.

nah
it’s one milestone tree in this forest ^^

:wink:

Finally :slight_smile:

i got this simple few lines:

import bpy # Never forget to import bpy



class SelectabilityTogglePanel(bpy.types.Panel): # It iherits from Panel Class
    bl_label = "My way to draw image"
    bl_idname = "MYADDON_PT_this_is_the_panel_id" # Its for internal organization
    bl_space_type = 'IMAGE_EDITOR'
    bl_region_type = 'UI'
    bl_category = 'Name Of My Tab'
    
    # Pay attention to indentation!
    def draw(self, context):
        ui_layout = self.layout
        ui_layout.prop(context.scene, "my_custom_boolean", toggle=False) # True is uppercase T

  
    
    


def toggled(self, context):
    print("hello",self.my_custom_boolean)
    return  

def register():
    # You forgot to register your panel
    bpy.utils.register_class(SelectabilityTogglePanel) 

    bpy.types.Scene.my_custom_boolean = bpy.props.BoolProperty(update=toggled)


if __name__ == "__main__":
    register()

I like it when it’s simple :slight_smile:

it creates a toggle in image N bar, and calls a print with the bool value at each change.

It’s perfect and exactly what i needed :smiley:
now i just have to replace the print with my piece of code and voilà !

thx again @Jeacom !

and happy blending ( and pythonning ^^ ) !

EDIT: for those wondering what i wanna do in image viewer: it’s just some colors manipulation.

import bpy # Never forget to import bpy



class SelectabilityTogglePanel(bpy.types.Panel): # It iherits from Panel Class
    bl_label = "My way to draw image"
    bl_idname = "MYADDON_PT_this_is_the_panel_id" # Its for internal organization
    bl_space_type = 'IMAGE_EDITOR'
    bl_region_type = 'UI'
    bl_category = 'Name Of My Tab'
    
    # Pay attention to indentation!
    def draw(self, context):
        ui_layout = self.layout
        ui_layout.prop(context.scene, "my_custom_boolean", toggle=False) # True is uppercase T

  
    
    

def toggled(self, context):

    img = bpy.data.images[0]
    print("x=",img.size[0])
    print("y=",img.size[1])

    pixels = list(img.pixels) # tuple ??? wtf does this mean ???? XD
       
    for i in range(0, len(pixels), 4):
          pixels[i]  =1.0-pixels[i]       # red
          pixels[i+1]=1.0-pixels[i+1]     # green
          pixels[i+2]=1.0-pixels[i+2]     # bloo
          pixels[i+3]=1.0                 # A
       
    img.pixels[:] = pixels
    img.update()
    
    return  

def register():
    bpy.utils.register_class(SelectabilityTogglePanel) 
    bpy.types.Scene.my_custom_boolean = bpy.props.BoolProperty(update=toggled)


if __name__ == "__main__":
    register()

Nice! I took so much time to get what that update argument did.

Also, I suspect the image pixels are in the numpy array format. Maybe its worth to learn numpy since its ridiculously faster than python loops.

ahah XD i obviously have lots of things to learn !!!

numpy… hmm another voodoo word :slight_smile:

i’ll google this for sure ! but now am struggling with the ‘modulo’ math node that don’t work like i want :confused:
even if i alrdy got the answer.

thx a lot @Jeacom

happy blending

    pixels = list(img.pixels) # tuple ??? wtf does this mean ???? XD

tuples are immutable lists that no matter what, if the content in two tuples is identical they are the same object in memory (Hashtable voodoo), as opposite to lists that even if exact duplicates they might be different objects.

in python you have two equality operators “==” and “is”, “==” checks if two objects are equivalent while “is” checks if who objects are the same in memory:

(1, 2, 3) == (1, 2, 3) # True, tuple
(1, 2, 3) is (1, 2, 3) # True, tuple
[1, 2, 3] == [1, 2, 3] # True, list
[1, 2, 3] is [1, 2, 3] # False, list

also, here’s your update callback written using numpy:

def toggled(self, context):

    img = bpy.data.images[0]
    print("x=",img.size[0])
    print("y=",img.size[1])

    import numpy
    pixels = numpy.array(img.pixels)
    pixels[0::4] = 1 - pixels[0::4]
    pixels[1::4] = 1 - pixels[1::4]
    pixels[2::4] = 1 - pixels[2::4]
       
    img.pixels[:] = pixels
    img.update()

I found this extensive numpy tutorial, if you don’t mind reading too much.
http://cs231n.github.io/python-numpy-tutorial/

wow !

I think i’ll have to change my opinion on python perfs :smiley:

what i understand in what you say is that python implicitly handles pointers just like does C or C++ ?
this is damn powerfull !

numpy ? hmm i’ll have to check this as it sounds very interresting and i’ll read this tut as soon as i finish my splatting shader !

thanks @Jeacom and have a nice afternoon !

and happy blending :slight_smile: