It is currently July 20th, 2019, 6:10 am

Working with InputText

Our most popular Tips and Tricks from the Rainmeter Team and others
User avatar
jsmorley
Developer
Posts: 19295
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Working with InputText

jsmorley » March 21st, 2014, 9:15 pm

InputText plugin

Some folks struggle a bit at first with the InputText plugin, as it is a slightly different animal than other Rainmeter measures or meters, and has some special rules. Let's take a quick look at some ways to use it.

Overview

The InputText plugin is used to obtain keyboard input from the user. A trigger action fires one or more CommandN options on the plugin, which use a special macro $UserInput$ to create an input field that text is entered into. When the Enter key is hit, the text that was input into the field is used in bang actions defined in the command.

The approach consists of two parts:

The InputText plugin measure
This is where you define the location and appearance of the input field that will be created, and one or more CommandN options to define what should happen when the input is complete.

A trigger action
An action, generally a mouse action on a meter of some kind, (but it can be any action) that uses the !CommandMeasure bang to fire the InputText plugin measure. This action will define which of the Command[i]N[/i] options on the measure are executed with the ExecuteBatch parameter. The InputText measure has no value, and takes no action, unless it is executed with one of these trigger bangs.

So at its most basic, it is:

Code: Select all

[SomeMeter]
Meter options...
LeftMouseUpAction=[!CommandMeasure InputTextMeasure "ExecuteBatch 1"]

[InputTextMeasure]
Measure options...
Command1=[!SomeBang "$UserInput$"]
The InputText plugin measure

Formatting options

An InputText measure may at first glance have some similarities with a meter, in that you define a position within the skin with X and Y, a size with W and H, and other text attributes like FontColor and StringStyle and such. It is NOT a meter however, and those attributes you define are just used by the plugin to create a standard Windows input field when the plugin is executed with the !CommandMeasure bang. Be aware that there are a few differences with how these attributes are handled by the plugin, as opposed to when they are used in a meter:

1: You can only use fonts in the FontFace option that are actually installed in Windows. No custom fonts stored in @Resources\Fonts can be used.

2: You cannot use "relative positioning" for X or Y in the measure. The "r" and "R" settings that define relative positions in meters won't function in an InputText measure. You must set specific values (or formulas) for X and Y.

Hint: it is still possible to have the measure be positioned "relative" to some meter, but you will need to use Section Variables to obtain the position and size of the meter in a formula on the measure.

3: If you set a SolidColor option on the measure, to define the background color of the input field, any "alpha" (transparency) setting on the option will apply to the entire field, both background and text. The alpha component of FontColor is entirely ignored. Generally you are not going to want to specify any alpha value (red,green,blue,alpha) on the measure. Leave it as the default 255 (opaque).

Hint: You can enter a linefeed while entering text in the input field by holding down CTRL and hitting Enter. You should be sure that the H (height) option of the InputText plugin measure is large enough to hold two (or as many as you need) lines of text at your current FontSize, or the text will scroll up out of the input field and it will be hard to see what you have entered.

The CommandN options

First, it's important to wrap your head around what the macro $UserInput$ means in the context of an InputText plugin measure. it does TWO things at once:

1: It actually causes the plugin to create the input field. Every time the measure sees $UserInput$ in a Command[i]N[/i] option, it will create an input field using the formatting options of the measure. If there is not one (and generally only one) instance of $UserInput$ in the CommandN options that you are executing, the plugin will not be fired at all.

2: Once the user inputs text and Enter is pressed, the string that was input is set as the value of the measure, and replaces the $UserInput$ as the bang that contains the $UserInput$ is executed. Only the $UserInput$ that created the input field is replaced with the value. If it is used more than once, it isn't going to pass the single input value multiple times, but will create multiple input fields, requiring separate input from the user.

Hint: You can address using the input value multiple times by using the [MeasureName] string value of the InputText measure in the bangs. That value is set as soon as you hit Enter on the field, and is available to use in your Command[i]N[/i] bangs. More on that in our example skin in a bit.

So any valid bang or series of bangs can work in our Command[i]N[/i] options, with $UserInput$ both creating and being evaluated as our input text.

Examples:

Command1=[!Log "$UserInput$"]
Command1=[!SetOption MeterString Text "$UserInput$"]
Command1=[!SetVariable SomeVar "$UserInput$"][!UpdateMeter *][!Redraw]
Command1=[!WriteKeyValue Variables SomeVar "$UserInput$"][!Refresh]

Command1=[]$UserInput$
As you can see in this last example, we don't have any bangs at all. We are simply capturing some user input, which will then be set as the value of the InputText measure. We can use that value with MeasureName= on a String or other meter, or as a section variable with "[MeasureName]". Note that we set a "null bang", or "[]" at the beginning to keep Rainmeter from "executing" the value of $UserInput$. That could be a problem if the input text is "calc" or "cmd" or some other text that is also a command or shortcut in the Windows "path".

The measure supports multiple Command options, using Command1, Command2 and so on. This is primarily to allow different "trigger" actions to execute different Command options, as defined in the value used in the ExecuteBatch parameter.

Command1=[!SetVariable SomeVar "$UserInput$"]
Command2=[!SetOption SomeMeter Text "$UserInput$"][!UpdateMeter *][!Redraw]

If you embed an InputText plugin option in the Command option string, then any values set for that option will be overridden when the Command is executed. Do not enclose these override values in square brackets [], they are not bangs or executables, just parameters to the CommandN option.

Command1=[!SetVariable SomeVar "$UserInput$"] DefaultValue="MyValue" FontColor="0,255,0,255"

Hints: Use quotes around the $UserInput$ or [MeasureName] values when used in your Command bangs. You don't have any way to be sure that spaces won't be included in the user input, and should just assume they will. Do always use square brackets around the bangs and commands you are executing. Due to the need to parse any Option=Value parameters in the Command option, InputText can become confused if normal Rainmeter "actions" are not enclosed in "[ ]".

Some other options

DefaultValue : This will be the default text that will appear and be highlighted in the field when the measure is activated.

FocusDismiss : If set to 1 (default), this will cause the field to be dismissed without capturing any input if the input field loses "focus"; If the mouse is clicked anywhere else outside the input field. If set to 0, then only the Escape key will dismiss the input field.

OnDismissAction : A bang or series of bangs to be executed if the field is dismissed without the Enter key being pressed.

Password : If set to 1, then both the active input by the user and any DefaultValue will be displayed as asterisk "*" characters.

Hint: All options in an InputText plugin measure are fully evaluated each time the input is "triggered", so DynamicVariables is never needed on the measure, even if using a dynamically changing #VarName# or [MeasureName] in the options.

The trigger action

The InputText measure is executed or "triggered" by an action on some other meter or measure. Generally, you will use a mouse action on a meter to trigger the input field.

You do this with a !CommandMeasure bang with the name of the InputText plugin measure as the first parameter, and ExecuteBatch followed by the number of the Command[i]N[/i] you wish the plugin measure to use. Some examples are:

LeftMouseUpAction=[!CommandMeasure InputMeasure "ExecuteBatch 1"] : Execute Command1
LeftMouseUpAction=[!CommandMeasure InputMeasure "ExecuteBatch 2"] : Execute Command2
LeftMouseUpAction=[!CommandMeasure InputMeasure "ExecuteBatch 1-4"] : Execute Command1 through Command4

Hint: Multiple meters, with different mouse actions, can execute the same InputText plugin measure. Simply have each action BatchExecute the appropriate Command numbers.

Example skin

As always, probably the best way to wrap your head around something in Rainmeter is to play with an example skin. Here is the skin and the code, we will go over some things that it is doing in a second.
InputExample_1.0.rmskin

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[Variables]
CurrentInput=""

[MeterGoogle]
Meter=String
FontSize=12
FontColor=204,255,196,255
StringStyle=Bold
SolidColor=47,47,47,255
Padding=5,6,5,5
AntiAlias=1
Text=G
LeftMouseUpAction=[!CommandMeasure MeasureInput "ExecuteBatch 1-2"]

[MeterBing]
Meter=String
X=2R
Y=0r
FontSize=12
FontColor=196,231,255,255
StringStyle=Bold
SolidColor=47,47,47,255
Padding=7,6,7,5
AntiAlias=1
Text=B
LeftMouseUpAction=[!CommandMeasure MeasureInput "ExecuteBatch 3-4"]

[MeterInputLabel]
Meter=String
X=52
Y=0r
W=170
H=18
FontSize=12
FontColor=170,170,170,255
SolidColor=27,27,27,255
Padding=5,6,5,4
StringStyle=Italic
AntiAlias=1
Text=Select Search Engine

[MeasureInput]
Measure=Plugin
Plugin=InputText
X=57
Y=4
W=171
H=20
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
FocusDismiss=1
DefaultValue=#CurrentInput#
OnDismissAction=[!SetVariable CurrentInput ""][Play "#@#Sounds\Dismiss.wav"]
Command1=["https://www.google.com/#q=$UserInput$"]
Command2=[!SetVariable CurrentInput "[MeasureInput]"][!UpdateMeter *][!Redraw]
Command3=["https://www.bing.com/search?q=$UserInput$"]
Command4=[!SetVariable CurrentInput "[MeasureInput]"][!UpdateMeter *][!Redraw]
InputExample.gif
First, we are creating two String meters, [MeterGoogle] and [MeterBing], that will act as the "triggers" for our InputText plugin. As you can see, they simply have a LeftMouseUpAction on them that sends a !CommandMeasure to our InputText measure, [MeasureInput], with the numbers of the Command[i]N[/i] options we want to have them BatchExecute.

Then we have a purely cosmetic meter, [MeterInputLabel], that is more or less a "place holder" for the InputText field when it is not active. We make it the same size and position and other attributes as the InputText plugin, so it just appears to "become" the input field at the appropriate time.

Hint: You can of course set the mouse action (the "trigger") on this meter, so you get the effect that clicking on the input field (really the place holder) starts the input. This will be a very common approach for using InputText.

Then we have our InputText measure, [MeasureInput]. We position and size it with options like X and Y and W and H, and format it with options like FontSize and FontColor. Again, we are using position and formatting options to make a seamless transition between the place holder meter above and the input field.

Then we have the meat-and-potatoes of the measure, the Command[i]N[/i] options:

Code: Select all

Command1=["https://www.google.com/#q=$UserInput$"]
Command2=[!SetVariable CurrentInput "[MeasureInput]"][!UpdateMeter *][!Redraw]
Command3=["https://www.bing.com/search?q=$UserInput$"]
Command4=[!SetVariable CurrentInput "[MeasureInput]"][!UpdateMeter *][!Redraw]
So what we are doing with Command1 and Command2, (executed by clicking on our [MeterGoogle] meter) is simply executing a Google search in our default browser, passing the string value we enter in the InputText field as the search parameter. Then we are setting the value of a Variable CurrentInput to the value we entered as well. Notice that we are using the string value of the measure with "[MeasureInput]", rather than trying to use the $UserInput$ macro twice. Then we update our meters and redraw, so things happen briskly when you hit Enter.

Command3 and Command4 do exactly the same thing, only searching Bing instead of Google. Those commands will be executed when we click on our [MeterBing] meter.

There is a lot of interesting stuff you can do when accepting user input, feel free to post here if you have questions or need advice.
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 19295
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with InputText

jsmorley » March 23rd, 2014, 2:39 am

It is important to understand that each $UserInput$ creates an input field when embedded in Command[i]N[/i] options that are executed in the same BatchExecute parameter. You can't use the single value input twice by just repeating $UserInput$ in the bangs being executed.

We talked in the first post of this thread about a way to get around this by using the "[MeasureName]" of the InputText plugin measure as a section variable, which will also contain the text input by the user.

However, it should be noted that there may be a time when you want to make use of the behavior as designed. When you in fact want two or more separate inputs from the user, one after the other, which you then use as separate entities in your skin.

Here is an example of how you might use $UserInput$ this way:

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[MeterInputLabel]
Meter=String
X=0
Y=0
W=170
H=18
FontSize=12
FontColor=170,170,170,255
SolidColor=47,47,47,255
Padding=5,6,5,4
StringStyle=Italic
AntiAlias=1
Text=Click to Enter Name
LeftMouseUpAction=[!CommandMeasure MeasureInput "ExecuteBatch 1-3"]

[MeasureInput]
Measure=Plugin
Plugin=InputText
X=5
Y=4
W=171
H=20
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
FocusDismiss=1
DefaultValue=""
Command1=[!SetVariable FirstName "$UserInput$"] DefaultValue="Enter First Name"
Command2=[!SetVariable LastName "$UserInput$"] DefaultValue="Enter Last Name"
Command3=[!SetOption MeterOutput Text "#*LastName*#, #*FirstName*#"][!UpdateMeter *][!Redraw]

[MeterOutput]
Meter=String
X=0
Y=5R
W=170
H=18
FontSize=12
FontColor=170,170,170,255
SolidColor=47,47,47,255
Padding=5,5,5,5
StringStyle=Italic
AntiAlias=1
DynamicVariables=1
test.gif
You do not have the required permissions to view the files attached to this post.
User avatar
JoBu
Posts: 280
Joined: February 16th, 2011, 12:46 am
Location: California

Re: Working with InputText

JoBu » March 24th, 2014, 9:18 pm

Great tutorial - could have used that during my IRC build!

Should be a great help to others though, nicely done sir!
User avatar
NickV
Posts: 20
Joined: March 28th, 2014, 2:34 pm

Re: Working with InputText

NickV » April 19th, 2014, 4:32 pm

Thanks for this. Of course, being me, I stumbled through the process first, and then read the tutorial :) —but the tutorial confirmed most of what I thought I'd figured out, and cleared up some details that were confusing me.

I have a couple of purely cosmetic questions:
1) how can I put a border around the input box, so it looks more like a "box"?
2) my input box is concealed when not in use, so I'm using "default value" (e.g., "Search Google:") instead of the meter input label, as you have done. But it highlights the default text in a garish blue. Is there any way I can change this without using the meter input label?
—Nick
User avatar
jsmorley
Developer
Posts: 19295
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with InputText

jsmorley » April 19th, 2014, 5:16 pm

NickV wrote: 1) how can I put a border around the input box, so it looks more like a "box"?
2) my input box is concealed when not in use, so I'm using "default value" (e.g., "Search Google:") instead of the meter input label, as you have done. But it highlights the default text in a garish blue. Is there any way I can change this without using the meter input label?

1) I would just draw a slightly larger box first, using an Image meter with W, H and SolidColor, then have the input box "after / in front" of it, slightly smaller. That will create what looks like a "border" around the box.

2) No. The "default text" is automatically highlighted, and in colors set by your theme in Windows. By default that is that bright blue with white letters. You can change your overall color theme in Windows I suppose, but whatever it is is what Rainmeter will get.
User avatar
NickV
Posts: 20
Joined: March 28th, 2014, 2:34 pm

Re: Working with InputText

NickV » April 19th, 2014, 5:43 pm

jsmorley wrote: No. The "default text" is automatically highlighted, and in colors set by your theme in Windows. By default that is that bright blue with white letters. You can change your overall color theme in Windows I suppose, but whatever it is is what Rainmeter will get.
Okay, thanks for this. Is there a way (that's not too complicated) to use meter input labels, as you have done, but make them vanish when not in use and when the input command executes?

thanks again
—Nick
User avatar
jsmorley
Developer
Posts: 19295
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with InputText

jsmorley » April 19th, 2014, 5:48 pm

NickV wrote: Okay, thanks for this. Is there a way (that's not too complicated) to use meter input labels, as you have done, but make them vanish when not in use and when the input command executes?

thanks again
You could use a MouseOverAction on the meters to make !SetOption set the "Text" option for the meter to "whatever" and on MouseLeaveAction to "". Then use [!UpdateMeter *][!Redraw] to make it "snappy".
User avatar
NickV
Posts: 20
Joined: March 28th, 2014, 2:34 pm

Re: Working with InputText

NickV » April 19th, 2014, 6:43 pm

jsmorley wrote:You could use a MouseOverAction on the meters to make !SetOption set the "Text" option for the meter to "whatever" and on MouseLeaveAction to "". Then use [!UpdateMeter *][!Redraw] to make it "snappy".
:oops: I'm getting a little over my head, but I think I understand this...

Going back to your other suggestion
jsmorley wrote:draw a slightly larger box first, using an Image meter with W, H and SolidColor, then have the input box "after / in front" of it, slightly smaller. That will create what looks like a "border" around the box.
I attempted this. I created a meter called "meterbox" and defined as image as per your suggestion, set it as hidden=1, because I don't want it to show by default, and then attempted to make it appear using this command:

Command1=!Execute [!showmeter #meterBox#]["https://duckduckgo.com/$UserInput$"]

The input command works, but the showmeter command does not. I tried it both with the # signs before and after "meterBox", and without, bercause I'm a little confused by them, but neither way works.

Is there enough information here for you to tell me what I'm doing wrong?

Never mind: I figured out that the showmeter command should be at the meter that makes the input function kick in, not at the input function itself. But I'm still trying to gure out how to make it dissapear properly. If I use a mouseleaveaction after the showmeter command, the box just flashes and goes away again.

Never mind again: (sorry to be a nuisance) I figured out that if I move the hidemeter function back to just after the input cammand line, then it works properly...
—Nick
User avatar
jsmorley
Developer
Posts: 19295
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with InputText

jsmorley » April 19th, 2014, 7:07 pm

NickV wrote: :oops: I'm getting a little over my head, but I think I understand this...

Going back to your other suggestion I attempted this. I created a meter called "meterbox" and defined as image as per your suggestion, set it as hidden=1, because I don't want it to show by default, and then attempted to make it appear using this command:

Command1=!Execute [!showmeter #meterBox#]["https://duckduckgo.com/$UserInput$"]

The input command works, but the showmeter command does not. I tried it both with the # signs before and after "meterBox", and without, bercause I'm a little confused by them, but neither way works.

Is there enough information here for you to tell me what I'm doing wrong?
That is not what I am saying though. You can't really have an action on a CommandN line that does something to a meter that is just instantly going to be replaced / overlaid by the actual input field. You will never see it.

What I am suggesting is something like:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[MeterInputLabel]
Meter=String
X=0
Y=0
W=172
H=18
FontSize=12
FontColor=170,170,170,255
SolidColor=27,27,27,255
Padding=5,6,5,4
AntiAlias=1
MouseOverAction=[!SetOption MeterInputLabel Text "Input Some Value"][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption MeterInputLabel Text ""][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!CommandMeasure MeasureInput "ExecuteBatch 1"]

[MeasureInput]
Measure=Plugin
Plugin=InputText
X=4
Y=4
W=172
H=20
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
FocusDismiss=1
Command1=[!Log "I entered $UserInput$"]
test.gif
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 19295
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with InputText

jsmorley » April 19th, 2014, 7:23 pm

Sorry, I sorta misunderstood a little bit. In fact I'm still not sure I understand the end-result you are trying to get. Anyway, to have the "border" meter show up only when you mouse over the input area, you might use:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[MeterBorder]
Meter=Image
W=186
H=32
SolidColor=255,0,0,1
MouseOverAction=[!SetOption MeterBorder SolidColor 255,255,255,255][!SetOption MeterInputLabel Text "Input Some Value"][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption MeterBorder SolidColor 255,255,255,1][!SetOption MeterInputLabel Text ""][!UpdateMeter *][!Redraw]

[MeterInputLabel]
Meter=String
X=2
Y=2
W=172
H=18
FontSize=12
FontColor=170,170,170,255
SolidColor=27,27,27,255
Padding=5,6,5,4
AntiAlias=1
LeftMouseUpAction=[!CommandMeasure MeasureInput "ExecuteBatch 1"]

[MeasureInput]
Measure=Plugin
Plugin=InputText
X=6
Y=6
W=172
H=20
FontSize=12
FontColor=255,255,255,255
SolidColor=47,47,47,255
AntiAlias=1
FocusDismiss=1
Command1=[!Log "I entered $UserInput$"]
test.gif
However, when you click on the meter that fires the input field, any MouseLeaveAction options will be triggered, as having the cursor "enter" the input field also makes the "leave" any other meters in the skin.
You do not have the required permissions to view the files attached to this post.