It is currently May 2nd, 2024, 11:19 am

Text editor skin?

Get help with creating, editing & fixing problems with skins
User avatar
Active Colors
Moderator
Posts: 1255
Joined: February 16th, 2012, 3:32 am
Location: Berlin, Germany

Re: Text editor skin?

Post by Active Colors »

Yincognito wrote: February 10th, 2022, 7:43 pm This is what stops one to make a text editor in Rainmeter - the InputText measure behavior:

Code: Select all

[Variables]
Text="one#CRLF#two#CRLF#six"

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

---Styles---

[StyleText]
FontFace=Arial
FontSize=10
FontColor=220,220,220
SolidColor=50,50,50
StringStyle=Normal
AntiAlias=1

---Measures---

[MeasureInput]
Measure=Plugin
Plugin=InputText
X=7
Y=24
W=166
H=230
FontFace=Arial
FontSize=10
FontColor=220,220,220
SolidColor=100,100,100
StringStyle=Normal
AntiAlias=1
FocusDismiss=1
DefaultValue="#Text#"
Command1=[!SetVariable SomeVariable "$UserInput$"]
DynamicVariables=1

---Meters---

[MeterBackground]
Meter=Image
X=0
Y=0
W=180
H=300
SolidColor=40,40,40
UpdateDivider=-1
DynamicVariables=1

[MeterNotes]
Meter=String
MeterStyle=StyleText
X=7
Y=24
W=166
H=230
Text="#Text#"
DynamicVariables=1

[MeterButtonEdit]
Meter=String
MeterStyle=StyleText
X=7
Y=265
SolidColor=60,60,60
Padding=5,5,5,5
Text=[Edit]
LeftMouseUpAction=[!CommandMeasure "MeasureInput" "ExecuteBatch 1"]
DynamicVariables=1
In the file above that has no dependencies (basically your modified Notes version), despite the fact that the meter displays the "#Text#" variable correctly using new lines, once one clicks on the [Edit] button to trigger any bang at all involving the "$InputText$" macro, the new line characters are stripped off the "#Text#" variable, similar to how new lines are stripped off in the Rainmeter Log when viewing String values of measures and variables that "normally" contain new lines as well.

As far as I'm concerned, I can deal and find solutions to most of the other issues, but if one cannot display the text properly in the InputText measures, creating a multiline editor is a difficult task, especially since this kind of measures are pretty much the only way one can interact to edit text in a Rainmeter skin. To build a multiline editor would thus involve crazy workarounds like having multiple one-line InputText measures to simulate new lines which would break proper selecting and copy pasting in the said construct, or reinventing the wheel and replicate all text interactions like the ones mentioned earlier in Rainmeter itself even though those things are already provided by Windows by default.

I didn't even get to Lua because of this, LOL. While in theory implementing such workarounds is entirely possible, via $MouseX$, $MouseY$, Draggable settings, context menus, different coloring for selected text and free text, or the HotKey plugin (I believe I started something along the HotKey lines a while ago just for fun), it's the fact that these are or should be already available and not have to be reimplemented. But yeah, I understand why this happens, InputText is a special measure based on a smart "steal" from Windows and requires special rules... :confused:
[\x000A] didn't work as well.
Simply saying, a new input plugin would be needed that would work with paragraphs and probably text files directly without any variables.

EDIT: actually the only thing the TextInput plugin is missing is the proper handling of the line-breaks. I wonder if it would be a hard thing to implement as well as the ability to read-write into a user-defined files and not just variables.


P.s. Dreaming additionally about a new Paragraph Meter as well as Measure Styles and Plugin Styles.)
User avatar
Yincognito
Rainmeter Sage
Posts: 7188
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Text editor skin?

Post by Yincognito »

Active Colors wrote: February 10th, 2022, 8:09 pmSimply saying, a new input plugin would be needed that would work with paragraphs and probably text files directly without any variables.
Not an Input plugin, but a Box plugin. In Windows terms, an input text (like the similar Input tag in HTML) is usually handling one line stuff; a text box on the other hand is designed with the multiline idea in mind.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5407
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Text editor skin?

Post by eclectic-tech »

I have not read through all the comments but wanted to mention that killall-q created a Lua script to work with in-the-skin notes. I have used it in several notes and to-do skins, and it works. Several other authors have used the exact script or a slightly modified version to create desktop notes with 'tabs'.

Here is a link to an example skin: Notes++ by RaziEil

That package uses the original Lua code 'Notes.ini' by killall-q contained here:
Notes.lua

Code: Select all

function Initialize()
	if SKIN:GetVariable('Item16') ~= "" then
		SKIN:Bang('!SetOption', 'Input', 'MouseOverAction', '[!SetOption Input Text "You List is Full!"][!SetOption Input SolidColor "160,0,0"][!UpdateMeter Input][!Redraw]')
		SKIN:Bang('!SetOption', 'Input', 'MouseLeaveAction', '[!SetOption Input Text "#*Prompt*#"][!SetOption Input SolidColor "0,0,0,1"][!UpdateMeter Input][!Redraw]')
		SKIN:Bang('!SetOption Input LeftMouseUpAction ""')
	end
end

function AddItem()
	local input, crlf = SKIN:GetVariable('Input'):gsub("\r\n", "#*CRLF*#")
	if input ~= "" then
		for i = 1, 15 do
			SKIN:Bang('!WriteKeyValue Variables Item'..(i+1)..' """'..SKIN:GetVariable('Item'..i):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
			SKIN:Bang('[!WriteKeyValue Variables State'..(i+1)..' [#State'..i..'] "#CURRENTPATH#Notes.ini"]')
		end
		SKIN:Bang('!WriteKeyValue Variables Item1 """'..input..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!WriteKeyValue Variables State1 None "#CURRENTPATH#Notes.ini"][!Refresh]')
		SKIN:Bang('[!WriteKeyValue Variables ItemLines (Clamp(#ItemLines#+1,1,17)) "#CURRENTPATH#Notes.ini"][!Refresh]')
	end
end

function EditItemA(n)
	SKIN:Bang('!SetVariable ItemOrig """'..SKIN:GetVariable('Item'..n):gsub("\n", "\r\n")..'"""')
	SKIN:Bang('!CommandMeasure mInput "ExecuteBatch 2"')
end

function EditItemB(n)
	local input = SKIN:GetVariable('Input'):gsub("\r\n", "#*CRLF*#")
	if input ~= "" then
		SKIN:Bang('[!WriteKeyValue Variables Item'..n..' """'..input..'""" "#CURRENTPATH#Notes.txt"][!Refresh]')
	else
		DeleteItem(n)
	end
end

function ClipItem(n)
	SKIN:Bang('!SetClip "'..SKIN:GetVariable('Item'..n):gsub("\n", "\r\n")..'"')
end

function StrikeItem(n)
	SKIN:Bang('[!WriteKeyValue Variables State'..n..' Strikethrough "#CURRENTPATH#Notes.ini"][!Refresh]')
end

function UnStrikeItem(n)
	SKIN:Bang('[!WriteKeyValue Variables State'..n..' None "#CURRENTPATH#Notes.ini"][!Refresh]')
end

function DeleteItem(n)
	for i = n, 15 do
		SKIN:Bang('!WriteKeyValue Variables Item'..i..' """'..SKIN:GetVariable('Item'..(i+1)):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!WriteKeyValue Variables State'..i..' [#State'..(i+1)..'] "#CURRENTPATH#Notes.ini"]')
	end
	SKIN:Bang('[!WriteKeyValue Variables Item16 "" "#CURRENTPATH#Notes.txt"][!Refresh]')
	SKIN:Bang('[!WriteKeyValue Variables ItemLines (Clamp(#ItemLines#-1,1,17)) "#CURRENTPATH#Notes.ini"][!Refresh]')
end

function SwapItemUp(n)
	if n ~= "1" then
		SKIN:Bang('!WriteKeyValue Variables Item'..n..' """'..SKIN:GetVariable('Item'..(n-1)):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!WriteKeyValue Variables State'..n..' [#State'..(n-1)..'] "#CURRENTPATH#Notes.ini"]')
		SKIN:Bang('[!WriteKeyValue Variables State'..(n-1)..' [#State'..n..'] "#CURRENTPATH#Notes.ini"]')
		SKIN:Bang('[!WriteKeyValue Variables Item'..(n-1)..' """'..SKIN:GetVariable('Item'..n):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"][!Refresh]')
	end
end

function SwapItemDown(n)
	if n ~= "16" and SKIN:GetVariable('Item'..(n+1)) ~= "" then
		SKIN:Bang('!WriteKeyValue Variables Item'..n..' """'..SKIN:GetVariable('Item'..(n+1)):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!WriteKeyValue Variables State'..n..' [#State'..(n+1)..'] "#CURRENTPATH#Notes.ini"]')
		SKIN:Bang('[!WriteKeyValue Variables State'..(n+1)..' [#State'..n..'] "#CURRENTPATH#Notes.ini"]')
		SKIN:Bang('[!WriteKeyValue Variables Item'..(n+1)..' """'..SKIN:GetVariable('Item'..n):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"][!Refresh]')
	end
end
Here is a 'Tab' version called NoteBoardX created by AxxRael (can't find the link anymore) but here is the LUa code and skin code.
Notes.lua

Code: Select all

function Initialize()
	if SKIN:GetVariable('Tab5') ~= "" then
		SKIN:Bang('!SetOption', 'Input', 'MouseOverAction', '[!SetOption Input Text "Too many notes."][!SetOption Input SolidColor "160,0,0"][!UpdateMeter Input][!Redraw]')
		SKIN:Bang('!SetOption', 'Input', 'MouseLeaveAction', '[!SetOption Input Text "Add note."][!SetOption Input SolidColor "#BGColor#"][!UpdateMeter Input][!Redraw]')
		SKIN:Bang('!SetOption Input LeftMouseUpAction ""')
	end
end

function AddTab()
	local input, crlf = SKIN:GetVariable('Input'):gsub("\r\n", "#*CRLF*#")
	if input ~= "" then
		for i = 1, 4 do
			SKIN:Bang('!WriteKeyValue Variables Tab'..(i+1)..' """'..SKIN:GetVariable('Tab'..i):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
		end
		SKIN:Bang('!WriteKeyValue Variables Tab1 """'..input..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!Move #CURRENTCONFIGX# (#CURRENTCONFIGY#-4-'..(SKIN:GetMeter('Input'):GetH()*(crlf+1))..')][!Refresh]')
	end
end

function EditTabA(n)
	SKIN:Bang('!SetVariable TabOrig """'..SKIN:GetVariable('Tab'..n):gsub("\n", "\r\n")..'"""')
	SKIN:Bang('!CommandMeasure NoteboardInput "ExecuteBatch 2"')
end

function EditTabB(n)
	local input = SKIN:GetVariable('Input'):gsub("\r\n", "#*CRLF*#")
	if input ~= "" then
		SKIN:Bang('[!WriteKeyValue Variables Tab'..n..' """'..input..'""" "#CURRENTPATH#Notes.txt"][!Refresh]')
	else
		DeleteTab(n)
	end
end

function ClipTab(n)
	SKIN:Bang('!SetClip "'..SKIN:GetVariable('Tab'..n):gsub("\n", "\r\n")..'"')
end

function DeleteTab(n)
	for i = n, 4 do
		SKIN:Bang('!WriteKeyValue Variables Tab'..i..' """'..SKIN:GetVariable('Tab'..(i+1)):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
	end
	SKIN:Bang('!WriteKeyValue Variables Tab5 "" "#CURRENTPATH#Notes.txt"')
	SKIN:Bang('[!Move #CURRENTCONFIGX# (#CURRENTCONFIGY#+4+'..SKIN:GetMeter('Tab'..n):GetH()..')][!Refresh]')
end

function SwapTabUp(n)
	if n ~= "1" then
		SKIN:Bang('!WriteKeyValue Variables Tab'..n..' """'..SKIN:GetVariable('Tab'..(n-1)):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!WriteKeyValue Variables Tab'..(n-1)..' """'..SKIN:GetVariable('Tab'..n):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"][!Refresh]')
	end
end

function SwapTabDown(n)
	if n ~= "5" and SKIN:GetVariable('Tab'..(n+1)) ~= "" then
		SKIN:Bang('!WriteKeyValue Variables Tab'..n..' """'..SKIN:GetVariable('Tab'..(n+1)):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"')
		SKIN:Bang('[!WriteKeyValue Variables Tab'..(n+1)..' """'..SKIN:GetVariable('Tab'..n):gsub("\n", "#*CRLF*#")..'""" "#CURRENTPATH#Notes.txt"][!Refresh]')
	end
end
And the skin code Noteboard.ini

Code: Select all

[Rainmeter]
MouseLeaveAction=[!HideMeterGroup Edit][!Redraw]

[Metadata]
Name=Noteboard
Author=Axxrael
Version=1.0
Information=A customizable noteboard with 5 tabs storing basic multiline text. Text can be edited directly from meter with an .lua file doing the backend work. | Ctrl+Enter inserts a line break.

[Variables]
@Include=Notes.txt

FontSize=9
FontFace=Orbitron
TextColor=255,255,255
TitleBarHeight=35
NotepadColor=0,0,0,50
NoteBoardWidth=490
NoteBoardHeight=400
NotePadMargin=10
NotePadWidth=(#NoteBoardWidth#-(#NotePadMargin#*2))
NotePadHeight=(#NoteBoardHeight#-60)


Hide=0
Show=1

[NoteboardScript]
Measure=Script
ScriptFile=Notes.lua

[NoteBoard]
Meter=IMAGE
SolidColor=0,0,0,50
W=#NoteBoardWidth#
H=400

[Title]
Meter=STRING
Antialias=1
Text=Notes
X=5
Y=5
FontColor=#TextColor#
FontSize=14
FontFace=#FontFace#

[Maximize]
meter=STRING
text=[+]
StringAlign=right
FontColor=#TextColor#
FontSize=18
FontFace=#FontFace#
x=(#NoteBoardWidth#-10)
y=0
LeftMouseUpAction=[!WriteKeyValue Title Text "Notes" "#CURRENTPATH#Noteboard.ini"][!WriteKeyValue NoteBoard H "#NoteBoardHeight#" "#CURRENTPATH#Noteboard.ini"][!WriteKeyValue Variables Hide "0" "#CURRENTPATH#Noteboard.ini"][!WriteKeyValue Variables Show "1" "#CURRENTPATH#Noteboard.ini"][!redraw][!Refresh #CURRENTCONFIG#]
Hidden=#Show#

[Minimize]
meter=STRING
text=[-]
StringAlign=right
FontColor=#TextColor#
FontSize=18
FontFace=#FontFace#
x=(#NoteBoardWidth#-10)
y=0
LeftMouseUpAction=[!WriteKeyValue Title Text "Notes..." #CURRENTPATH#Noteboard.ini"][!WriteKeyValue NoteBoard H "#TitleBarHeight#" #CURRENTPATH#Noteboard.ini"][!WriteKeyValue Variables Hide "1" "#CURRENTPATH#Noteboard.ini"][!WriteKeyValue Variables Show "0" "#CURRENTPATH#Noteboard.ini"][!redraw][!Refresh #CURRENTCONFIG#]
Hidden=#Hide#

[MenuTab1]
Meter=IMAGE
MeterStyle=MenuTabs
SolidColor=#NotepadColor#
X=#NotePadMargin#
LeftMouseUpAction=[!SetOption MenuTab1 SolidColor "#NotepadColor#"][!SetOption MenuTab2 SolidColor "255,255,255,50"][!SetOption MenuTab3 SolidColor "255,255,255,50"][!SetOption MenuTab4 SolidColor "255,255,255,50"][!SetOption MenuTab5 SolidColor "255,255,255,50"][!HideMeter Tab2][!HideMeter Tab2Background][!HideMeter Tab3][!HideMeter Tab3Background][!HideMeter Tab4][!HideMeter Tab4Background][!HideMeter Tab5][!HideMeter Tab5Background][!ShowMeter Tab1Background][!ShowMeter Tab1]

[MenuTab2]
Meter=IMAGE
MeterStyle=MenuTabs
X=2R
LeftMouseUpAction=[!SetOption MenuTab2 SolidColor "#NotepadColor#"][!SetOption MenuTab1 SolidColor "255,255,255,50"][!SetOption MenuTab3 SolidColor "255,255,255,50"][!SetOption MenuTab4 SolidColor "255,255,255,50"][!SetOption MenuTab5 SolidColor "255,255,255,50"][!HideMeter Tab1][!HideMeter Tab1Background][!HideMeter Tab3][!HideMeter Tab3Background][!HideMeter Tab4][!HideMeter Tab4Background][!HideMeter Tab5][!HideMeter Tab5Background][!ShowMeter Tab2Background][!ShowMeter Tab2]

[MenuTab3]
Meter=IMAGE
MeterStyle=MenuTabs
X=2R
LeftMouseUpAction=[!SetOption MenuTab3 SolidColor "#NotepadColor#"][!SetOption MenuTab1 SolidColor "255,255,255,50"][!SetOption MenuTab2 SolidColor "255,255,255,50"][!SetOption MenuTab4 SolidColor "255,255,255,50"][!SetOption MenuTab5 SolidColor "255,255,255,50"][!HideMeter Tab1][!HideMeter Tab1Background][!HideMeter Tab2][!HideMeter Tab2Background][!HideMeter Tab4][!HideMeter Tab4Background][!HideMeter Tab5][!HideMeter Tab5Background][!ShowMeter Tab3Background][!ShowMeter Tab3]

[MenuTab4]
Meter=IMAGE
MeterStyle=MenuTabs
X=2R
LeftMouseUpAction=[!SetOption MenuTab4 SolidColor "#NotepadColor#"][!SetOption MenuTab1 SolidColor "255,255,255,50"][!SetOption MenuTab2 SolidColor "255,255,255,50"][!SetOption MenuTab3 SolidColor "255,255,255,50"][!SetOption MenuTab5 SolidColor "255,255,255,50"][!HideMeter Tab1][!HideMeter Tab1Background][!HideMeter Tab2][!HideMeter Tab2Background][!HideMeter Tab3][!HideMeter Tab3Background][!HideMeter Tab5][!HideMeter Tab5Background][!ShowMeter Tab4Background][!ShowMeter Tab4]

[MenuTab5]
Meter=IMAGE
MeterStyle=MenuTabs
X=2R
LeftMouseUpAction=[!SetOption MenuTab5 SolidColor "#NotepadColor#"][!SetOption MenuTab1 SolidColor "255,255,255,50"][!SetOption MenuTab2 SolidColor "255,255,255,50"][!SetOption MenuTab3 SolidColor "255,255,255,50"][!SetOption MenuTab4 SolidColor "255,255,255,50"][!HideMeter Tab1][!HideMeter Tab1Background][!HideMeter Tab2][!HideMeter Tab2Background][!HideMeter Tab3][!HideMeter Tab3Background][!HideMeter Tab4][!HideMeter Tab4Background][!ShowMeter Tab5Background][!ShowMeter Tab5]

; ----------------MEASURES--------------

[NoteboardInput]
Measure=Plugin
Plugin=InputText
SolidColor=0,0,0
X=#NotePadMargin#
Y=(#TitleBarHeight#+25)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-5)
StringAlign=LEFT
FontFace=#FontFace#
StringStyle=NORMAL
FontColor=#TextColor#
FontSize=#FontSize#
AntiAlias=1
FocusDismiss=1
Hidden=#Hide#
Command1=[!SetVariable Input """$UserInput$""" H="[Input:H]"][!CommandMeasure NoteboardScript AddTab() #CURRENTCONFIG#]
Command2=[!SetVariable Input """$UserInput$""" DefaultValue="#TabOrig#" Y="[Tab#Tab#:Y]" H="[Tab#Tab#:H]"][!CommandMeasure NoteboardScript EditTabB('#Tab#') #CURRENTCONFIG#]

; ----------------STYLES----------------

[MenuTabs]
SolidColor=255,255,255,50
Y=40
W=((#NotePadWidth#/5)-2)
H=20
Hidden=#Hide#

[Tabs]
X=#NotePadMargin#
Y=(#TitleBarHeight#+25)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-25)
StringAlign=LEFT
FontFace=#FontFace#
StringStyle=NORMAL
FontColor=#TextColor#
FontSize=#FontSize#
ClipString=2
ClipStringW=#NotePadWidth#
AntiAlias=1
SolidColor=#NotepadColor#
Hidden=#Hide#
MouseActionCursorName=Text
MouseOverAction=[!UpdateMeter #CURRENTSECTION#][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# SolidColor "#NotepadColor#"][!UpdateMeter #CURRENTSECTION#][!Redraw]
LeftMouseUpAction=[!CommandMeasure NoteboardScript EditTabA('#Tab#')]
MiddleMouseDownAction=!CommandMeasure NoteboardScript ClipTab('#Tab#')

; ----------------METERS----------------

[Tab1]
Meter=String
MeterStyle=Tabs
Group=Tabs
Text=#Tab1#

[Tab1Background]
Meter=Image
MeterStyle=TabsBackground
X=#NotePadMargin#
Y=(#TitleBarHeight#+5)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-5)
Group=Tabs
MouseOverAction=[!ShowMeterGroup Edit][!SetVariable Tab 1][!Update]

[Tab2]
Meter=String
MeterStyle=Tabs
Text=#Tab2#
Hidden=1

[Tab2Background]
Meter=Image
MeterStyle=TabsBackground
X=#NotePadMargin#
Y=(#TitleBarHeight#+5)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-5)
MouseOverAction=[!ShowMeterGroup Edit][!SetVariable Tab 2][!Update]
Hidden=1

[Tab3]
Meter=String
MeterStyle=Tabs
Text=#Tab3#
Hidden=1

[Tab3Background]
Meter=Image
MeterStyle=TabsBackground
X=#NotePadMargin#
Y=(#TitleBarHeight#+5)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-5)
MouseOverAction=[!ShowMeterGroup Edit][!SetVariable Tab 3][!Update]
Hidden=1

[Tab4]
Meter=String
MeterStyle=Tabs
Text=#Tab4#
Hidden=1

[Tab4Background]
Meter=Image
MeterStyle=TabsBackground
X=#NotePadMargin#
Y=(#TitleBarHeight#+5)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-5)
MouseOverAction=[!ShowMeterGroup Edit][!SetVariable Tab 4][!Update]
Hidden=1

[Tab5]
Meter=String
MeterStyle=Tabs
Text=#Tab5#
Hidden=1

[Tab5Background]
Meter=Image
MeterStyle=TabsBackground
X=#NotePadMargin#
Y=(#TitleBarHeight#+5)
W=(#NoteBoardWidth#-(#NotePadMargin#*2))
H=((#NoteBoardHeight#-(#TitleBarHeight#+#NotePadMargin#))-5)
MouseOverAction=[!ShowMeterGroup Edit][!SetVariable Tab 5][!Update]
Hidden=1
Perhaps some of this can be used.
User avatar
Yincognito
Rainmeter Sage
Posts: 7188
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Text editor skin?

Post by Yincognito »

Since it's the appropriate thread for it, here is my old HotKey "InputBox.ini" multiline text editor - just added the ENTER and SPACE to it to demonstrate the - albeit limited since currently only A, S and D and a few others are added, both lower and upper case - functionality (this obviously requires Brian's HotKey plugin here):

Code: Select all

[Variables]
InitialText=
Key=
CursorPattern0=\|$
CursorPattern1=^$
CursorPatternIndex=0

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
OnRefreshAction=[!SetOption Text String "#InitialText#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!SetOption Text String "[*Text*][*\x200B*]#*Key*#"]

---Measures---

[a]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[SHIFT A]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[s]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[SHIFT S]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[d]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[SHIFT D]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[SPACE]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[ENTER]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[BACKSPACE]
Measure=Plugin
Plugin=HotKey
HotKey=#CURRENTSECTION#
ShowAllKeys=1
KeyDownAction=[!SetVariable Key "#CURRENTSECTION#"][!UpdateMeasure Text][!UpdateMeter Input][!Redraw][!UpdateMeasure "#CURRENTSECTION#"]
DynamicVariables=1

[Text]
Measure=String
String=[Text][\x200B]#Key#
RegExpSubstitute=1
Substitute="(?siU)(.)[\x200B]SPACE$":"\1 ","(?siU)(.)[\x200B]ENTER$":"\1#CRLF#","(?siU)(?:.[\x200B])?BACKSPACE$":"","(?siU).[\x200B]SHIFT (.)":"\1","[\x200B]":""
UpdateDivider=-1
DynamicVariables=1

---Meters---

[Background]
Meter=Image
SolidColor=47,47,47,255
W=400
H=400

[Input]
Meter=String
X=5r
Y=5r
W=390
H=390
FontFace=Consolas
FontSize=16
SolidColor=0,0,0,255
FontColor=255,255,255,255
AntiAlias=1
MeasureName=Text
Text="%1|"
InlineSetting=Color | 0,0,0,255
InlinePattern=[#CursorPattern[#CursorPatternIndex]]
OnUpdateAction=[!SetVariable CursorPatternIndex (1-#CursorPatternIndex#)]
DynamicVariables=1
InputBox.jpg
Adding new keys is quite easy and straightforward: just copy paste one of the key measures, modify its name to resemble exactly the key (i.e. f would be [f] measure, F would be [SHIFT F]) in a way that can be manipulated later on in the [Text] measure (where only "special" keys like non-alphanumeric stuff need handling) using the "invisible" zero-width space character aka [\x200B] as a separator between successive keys or key sequences and some relatively simple regex to replace the measure name corresponding to the pressed key with the actual character or, in the case of BACKSPACE, action (e.g. deleting the last character).

This is far from being complete or handling all kinds of exceptions and situations (like international keyboards and other such stuff), but at least it's a start, if one wants to follow on it. It can be made to pass the text to Lua for saving in a file and naturally Lua can be made to pass text to the [Text] measure or the #InitialText# variable (the latter can be of course edited by the user as well). The reason why I stopped developing this is because I couldn't figure an easy (or easier) way to translate the UP and DOWN actions as well as the mouse pixel position when clicked (aka $MouseX$ and $MouseY$) into something that relates to a position within the characters of the string - in other words, how do I know that, say, mouse clicking at X=74 and Y=26 is the 3rd character from the 2nd line of text (so I can move the cursor and the subsequent actions at that place using the regex). If it were only about the monospaced fonts that would have been feasible, but with the different styles and sizes of a proportional font, these things become complicated really fast.

But then, it can be fun to play with from time to time, haha!
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7188
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Text editor skin?

Post by Yincognito »

eclectic-tech wrote: February 10th, 2022, 9:32 pmPerhaps some of this can be used.
That's for sure! Thanks, eclectic-tech. Personally I'm not the one who's necessarily interested in making a text editor skin, I'm much more interested in HOW such a skin can be made - and specific to this case, how these guys got around the InputText removing the new line characters once $UserInput$ is used in a bang. As far as I can tell, the technique involves some back and forth between #*CRLF*#-s and actual \r\n newlines, along with some !Refresh and using the stored variables, but apart from that I'll probably leave understanding the concept / pseudo-code steps for another time, preferably when not tired ... unless you can shed some light on it, since you're there as an author as well. :D
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: Text editor skin?

Post by death.crafter »

Yincognito wrote: February 10th, 2022, 11:03 pm That's for sure! Thanks, eclectic-tech. Personally I'm not the one who's necessarily interested in making a text editor skin, I'm much more interested in HOW such a skin can be made - and specific to this case, how these guys got around the InputText removing the new line characters once $UserInput$ is used in a bang. As far as I can tell, the technique involves some back and forth between #*CRLF*#-s and actual \r\n newlines, along with some !Refresh and using the stored variables, but apart from that I'll probably leave understanding the concept / pseudo-code steps for another time, preferably when not tired ... unless you can shed some light on it, since you're there as an author as well. :D
This is how!
MultilineInput - Text Editor_1.0.rmskin
Ohh! And I am not limiting the scroll amount, vertical or horizontal(shift + scroll). So be careful!
You do not have the required permissions to view the files attached to this post.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7188
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Text editor skin?

Post by Yincognito »

death.crafter wrote: February 10th, 2022, 11:29 pm This is how!

MultilineInput - Text Editor_1.0.rmskin
Ohh! And I am not limiting the scroll amount, vertical or horizontal(shift + scroll). So be careful!
I mean, you're right with the message and the plugin is great, but:
- while typing works, Enter hides the cursor instead of placing it on the following line or inserting a new line at the cursor and breaking the text in 2; maybe I'm wrong, but I'm not sure this is supposed to happen :???:
- in my previous reply I meant that I was curious about a simple explanation on how multiline editing is achieved instead of trying to understand it from code 8-)

Anyway, it seems the number of alternatives is increasing, which is good. Now if such alternatives - including my own poor attempt - were simple / simpler as well, that would be excellent. If your work is about an InputText enhancement, I look forward to see it fully polished (guess that asking without Lua is too much, but who knows)... :thumbup:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5407
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Text editor skin?

Post by eclectic-tech »

Yincognito wrote: February 11th, 2022, 1:06 am I mean, you're right with the message and the plugin is great, but:
- while typing works, Enter hides the cursor instead of placing it on the following line or inserting a new line at the cursor and breaking the text in 2; maybe I'm wrong, but I'm not sure this is supposed to happen :???:
I experienced the same when trying to create a 'blank' line, but the clean input scheme looks great.
Yincognito wrote:- in my previous reply I meant that I was curious about a simple explanation on how multiline editing is achieved instead of trying to understand it from code 8-)
A quick explanation would be the script handles line breaks \r\n or \n, by replacing them with #*CRLF*# when using !WriteKeyValue bangs.

The script also adds the ability to copy the item to the clipboard, re-arrange the placement of items, and strikethrough or delete items.

As for the lines themselves, in the original variant each item (single line or multiple lines) is saved as a separate variable, up to 16 items.

In the 'tab' variant, each tab 'page' is saved as a single variable (5 tabs in the code above). I have not used the 'tab' variant enough to add much more info.
User avatar
Yincognito
Rainmeter Sage
Posts: 7188
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Text editor skin?

Post by Yincognito »

eclectic-tech wrote: February 11th, 2022, 1:29 amI experienced the same when trying to create a 'blank' line, but the clean input scheme looks great.
Looks great indeed, but what you mean by the 'clean input scheme'? The enter issue happens to me even after I delete the entire content, if by any chance you referred to that...
eclectic-tech wrote: February 11th, 2022, 1:29 amA quick explanation would be the script handles line breaks \r\n or \n, by replacing them with #*CRLF*# when using !WriteKeyValue bangs.
That's pretty much what I was interested in, though I had the 'feeling' that refreshes and stoping mouse actions played a part. Still have no idea how the implementation keeps the input text at more than one line after double clicking on it though, that is the mystery for me. Keeping variables right is not difficult, but forcing the input text to stay multiline when clicking to edit a previously multiline text is either some kind of magic or an illlusion, LMAO. Unless one can manipulate the $UserInput$ macro at will, that is.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: Text editor skin?

Post by death.crafter »

Yincognito wrote: February 11th, 2022, 1:06 am I mean, you're right with the message and the plugin is great, but:
- while typing works, Enter hides the cursor instead of placing it on the following line or inserting a new line at the cursor and breaking the text in 2; maybe I'm wrong, but I'm not sure this is supposed to happen :???:
- in my previous reply I meant that I was curious about a simple explanation on how multiline editing is achieved instead of trying to understand it from code 8-)

Anyway, it seems the number of alternatives is increasing, which is good. Now if such alternatives - including my own poor attempt - were simple / simpler as well, that would be excellent. If your work is about an InputText enhancement, I look forward to see it fully polished (guess that asking without Lua is too much, but who knows)... :thumbup:
It's Shift + Enter.

Only Enter saves the file. I just modified my example skin a bit to make this. So didn't put much into functionalities.

Also, yeah, I made this to over come the lacunas of InputText. But when actually making it, I realized multiline input is harder to make. I will try to perfect it later sometime, as I am busy with other things. I just released the plugin in case someone else is able to make it.
from the Realm of Death