Styles

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Styles

Post by ggoblin »

Sorry another beginner question.

I have created a shape in a moho script and given it a style (just a stroke and fill) and named that style, but it doesn't appear in the styles pallete. What am I missing?

(for bevity I have left the shape code out, but the shape creates fine with the correct style attributes)

Code: Select all

		local shapeid = moho:CreateShape(true,false,0)	
		local shape = mesh:Shape(shapeid)
		
		shape:SetName("my shape")
		shape.fMyStyle.fLineWidth = 0.01
		
		local rgbCol = LM.rgb_color:new_local()
		rgbCol.r = 255
		rgbCol.g = 0
		rgbCol.b = 0
		rgbCol.a = 255
		
		shape.fMyStyle.fLineCol:SetValue(0, rgbCol)
		

		rgbCol.r = 0
		rgbCol.g = 255
		rgbCol.b = 0
		rgbCol.a = 255

		shape.fMyStyle.fFillCol:SetValue(0, rgbCol)
		
		local stylename = LM.String:new_local()
		stylename:Set("my style")
		shape.fMyStyle.fName = stylename
I tried looping though all the styles in the document in case it was there but just not being displayed in the style pallete - it listed all the other styles but not the one I created in the script.

Code: Select all

		for styleIndex = 0, moho.document:CountStyles()-1 do
			print(styleIndex.." > "..moho.document:StyleByID(styleIndex).fName:Buffer())	
		end
	


Then I came across AddStyle function. It has no documentation and there are no scripts listed as using it. I tried to call it in the following manner:

Code: Select all

		moho.document:AddStyle(shape.fMyStyle)
But that just crashed moho :(
What am I missing?


BTW I can select the shape using its name from the style pallete and that way change its style but thats not what I am after as I will be creating lots of shapes across many layers so need to be able to change all of them in one go.


Thank you for any help.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Styles

Post by ggoblin »

Sorry spotted one error already:

Code: Select all

	
		shape.fMyStyle.fName=stylename

should be 

		shape.fMyStyle.fName:Set(stylename)
But unfortunately fixing it hasn't solved my problem. :(
User avatar
synthsin75
Posts: 10013
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Styles

Post by synthsin75 »

Don't have much time right now, but from my scripting notes:

Code: Select all

	---[=[--try renaming style [fail]
	local doc = moho.document
	local ct = doc:CountStyles()
	local style = doc:StyleByID(ct-1) -- get the last one
	--local style = mesh:Shape(i).fMyStyle
	local name = style.fName:Buffer()
	doc:AddStyle(style)
	ct = doc:CountStyles() -- now one more ...
	style = doc:StyleByID(ct-1)
	name = style.fName:Buffer() .. ".new"
	style = doc:StyleByID(ct-1) -- setting name only works with this
	style.fName:Set(name)
	--]=]
Might be one of the few broken bits of the scripting API.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Styles

Post by ggoblin »

Thank you Wes for looking in to this, I know its always a chore to look at someone elses code :)

One thing I did notice when I was trying to debug was that this method of naming a style didn't seem to work for me:

Code: Select all

		local stylename = LM.String:new_local()
		stylename:Set("boxstyle")
		shape.fMyStyle.fName:Set(stylename)

		print("Style name >>>"..shape.fMyStyle.fName:Buffer().."<<<")

-- OUTPUT:  Style name >>><<<
But if I change it to:

Code: Select all

		shape.fMyStyle.fName:Set("boxstyle")

		print("Style name >>>"..shape.fMyStyle.fName:Buffer().."<<<")

-- OUTPUT:  Style name >>>boxstyle<<<
Then it seems to work. I put it down to my near zero undersatnding of both Lua and the Moho API.. but perhaps it was something else?

But in either case as soon as I call

Code: Select all

moho.document:AddStyle(shape.fMyStyle)
Moho crashes.. :(

In your trials, did AddStyle also crash Moho?

Without AddStyle working how can we create a new style from within a script?
User avatar
synthsin75
Posts: 10013
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Styles

Post by synthsin75 »

I'm pretty sure the add style API is broken. From what I recall, I could make a new style by copying an existing one (not from a shape), but it never seemed stable.
User avatar
hayasidist
Posts: 3564
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Styles

Post by hayasidist »

I've recently been looking at styles (again!) for other reasons -- it's still WIP so the following is all "I think..."


Style API is broken and has been for a while - bug reports were raised in 2014 and 2017. http://www.lostmarble.com/forum/viewtop ... 12&t=33871 Those bugs (and more recent issues) have been logged in the new system.

===

myStyle in a shape is an M_Style object; but it is not a Document-wide style - so that intentionally won't show up in the style list.

There are aspects of a style (e.g. fill gradient) for which there is no API. The Style object stored in the moho file contains more fields than the M_Style object presented via the scripting interface - although some of these can be accessed via sub-channels of the shape's Effects channel and these can be used to play with the gradients (etc). e.g. this video was done using a script to set and then vary the colours: https://youtu.be/y54IvF-D6eI

===


Also (from my recent investigations):

doc:StyleByID(i) seems to return an M_Style than only has its .fName defined (type LM_String)
Interestingly, the return from st = doc:StyleByID(i) itself has a Buffer() method. so st:Buffer() also returns the style name. [The meta table for the object looks more like that for an LM_String than for an M_Style]

using that fName:Buffer() as input to doc:Style(name) returns an M_Style that does appear to be correct.

This works:

Code: Select all

		style = doc:StyleByID(i)
		name = style.fName:Buffer()
		mStyle = doc:Style(name) -- <<< Need this extra step
		uuid = mStyle.fUUID:Buffer() -- etc
What I haven't yet done:
>> I haven't tried to use the "properly formed" mStyle as input to MohoDoc:AddStyle(style)
BUT noticing that AddStyle predates the change from Name to UUID - it isn't at all clear to me if AddStyle will provide a new UUID ... that investigation was still in the TBD list

[EDIT:] ... and the answers are: AddStyle seems to work without crashing when given a "good" M_Style ... but Moho expects unique UUIDs. (creating styles with different fName but the same fUUID confuses Moho)

[... to be continued]
Last edited by hayasidist on Tue Jun 07, 2022 1:56 pm, edited 1 time in total.
User avatar
Lukas
Posts: 1297
Joined: Fri Apr 09, 2010 9:00 am
Location: Netherlands
Contact:

Re: Styles

Post by Lukas »

I can't remember what it was exactly, but I once encountered something with styles in a script that would not do anything unless the style windows was open.
User avatar
hayasidist
Posts: 3564
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Styles

Post by hayasidist »

No luck I'm afraid. I think it's the "instance" trap (see "Your vector assignment looks right, but it doesn't work?!" in https://mohoscripting.com/introduction)

doc:AddStyle when you've used an existing style as the "template" appears to work, but the "duplicated" style causes Moho to throw all manner of oddities that ultimately result in a crash.

End of the road for now - unless / until we get the M_Style:new() [or someone figures out a way round this .. it's got me stumped at present...]
User avatar
synthsin75
Posts: 10013
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: Styles

Post by synthsin75 »

hayasidist wrote: Tue Jun 07, 2022 9:16 pm No luck I'm afraid. I think it's the "instance" trap (see "Your vector assignment looks right, but it doesn't work?!" in https://mohoscripting.com/introduction)

doc:AddStyle when you've used an existing style as the "template" appears to work, but the "duplicated" style causes Moho to throw all manner of oddities that ultimately result in a crash.

End of the road for now - unless / until we get the M_Style:new() [or someone figures out a way round this .. it's got me stumped at present...]
Yeah, that's what I vaguely remember. You can only define a proper style to add by using an existing one, BUT that added style just becomes and instance, which Moho doesn't like.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Styles

Post by ggoblin »

I have to admit its dissapointing to learn that something as fundamental as styles API is broken and despite bug reports raised several times over the last 8 years its still not fixed. And then to read Hayasidist say that some aspects of a Style, like gradients, were never covered by the API in the first place.. :(

I think at the very least, programmers that come after us should be warned of these potholes. The function description of AddStyle should clearly state it does not work and will cause instability if you try to use it. Also the mStyle API description should list what style properties like gradients are missing from the API so people dont waste time looking for things that do not exist, also any possible workarounds like using sub-channels should be mentioned.

As a beginner I'm still not clear how broken the style API is, can someone please clarify:

1. Can we safely create a new style from Lua? I am guessing this a a big no.

2. Can we safely modify an existing style and save it as a new style from Lua?

3. Can we safely modify an existing style in Lua and the modifications appear in the style pallette?

4. Can we safely choose an existing style and use it in Lua for shapes created in Lua? I am guessing this is a yes, otherwise there would be little point in using scripts to create shapes.

Are there other known parts of the API that are known to be broken? A list would be very useful.

Thank you.

BTW Thank you for the open discussion, I am learning so much from it.
User avatar
hayasidist
Posts: 3564
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Styles

Post by hayasidist »

Let me start by saying that you don't **need** styles -- shapes can be created with stroke/fill; and the default fill / line colours can be found in ScriptInterface:NewShapeProperties()

most drawing scripts, including the standard LM_ ones, use the default fill / stroke info....

BUT that NewShapeProperties() has just given me an idea... there's an M_Style in there which **might** just be usable as the basis of a cloning because it's a "shape:myStyle" not a "doc:style" .. I'll take a look at that later

===
[EDIT: "Later"]

Nah .. after some initial optimism -- it gets as far as adding a new style with a new name and new UUID, but as soon as you try to use the UI to mod the new style -->> crash!
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Styles

Post by ggoblin »

I came across this script by strider2 to Reassign Styles.

https://mohoscripts.com/script/msReassignStyles

It doesn't create any styles in Lua, but does replace a shapes existing style with another existing style.

It converts the both search and replacement style names to their Style.fUUID, then uses that for searching

Code: Select all

	local style = moho.document:Style(msReassignStyles.searchString)
	self.searchStyleID = style.fUUID
For each layer it loops though all the shapes looking to see if any of their fInheritedStyleName matches the style that needs reassigning (using Style.fUUID to match). When it finds a match it swaps the styles fUUID with the replacement style fUUID to achieve the reassignment.

Code: Select all

    local vectorLayer = self.moho:LayerAsVector(layer)
    local mesh = vectorLayer:Mesh()
    for i = 0, mesh:CountShapes()-1 do
        if(mesh:Shape(i).fInheritedStyleName:Buffer() == self.searchStyleID:Buffer()) then
            mesh:Shape(i).fInheritedStyleName = self.replacementStyleID
        end
    end
    self.moho.document:RelinkStyles(vectorLayer)

Not really what we are looking for, but it might be useful.

BTW He also has a script for renaming styles: https://mohoscripts.com/script/msRenameStyles

[EDIT Forgot to mention he uses

Code: Select all

RelinkStyles
I've never come across that before, there doesn't appear to be any documentation for it. A command called to 'bake' the style changes in? ]
Last edited by ggoblin on Thu Jun 09, 2022 3:06 am, edited 1 time in total.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Styles

Post by ggoblin »

hayasidist wrote: Wed Jun 08, 2022 6:11 pm Let me start by saying that you don't **need** styles
I guess it depends on what you are doing. If your script is just creating a shape then sure the script will give it a stroke and a fill and even a stroke width, and then if you need a style you can always assign it after the script has finished.

But in my case the script is creating lots of identical shapes across lots of layers. When the script finishes I need to be able to customise the look of all these identical shapes hence I really do **need** styles, unless there is another way to group them across layers ( if it was on one layer I might get away with identical shape names to group them, if that is allowed, and then change their style as a shape group). Even if it could be done over layers, its still a very messy approach to something I wanted to automate (hence the purpose of the script). At the moment I am setting a style before running the script and it picks up that style and assigns it to the shapes and I can customise the shapes with that style, but that means I can only use one style for everthing which is not what I want.
ggoblin
Posts: 266
Joined: Wed Jan 19, 2022 2:09 pm

Re: Styles

Post by ggoblin »

hayasidist wrote: Wed Jun 08, 2022 6:11 pm it gets as far as adding a new style with a new name and new UUID, but as soon as you try to use the UI to mod the new style -->> crash!
How about if you use striders script to replace the new style with a previously UI created old style and then discard the new 'doggy' style and just customise the old style as needed?
User avatar
hayasidist
Posts: 3564
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Styles

Post by hayasidist »

ggoblin wrote: Wed Jun 08, 2022 11:10 pm ...
But in my case the script is creating lots of identical shapes across lots of layers. When the script finishes I need to be able to customise the look of all these identical shapes hence I really do **need** styles, unless there is another way to group them across layers ( if it was on one layer I might get away with identical shape names to group them, if that is allowed, and then change their style as a shape group). Even if it could be done over layers, its still a very messy approach to something I wanted to automate (hence the purpose of the script). At the moment I am setting a style before running the script and it picks up that style and assigns it to the shapes and I can customise the shapes with that style, but that means I can only use one style for everthing which is not what I want.
plenty of ways to address that...

e.g. in your tool create a list of all the styles in the document and present that list against the list of all the different things you want to create. Exactly how you design that UI is down to you - but (e.g.) you loop through the "things" and present the styles list each time as a dropdown - the user picks the one they want from the dropdown ... or radio buttons against the style list ... or loop through the styles and ask which "thing" to use it for ... but however you do it, you end up with a list of "things" and the chosen style. Setting a style is ok - changing the style on a shape is ok - creating one from "scratch" is the problem right now.
Post Reply