It is currently April 3rd, 2020, 12:01 pm

TextClock 1.2 and 2.1

Post your work-in-progress and completed skins to share and discuss.
User avatar
jsmorley
Developer
Posts: 20433
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

TextClock 1.2 and 2.1

Post by jsmorley »

Displays the time with a "minutes before/after hour" analog to text format

ONE MINUTE AFTER TEN
EIGHTEEN AFTER TEN
HALF PAST TEN
TWENTY SEVEN TO ELEVEN
QUARTER TO ELEVEN
FIVE MINUTES TO ELEVEN
ELEVEN O'CLOCK

Requires Rainmeter 4.0 or later from https://rainmeter.net 1

Edit: Version 1.1 Corrects a bug in the Lua when the hour is 12.

Edit: Version 1.2 changes AfterText to "after" and adds HalfText as "half" to be more consistent with American spoken usage.

Feel free to change the three variables to fit your culture's usage. You might use "past" at all times, or use "til" or "until". How these are spoken varies depending on where you are from. Simply mentally "say" the various times until you find the usage that "sounds right" to your ear.
TextClock.ini:

Code: Select all

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

[Metadata]
Name=TextClock
Author=JSMorley
Version=1.2 - Apr 30, 2016
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Displays the time with a "minutes before/after hour" text format||i.e "QUARTER AFTER TEN"||Requires Rainmeter 4.0 or later.

[Variables]
AfterText=after
UntilText=to
HalfText=past

[MeasureTime]
Measure=Script
ScriptFile=TextClock.lua

[MeterTime]
Meter=String
MeasureName=MeasureTime
InlineSetting=Face | Segoe UI
InlineSetting2=Size | 25
InlineSetting3=Weight | 100
InlineSetting4=Color | 255,255,255,255
InlineSetting5=Case | Upper
InlineSetting6=Size | 20
InlinePattern6=(?i)minute || minutes
InlineSetting7=Size | 20
InlinePattern7=(?i)#AfterText# || #UntilText# || #HalfText#
SolidColor=0,0,0,1
AntiAlias=1
TextClock.lua:

Code: Select all

function Initialize()

		afterText = SKIN:GetVariable('AfterText')
		untilText = SKIN:GetVariable('UntilText')
		halfText = SKIN:GetVariable('HalfText')
		
		numTable = {}
		
		numTable['0'] = 'zero'
		numTable['1'] = 'one'
		numTable['2'] = 'two'
		numTable['3'] = 'three'
		numTable['4'] = 'four'
		numTable['5'] = 'five'
		numTable['6'] = 'six'
		numTable['7'] = 'seven'
		numTable['8'] = 'eight'
		numTable['9'] = 'nine'
		numTable['10'] = 'ten'
		numTable['11'] = 'eleven'
		numTable['12'] = 'twelve'
		numTable['13'] = 'thirteen'
		numTable['14'] = 'fourteen'
		numTable['15'] = 'quarter'
		numTable['16'] = 'sixteen'
		numTable['17'] = 'seventeen'
		numTable['18'] = 'eighteen'
		numTable['19'] = 'nineteen'
		numTable['30'] = 'half'

end

function Update()

	hour = tonumber(os.date('%I'))
	minute = tonumber(os.date('%M'))
	
	if minute < 30 then
		adjustedMinute = minute
		midText = afterText
	elseif minute == 30 then
		adjustedMinute = minute
		midText = halfText
	else
		midText = untilText
		adjustedMinute = 60 - minute
		hour = hour == 12 and 1 or hour + 1
	end

	if adjustedMinute >= 20 and adjustedMinute < 30 then 
		if adjustedMinute == 20 then
			minuteText = 'twenty'
		else
			minuteText = 'twenty'..' '..numTable[tostring(adjustedMinute - 20)]
		end
	else
		if adjustedMinute < 10 then
			if adjustedMinute == 1 then
				minuteText = numTable[tostring(adjustedMinute)]..' minute'
			else
				minuteText = numTable[tostring(adjustedMinute)]..' minutes'
			end
		else
			minuteText = numTable[tostring(adjustedMinute)]
		end
	end

	if adjustedMinute == 0 then
		return numTable[tostring(hour)]..' o\'clock'
	else
		return minuteText.. ' '..midText..' '..numTable[tostring(hour)]
	end

end
1 Note: The requirement for Rainmeter 4.0 is due to the InlineSetting options I use in the skin. Feel free to create your own skin and copy and use the .lua file above if you want to do something cosmetically different or use this on Rainmeter 3.3. This is really all about the Lua.

Edit:

Expanded the concept a tad... ;-)
User avatar
Refugeesus
Posts: 2
Joined: May 4th, 2016, 3:27 am

Re: TextClock 1.1

Post by Refugeesus »

This is great. I have downloaded 1.2

My current concern is I have lost the "minute/s" text from my display.

I admit to fiddling with the ini to try and learn and customise to suit me, but I reloaded your original file and found the text was missing originally.

I have no training or knowledge of this stuff, just trying to piece it together and learn as I go.

Here is my modified version of your ini file. Thanks in advance for your help.

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

[Metadata]
Name=TextClock
Author=JSMorley
Version=1.2 - Apr 30, 2016
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Displays the time with a "minutes before/after hour" text format||i.e "QUARTER AFTER TEN"||Requires Rainmeter 4.0 or later.

[Variables]
AfterText=after
UntilText=to
HalfText=past

[MeasureTime]
Measure=Script
ScriptFile=TextClock.lua

[MeterTime]
Meter=String
MeasureName=MeasureTime
InlineSetting=Face | Agency FB
InlineSetting2=Size | 80
InlineSetting3=Weight | 100
InlineSetting4=Color | 255,850,850,255
InlineSetting5=Case | Upper
InlineSetting6=Size | 40
InlinePattern6=(?i)minute || minutes
InlineSetting7=Size | 40
InlinePattern7=(?i)#AfterText# || #UntilText# || #HalfText#
SolidColor=0,0,0,1
AntiAlias=1
User avatar
jsmorley
Developer
Posts: 20433
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: TextClock 1.1

Post by jsmorley »

The "minute(s)" text is only shown during the first and last 9 minutes of the hour...

At least in my little corner of the world, folks tend to say "3 minutes after", but not "20 minutes after", but rather "20 after". Same with "to". It sounds "right" to my ear to say "20 to", and "8 minutes to".

This is all very cultural and regional, and even has a lot of subtleties having to do with the context you are using the time in. Your brain will automatically evaluate whether the context is "what time is it?" vs "what is the time". Those, while really subtle, are cues that will make your brain respond with "a quarter after three" for one, and "three fifteen" for the other. These are virtually unconscious decisions you instantly make. for instance, most folks will switch from "to" to "before" or "until" or "til" when a number ends in the "to" sound, like "22". So while you might say "twenty three to seven", you are quite likely to say "twenty two before/until/til seven", and not even realize that you avoided the duplicate "to to" sound. There really are no hard-and-fast rules, just things that were imprinted on you when you were very young that you don't even think about. Anyway, feel free to tinker with the Lua if you want to make it behave differently.
User avatar
Refugeesus
Posts: 2
Joined: May 4th, 2016, 3:27 am

Re: TextClock 1.1

Post by Refugeesus »

Cheers. I thought it may be that simple. I am trying to decipher the code as I go. Appreciate the noob help. I will stop searching for an answer that doesn't exist.
dvo
Posts: 698
Joined: February 7th, 2016, 6:08 am

Re: TextClock 1.1

Post by dvo »

dutch version doesn't work like that :(
dvo
Posts: 698
Joined: February 7th, 2016, 6:08 am

Re: TextClock 1.1

Post by dvo »

:D
Last edited by dvo on May 12th, 2016, 7:39 pm, edited 1 time in total.
dvo
Posts: 698
Joined: February 7th, 2016, 6:08 am

Re: TextClock 1.1

Post by dvo »

tnx for all your help ... :D
User avatar
jsmorley
Developer
Posts: 20433
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: TextClock 2.0

Post by jsmorley »

Expanded on the concept a bit...

Code: Select all

function Initialize()

		measureUnits = SKIN:GetMeasure('UnitsChild')
		measureTemperature = SKIN:GetMeasure('TemperatureChild')
		measureConditions = SKIN:GetMeasure('ConditionsChild')
		
		afterText = SKIN:GetVariable('AfterText')
		untilText = SKIN:GetVariable('UntilText')
		halfText = SKIN:GetVariable('HalfText')
		
		dayTable = {}
		
		dayTable['0'] = ''
		dayTable['1'] = 'first'
		dayTable['2'] = 'second'
		dayTable['3'] = 'third'
		dayTable['4'] = 'forth'
		dayTable['5'] = 'fifth'
		dayTable['6'] = 'sixth'
		dayTable['7'] = 'seventh'
		dayTable['8'] = 'eighth'
		dayTable['9'] = 'ninth'
		dayTable['10'] = 'tenth'
		dayTable['11'] = 'eleventh'
		dayTable['12'] = 'twelfth'
		dayTable['13'] = 'thirteenth'
		dayTable['14'] = 'fourteenth'
		dayTable['15'] = 'fifteenth'
		dayTable['16'] = 'sixteenth'
		dayTable['17'] = 'seventeenth'
		dayTable['18'] = 'eighteenth'
		dayTable['19'] = 'nineteenth'
		dayTable['20'] = 'twentieth'
		dayTable['30'] = 'thirtieth'
		
		numTable = {}
		
		numTable['0'] = 'zero'
		numTable['1'] = 'one'
		numTable['2'] = 'two'
		numTable['3'] = 'three'
		numTable['4'] = 'four'
		numTable['5'] = 'five'
		numTable['6'] = 'six'
		numTable['7'] = 'seven'
		numTable['8'] = 'eight'
		numTable['9'] = 'nine'
		numTable['10'] = 'ten'
		numTable['11'] = 'eleven'
		numTable['12'] = 'twelve'
		numTable['13'] = 'thirteen'
		numTable['14'] = 'fourteen'
		numTable['15'] = 'fifteen'
		numTable['16'] = 'sixteen'
		numTable['17'] = 'seventeen'
		numTable['18'] = 'eighteen'
		numTable['19'] = 'nineteen'
		numTable['20'] = 'twenty'
		numTable['30'] = 'thirty'
		numTable['40'] = 'forty'
		numTable['50'] = 'fifty'
		numTable['60'] = 'sixty'
		numTable['70'] = 'seventy'
		numTable['80'] = 'eighty'
		numTable['90'] = 'ninety'
		numTable['100'] = 'one hundred'

end

function Update()

	TimeString()
	DateString()
	ConditionsString()
	TemperatureString()
	
end

function TimeString()

	hour24 = tonumber(os.date('%H'))
	hour12 = tonumber(os.date('%I'))
	minute = tonumber(os.date('%M'))

	if hour24 < 12 then
		partOfDay = 'morning'
	elseif hour24 >= 12 and hour24 < 17 then
		partOfDay = 'afternoon'
	else
		partOfDay = 'evening'
	end
	
	if minute < 30 then
		adjustedMinute = minute
		midText = afterText
	elseif minute == 30 then
		adjustedMinute = minute
		midText = halfText
	else
		midText = untilText
		adjustedMinute = 60 - minute
		hour12 = hour12 == 12 and 1 or hour12 + 1
	end

	if adjustedMinute >= 20 and adjustedMinute < 30 then 
		if adjustedMinute == 20 then
			minuteText = 'twenty'
		else
			minuteText = 'twenty'..'-'..numTable[tostring(adjustedMinute - 20)]
		end
	else
		if adjustedMinute < 10 then
			if adjustedMinute == 1 then
				minuteText = numTable[tostring(adjustedMinute)]..' minute'
			else
				minuteText = numTable[tostring(adjustedMinute)]..' minutes'
			end
		elseif adjustedMinute == 15 then
			minuteText = 'quarter'
		elseif adjustedMinute == 30 then
			minuteText = 'half'
		else
			minuteText = numTable[tostring(adjustedMinute)]
		end
	end

	if hour24 == 12 and minute == 0 then
		SKIN:Bang('!SetOption', 'MeterTime', 'Text', 'it\'s '..numTable[tostring(hour12)]..' o\'clock noon')
	end
	if hour24 == 0 and minute == 0 then
		SKIN:Bang('!SetOption', 'MeterTime', 'Text', 'it\'s '..numTable[tostring(hour12)]..' o\'clock midnight')
	end	
	if adjustedMinute == 0 then
		SKIN:Bang('!SetOption', 'MeterTime', 'Text', 'it\'s '..numTable[tostring(hour12)]..' o\'clock'..' in the '..partOfDay)
	else
		SKIN:Bang('!SetOption', 'MeterTime', 'Text', 'it\'s '..minuteText.. ' '..midText..' '..numTable[tostring(hour12)]..' in the '..partOfDay)
	end

end

function DateString()

	weekdayName = os.date('%A')
	monthName = os.date('%B')
	
	dayNumber = os.date('%d')

	if tonumber(dayNumber) < 20 or tonumber(dayNumber) % 10 == 0 then
		dayText = dayTable[dayNumber]
	else
		dayLeft = string.sub(dayNumber, 1, 1) * 10
		dayRight = string.sub(dayNumber, 2)
		dayText = numTable[tostring(dayLeft)]..'-'..dayTable[dayRight]
	end
	
	SKIN:Bang('!SetOption', 'MeterDate', 'Text', weekdayName..', the '..dayText..' of '..monthName)
	
end

function ConditionsString()

	conditionsText = measureConditions:GetStringValue()
	conditionsText = string.gsub(conditionsText, ' / ', ' and ')
	SKIN:Bang('!SetOption', 'MeterConditions', 'Text', 'the weather is '..conditionsText)

end

function TemperatureString()

	tempUnit = measureUnits:GetStringValue()
	tempValue = tonumber(measureTemperature:GetStringValue())
	
	if tempUnit == 'C' then
		if tempValue > 31.7 then tempDesc = 'really hot'
			elseif tempValue > 26.1 then tempDesc = 'sort of hot'
			elseif tempValue > 15 then tempDesc = 'fairly warm'
			elseif tempValue > 9.4 then tempDesc = 'fairly cool'
			elseif tempValue > 0 then tempDesc = 'sort of chilly'
			else tempDesc = 'really cold'
		end
	end
	
	if tempUnit == 'F' then
		if tempValue > 89 then tempDesc = 'really hot'
			elseif tempValue > 79 then tempDesc = 'sort of hot'
			elseif tempValue > 59 then tempDesc = 'fairly warm'
			elseif tempValue > 49 then tempDesc = 'fairly cool'
			elseif tempValue > 32 then tempDesc = 'sort of chilly'
			else tempDesc = 'really cold'
		end
	end	
	
	if tempValue < 0 then
		tempValue = math.abs(tempValue)
		belowZero = 1
	else
		belowZero = 0
	end
	
	if tempValue >= 100 then
		hundredText = 'one hundred and '
		tempValue = tempValue - 100
	else
		hundredText = ''
	end
	
	if tempValue < 20 or tempValue % 10 == 0 then
		tempText = numTable[tostring(tempValue)]
	else
		tempLeft = string.sub(tempValue, 1, 1) * 10
		tempRight = string.sub(tempValue, 2)
		tempText = numTable[tostring(tempLeft)]..'-'..numTable[tempRight]
	end
	
	if belowZero == 0 then
		SKIN:Bang('!SetOption', 'MeterTemperature', 'Text', 'it\'s '..tempDesc..' at '..hundredText..tempText..' degrees')
	else
		SKIN:Bang('!SetOption', 'MeterTemperature', 'Text', 'it\'s '..tempDesc..' at '..hundredText..tempText..' degrees below zero')
	end
	
end
1.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
balala
Rainmeter Sage
Posts: 10034
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: TextClock 1.1

Post by balala »

I allowed myself to work a bit with your TextClock, adding an, I'd say, nice fade effect.
So, the code of the skin:

Code: Select all

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

[Metadata]
Name=TextClock
Author=JSMorley
Version=1.2 - Apr 30, 2016
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Displays the time with a "minutes before/after hour" text format||i.e "QUARTER AFTER TEN"||Requires Rainmeter 4.0 or later.

[Variables]
AfterText=after
UntilText=to
HalfText=past
Alpha=0
U=[!UpdateMeasure "MeasureSliders"][!UpdateMeterGroup "Time"][!Redraw]

[StringStyle]
X=150
Y=45
W=300
H=90
ClipString=1
FontFace=Calibri
FontSize=18
StringStyle=Normal
StringAlign=CENTERCENTER
SolidColor=0,0,0,1
StringEffect=Border
AntiAlias=1
DynamicVariables=1
Group=Time

[MeasureTime]
Measure=Script
ScriptFile=#@#TextClock.lua

[MeasureSeconds]
Measure=Time
Format=%#S
IfCondition=(MeasureSeconds=0)
IfTrueAction=[!CommandMeasure MeasureSliders "Execute 1"]
IfFalseAction=[!CommandMeasure MeasureSliders "Stop 1"][!SetVariable Alpha "0"]

[MeasureSliders]
Measure=Plugin
Plugin=ActionTimer
Group=Sliders
ActionList1=Repeat Tran,15,55
Tran=[!SetVariable Alpha "(Clamp(#Alpha#+5,0,255))"]#U#
DynamicVariables=1

[MeterTimeCurrent]
Meter=String
MeterStyle=StringStyle
FontColor=255,255,255,#Alpha#
FontEffectColor=0,0,0,#Alpha#
Text=#Time#

[MeterTimePrev]
Meter=String
MeterStyle=StringStyle
FontColor=255,255,255,(255-#Alpha#)
FontEffectColor=0,0,0,(255-#Alpha#)
Text=#OTime#
And the modified TextClock.lua:

Code: Select all

function Initialize()
	afterText = SKIN:GetVariable('AfterText')
	untilText = SKIN:GetVariable('UntilText')
	halfText = SKIN:GetVariable('HalfText')
	numTable = {}
	numTable['0'] = 'zero'
	numTable['1'] = 'one'
	numTable['2'] = 'two'
	numTable['3'] = 'three'
	numTable['4'] = 'four'
	numTable['5'] = 'five'
	numTable['6'] = 'six'
	numTable['7'] = 'seven'
	numTable['8'] = 'eight'
	numTable['9'] = 'nine'
	numTable['10'] = 'ten'
	numTable['11'] = 'eleven'
	numTable['12'] = 'twelve'
	numTable['13'] = 'thirteen'
	numTable['14'] = 'fourteen'
	numTable['15'] = 'quarter'
	numTable['16'] = 'sixteen'
	numTable['17'] = 'seventeen'
	numTable['18'] = 'eighteen'
	numTable['19'] = 'nineteen'
	numTable['30'] = 'half'
end

function Update()
	OldTime = SKIN:GetVariable('Time')
	hour = tonumber(os.date('%I'))
	minute = tonumber(os.date('%M'))
	if minute < 30 then
		adjustedMinute = minute
		midText = afterText
	elseif minute == 30 then
		adjustedMinute = minute
		midText = halfText
	else
		midText = untilText
		adjustedMinute = 60 - minute
		hour = hour == 12 and 1 or hour + 1
	end
	if adjustedMinute >= 20 and adjustedMinute < 30 then 
		if adjustedMinute == 20 then
			minuteText = 'twenty'
		else
			minuteText = 'twenty'..' '..numTable[tostring(adjustedMinute - 20)]
		end
	else
		if adjustedMinute < 10 then
			if adjustedMinute == 1 then
				minuteText = numTable[tostring(adjustedMinute)]..' minute'
			else
				minuteText = numTable[tostring(adjustedMinute)]..' minutes'
			end
		else
			minuteText = numTable[tostring(adjustedMinute)]
		end
	end
	if adjustedMinute == 0 then
		SKIN:Bang('!SetVariable', 'Time', numTable[tostring(hour)]..' o\'clock')
	else
		SKIN:Bang('!SetVariable', 'Time', minuteText.. ' '..midText..' '..numTable[tostring(hour)])
	end
	SKIN:Bang('!SetVariable', 'OTime', OldTime)
end
Note that this is related not to the latest, 2.0, version, posted a few minutes ago, but to the first one. I didn't use your string style, but I've created mine own one. I used the ActionTimer plugin (an extremely good toolo, in my opinion - congratulations to the developers).
So, what you think about this?
You do not have the required permissions to view the files attached to this post.
Last edited by balala on May 15th, 2016, 5:54 pm, edited 1 time in total.
User avatar
jsmorley
Developer
Posts: 20433
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: TextClock 1.2 and 2.0

Post by jsmorley »

Very cool...