It is currently November 29th, 2020, 4:54 pm

DEV : Formatting output from the 'backend' ..

Share and get help with Plugins and Addons
Hansz
Posts: 8
Joined: January 10th, 2015, 11:36 pm

DEV : Formatting output from the 'backend' ..

Post by Hansz »

Ok... Me learning to create plugins is taking shape and form ... I have got my Teamspeak viewer plugin going and I'm actually getting output on the screen ...

Now I'd like to to format the output a bit (color/font wise) ...

I can see where I manipulate this kind of behavior from the the 'Skin' side of things, but that seems to be aimed at a more 'static' output ...

Is there a way of manipulating the color, font-size/style/weight from the 'backend' (aka by formatting stuff in the getString method of a plugin maybe ? How do you guys achieve this kind of behavior?

Thnx again for your time and information :welcome:
User avatar
.raptor
Posts: 220
Joined: April 3rd, 2013, 11:03 pm
Location: Norway

Re: DEV : Formatting output from the 'backend' ..

Post by .raptor »

Hansz wrote:Ok... Me learning to create plugins is taking shape and form ... I have got my Teamspeak viewer plugin going and I'm actually getting output on the screen ...

Now I'd like to to format the output a bit (color/font wise) ...

I can see where I manipulate this kind of behavior from the the 'Skin' side of things, but that seems to be aimed at a more 'static' output ...

Is there a way of manipulating the color, font-size/style/weight from the 'backend' (aka by formatting stuff in the getString method of a plugin maybe ? How do you guys achieve this kind of behavior?

Thnx again for your time and information :welcome:
I don't really see any easy way this could be achieved, neither do i see a reason why you would want it. The reason Rainmeter is so great is that it gives users the highest possible amount of control over the output style. it would be, to say the least, mildly annoying if one of my plugins decided to set styles on its own. Formatting on the other hand is quite easily achieved with a string builder (or the corresponding C++ word for it ;-) ).
Hansz
Posts: 8
Joined: January 10th, 2015, 11:36 pm

Re: DEV : Formatting output from the 'backend' ..

Post by Hansz »

Hmm...

That's a very good point you're making there. I guess my background as a web-developer is playing up a bit here (and even there it's considered bad practice to do the formatting in the background).

My problem (if you can call it that) however, remains ...

I have a dynamic list of (nested) channels that can have a variable amount of 'clients' inside ... I'd like to format them differently to make the distinction between the channels and the clients by giving them a different color/fontface/weight

What would be the best way to achieve something like this. A pointer to an example/skin would do fine I think. I have unable to find this on google/searching the forum but maybe I'm asking the wrong question(s) ? :lol:

Hansz.
User avatar
jsmorley
Developer
Posts: 21550
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: DEV : Formatting output from the 'backend' ..

Post by jsmorley »

There certainly is no way you are going to have the plugin itself set the attributes of meters. Aside from the fact that it really just wouldn't be possible, it would be the "anti-Rainmeter" in a lot of ways. Plugins, and measures in general, "measure" something, and return a number or string as the "value" of the measure. It is up to the skin, and the author / user of the skin, to decide how to evaluate, use and display this information.

You might have a parent-child approach were you do something like WebParser or FileView and set up "indexes" to the information you measure. Then you could have some kind of "type" option for the child measures, to return a number or string to represent "channel" or "client".

[MeasureParent]
Measure=Plugin
Plugin=MyPlugin
Server=blah

[MeasureChild1Name]
Measure=Plugin
Plugin=MyPlugin
Server=[MeasureParent]
Index=1
Type=Name

[MeasureChild1Level]
Measure=Plugin
Plugin=MyPlugin
Server=[MeasureParent]
Index=1
Type=Level

Then on that measure getting the "Level", the skin can react with an IfCondition if you are returning a number like 1/2 or an IfMatch if you are returning a string like "Channel / Client", and use !SetOption to set any attributes of meters you like.

I'm no expert on TeamSpeak, but I would think you would want this kind of approach so you can isolate other information about the channel or client in any case. I don't know, stuff like "muted" or "operator" or other status / attributes of the entity.

Take a look at the code for FileView for an example of how you might use parent-child approaches with a plugin.
User avatar
jsmorley
Developer
Posts: 21550
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: DEV : Formatting output from the 'backend' ..

Post by jsmorley »

I would caution that in general this whole "TeamSpeak server" thing might not be the best fit for Rainmeter. By its nature, the TeamSpeak client is based on a dynamic "tree" of information, something like

-Server
--Channel 1
---Client 1
---Client 2
--Channel 2
---Client 1

and so on. There can be 0-xxx "channels" and each of those can have 0-xxx "clients". This tree will change dynamically as clients come and go, and even as channels are created and deleted by server moderators.

The nature of Rainmeter on the other hand, is that you build some static number of "measures" and those are displayed in some static number of "meters".

While that is fine for an RSS feed or something else where you can say "get and show the first 5 or 10 or 20 entries", or whatever you want to build into the skin to accommodate, it won't be a great fit for something that is "open ended" and where just showing the "first xxx" items is not what you want.

If you build the skin with 10 measures and meters, then you are just going to get a "truncated" tree of information, which is going to be really weird. If you build the skin with 100 measures and meters, and only 5 people are on the server at some point, that has its own challenges to deal with. You can have lots of "empty" meters to deal with.

You might be able to have it return a "count" as one of the attributes of the parent measure, then do some things with "disabling / enabling" measures and "hiding / showing" meters, but it will be challenging to get a really functioning "tree" of information where there are naturally no constraints on how that tree is dynamically populated. Reacting properly as "clients" come and go from various channels and the "tree" collapses and expands is going to be hard to manage in the Rainmeter world.

You might be able to do something with "scrolling" or "paging" through the index numbers based on a mouse click, once again the FileView plugin might be instructive.

If the idea is to just return a single long "string" with all the information, having the plugin insert linefeeds and / or tabs between entries to do some "spatial formatting", that is an approach that will work, but I will stop you right there and tell you that there is NO way that you are going to get any "inline attribute formatting" of that information to have things be different colors or sizes or fonts or any of that. That is just not how Rainmeter works. A meter can have only one set of attribute options. The entire concept of "inline" does not exist in Rainmeter.

Anyway, might be doable, and I have no idea what kind of display you have in mind, but I would carefully think this all the way through. Not only "what can I get?", but "how will a skin author use it?"
Hansz
Posts: 8
Joined: January 10th, 2015, 11:36 pm

Re: DEV : Formatting output from the 'backend' ..

Post by Hansz »

Hi JSMorley,

Thnx for the input ...

What you describe is pretty much what I suspected/was afraid off.

The 'String approach you mention is how I currently do it, but I feel it must be doable to make it look more 'appealing' to the eye so to speak. (hence my questions).

Anyway ... as you mention, I have this nagging feeling it should be doable one way or the other so I'm picking up the gauntlet here and will try to figure out a way to make this work.

All comments to my question(s) have convinced me I'm on the right way ...

:rosegift:
User avatar
jsmorley
Developer
Posts: 21550
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: DEV : Formatting output from the 'backend' ..

Post by jsmorley »

Well there one hard and fast rule that you have to live with no matter what approach you take.

A String meter can be thought of (somewhat oversimplified) this way. Rainmeter collects whatever will constitute the "string", based on the MeasureName associated with the meter, and any Text / Prefix / Postfix and other options. It builds the string in memory, then starts looking at the "attribute" options of the meter. These can be FontColor, FontSize, Padding, any of the "formatting" attributes you set.

It then creates a GDI+ or D2D graphical object and paints the string on that object using those formatting options for the "brush". What is eventually arrived at is in a sense an "image" of the string. That image is then just drawn on the screen. It is not a "text" object at the end of the day. Notice how you can't highlight the string, or copy it, or any of the kinds of behavior you might expect from a "text" object in a Windows application.

So there is no way that Rainmeter will ever have any kind of "inline formatting" of a String meter. It would take a complete re-design of how meters work in the code. This will never be HTML/CSS with spans and styles and divs and all that.

So you have two choices:

You can display the entire string in a single String meter, but will be limited to one of each of the formatting attributes at a time. One FontColor, one FontSize.

You can break up the string and display the pieces in separate String meters, using relative positioning to give the impression of a single string in different colors.

How you break it up can be a couple of different ways. First, you can have multiple instances of the plugin measure, each returning a different bit of data, using the parent-child approach I mentioned above. That is probably the best way, since you have control over how the plugin is written.

Another approach might be to take the entire string from the plugin, and use a bunch of String measures, using RegExpSubstitute / Substitute to have each String measure end up with just a "piece" of the string as its value. Then use those in your separate meters instead of the value of your plugin directly. This in a sense is similar to and no better than a parent-child approach with the plugin, the result is much the same. If I was writing a plugin and could avoid forcing this mess on my users, I certainly would.

Any approach that "breaks it up" for display must be done in the context of the fact that you have to actually code as many measures and meters as you intend to use in the skin code. There is no way to have it say "The plugin returned 20 items, so dynamically create 20 child measures and 20 meters to display them." Again, just not how Rainmeter works. Any attempt to "brute force" this, say in Lua, by actually re-writing the skin .ini or .inc include file based on the return of some value(s) and refreshing the skin has almost unavoidable issues with endless recursion.

That is pretty much where you are. There is just no way you are going to have any "inline" formatting of a meter, and no plugin is ever going to have any control over what is displayed in the skin. You have to work with the tools you have.
User avatar
dgrace
Developer
Posts: 265
Joined: June 28th, 2014, 8:32 am
Location: Tokyo, Japan

Re: DEV : Formatting output from the 'backend' ..

Post by dgrace »

Really ugly hack: you could have your plugin render the string out to a .png file and then display that file with an Image meter that's constantly refreshing. ;>

*runs and hides*

dave
User avatar
jsmorley
Developer
Posts: 21550
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: DEV : Formatting output from the 'backend' ..

Post by jsmorley »

dgrace wrote:Really ugly hack: you could have your plugin render the string out to a .png file and then display that file with an Image meter that's constantly refreshing. ;>

*runs and hides*

dave
Image
ailia
Posts: 34
Joined: August 6th, 2012, 9:56 pm
Location: Lurking

Re: DEV : Formatting output from the 'backend' ..

Post by ailia »

Actually thought about this one a few days since I seem to find myself doing similar hacky things with rainmeter at times, jsmorley might remember when I started a fork of rainmeter to work around this exact problem, and quickly abandoned it after some initial testing that showed it really didn't do anything new except bog down performance almost as bad as brute-forcing things in lua.

Anyways, as to getting some formatting and colors without having N meters for channels and N submeters per channel, try using a set of string meters as follows:

Keep the font height constant across all string meters, leaving color and font/styling to vary.
To "change" the font of any given line, move that line from one string meter to another.
Due to all the meters rendering at the same coordinates without backgrounds, the text style changes, but the apparent position does not.

A bit of a hack, but the cleanest way to do it without N*N meters.

Code: Select all

Channel 1


Channel 2



Channel 3
 

Code: Select all

 
User 1
User 2

User 3
User 4
User 5

User 6
Channel 1
User 1
User 2

Channel 2
User 3
User 4
User 5

Channel 3
User 6