Gtkdialog Calendar

For discussions about programming, and for programming questions and advice


Moderator: Forum moderators

recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Gtkdialog Calendar

Post by recobayu »

The last and better version is on the last post.
From this first post to the next, describing my code from simple to complex.

Here is my simple calendar using gtkdialog:

Code: Select all

#!/bin/bash

buat_tombol(){
    echo '
        <button width-request="50" height-request="50" relief="2">
            <label>'$1'</label>
            <action>echo '$1' `date "+%B %Y"`</action>
        </button>'
}

export -f buat_tombol

buat_perbaris(){

i=0
IFS=''
cal|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
#echo baris $i: "$line"

echo '
    <hbox spacing="0">'
for j in {1..7};do
    
    tgl=`echo "$line"|cut -d "," -f $j`
    if [ "$tgl" == "  " -o "$tgl" == " " -o "$tgl" == ""  ];then tgl=" -";fi
    buat_tombol "$tgl"
    
done
echo '
    </hbox>'
((i++))
done

}

export -f buat_perbaris


#h_screen=`xwininfo -root|sed '/Height/!d;s/.* //'`
#<window height-request="'$h_screen'" width-request="360">

echo '
<window>
<vbox spacing="0">
    <button relief="2">
        <label>'"`date "+%B %Y"`"'</label>
    </button>
'"`buat_perbaris`"'

</vbox>
</window>
'>gui_kalendermuks
gtkdialog -f gui_kalendermuks
Attachments
Screenshot.png
Screenshot.png (13.39 KiB) Viewed 2680 times
Last edited by recobayu on Tue Feb 22, 2022 7:16 pm, edited 1 time in total.
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Month

Code: Select all

#!/bin/sh

bln(){
	m=1
	
	for i in 1 2 3 4;do
		echo '		<hbox space-fill="true" space-expand="true">'
		for j in 1 2 3;do
		
		case $m in
			1) b="Jan";;
			2) b="Feb";;
			3) b="Mar";;
			4) b="Apr";;
			5) b="Mei";;
			6) b="Jun";;
			7) b="Jul";;
			8) b="Ags";;
			9) b="Sep";;
			10)b="Okt";;
			11)b="Nov";;
			12)b="Des";;
		esac
		
			echo '			<button width-request="50" height-request="50">
				<label>'$b'</label>
			</button>
			'
			((m++))
		done
		echo '		</hbox>'
	done
	
}

echo '
<window>

<notebook>
	<vbox>
		<button>
			<label>bulan ini</label>
		</button>
	</vbox>
	<vbox>
		'"`bln`"'
	</vbox>
	<input file>inputfile</input>
</notebook>
</window>' > guibln

gtkdialog -f guibln
User avatar
puppy_apprentice
Posts: 691
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: Gtkdialog Calendar

Post by puppy_apprentice »

Something went wrong:

gtk-cal.png
gtk-cal.png (4 KiB) Viewed 2670 times
terminal-test.png
terminal-test.png (7.91 KiB) Viewed 2670 times

Please use English names for functions and comments.

Attachments
gui_kalendermuks.gz
erase .gz
(8.46 KiB) Downloaded 76 times
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Hi @puppy_apprentice
what version of your puppylinux?
I try on several puppy (imppup64, slacko64, voidpup64), bullseye-dog, and linux mint 20.3, and it can run.

Last edited by recobayu on Tue Feb 22, 2022 7:11 pm, edited 1 time in total.
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar using SVG button

Post by recobayu »

This calendar button using SVG file as input on it's number.

Code: Select all

#!/bin/bash

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>echo</action>
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
	
}

amonth(){
	m="$1"
	Y="$2"
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	B=`date -d 2022-"$m"-1 '+%B'`
	echo "$B $Y" > monthyear

	#echo "$m $Y"	#debug
	
	row=1
	cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			svg_number "$number_grid" 16 "number/grid_$row$column.svg"
		fi
		
		done
		((row++))
	done
}



svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}

export -f svg_number


mkdir -p number
#amonth 4
amonth


echo '
<window title="kalendermuks">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<label>'`cat monthyear`'</label>
			<action>refresh:btn_grid_11</action>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
		</button>
		
		<button relief="2" width-request="46" height-request="40">
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>
</window>' > guikalender

gtkdialog -f guikalender

We can use different month by change the value in line 65 (for example):

Code: Select all

amonth 4

to show April and

Code: Select all

amonth

to show this month

Attachments
amonth 4 --&gt; April
amonth 4 --> April
Screenshot.png (18.53 KiB) Viewed 2631 times
amonth --&gt; this month
amonth --> this month
Screenshot2.png (18.18 KiB) Viewed 2631 times
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

This script can refresh the button's "label" by click the arrow previous and next month.

Changelog:
1. Add arrow (previous and next) month
2. Grabfocus to current date
3. Using svg file as "label" of button grid

feel free to give advice.
Thank you

Code: Select all

#!/bin/bash

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>echo</action>
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
}

amonth(){
	m="$1"
	Y="$2"
	
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
	echo "$Y-$m-1" > year_month
	svg_word "$BY" 20 number/monthyear.svg

	#echo "$m $Y"	#debug
	
	row=1
	cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			svg_number "$number_grid" 16 "number/grid_$row$column.svg"
		fi
		
		today=`date "+%_d"`
		if [ "$number_grid" == "$today" ];then echo "btn_grid_$row$column" > btn_today;fi
		
		done
		((row++))
	done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
	BY=`date -d "$new_month" "+%B %Y"`
	m=`date -d "$new_month" "+%m"`
	Y=`date -d "$new_month" "+%Y"`
	
	amonth "$m" "$Y"
}
export -f change_month

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3"
}
export -f svg_word

svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number


refresh_btn_grid(){
	for i in {1..7};do
		for j in {1..7};do
			echo '
			<action>refresh:btn_grid_'$i$j'</action>'
		done
	done	
}



# make arrow
echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/next.svg

echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/previous.svg



mkdir -p number
#amonth 4
amonth







echo '
<window title="kalendermuks">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>refresh:btn_grid_11</action>
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>
<action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>

</window>' > guikalender

gtkdialog -f guikalender
Attachments
Screenshot3.png
Screenshot3.png (18.24 KiB) Viewed 2620 times
User avatar
puppy_apprentice
Posts: 691
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: Gtkdialog Calendar

Post by puppy_apprentice »

recobayu wrote: Tue Feb 22, 2022 2:57 pm

what version of your puppylinux?

slacko64 6.3.2

recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

puppy_apprentice wrote: Tue Feb 22, 2022 8:47 pm
recobayu wrote: Tue Feb 22, 2022 2:57 pm

what version of your puppylinux?

slacko64 6.3.2

Hi @puppy_apprentice, I try this code in slacko64 6.3.2. and I also got the same error. So, the solution is, replace the line

Code: Select all

cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'

with this:

Code: Select all

cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'

Just remove the `tr'. And it will run. You can try the code from my last post.

User avatar
puppy_apprentice
Posts: 691
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: Gtkdialog Calendar

Post by puppy_apprentice »

Now works. You are on the good way to replace OSMO ;)

You can use variables instead of extra files, eg:

Code: Select all

line 30:
year_month=$(echo "$Y-$m-1")
line 56:
current_month=$year_month

Code: Select all

line 47:
if [ "$number_grid" == "$today" ];then btn_today=$(echo "btn_grid_$row$column") ;fi

Code: Select all

from line 120:
export cal_frontend='
<window title="kalendermuks">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>refresh:btn_grid_11</action>
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>
<action signal="focus-in-event">grabfocus:'$btn_today'</action>

</window>'

gtkdialog --program=cal_frontend

Edit: Tested more carefully and my changes don't work as expected.

Last edited by puppy_apprentice on Wed Feb 23, 2022 9:29 am, edited 1 time in total.
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Thank you @puppy_apprentice ..
Now, We can change the year directly by pressing the "Month Year" button.
I use notebook to "refresh" the gui. Here is the code:

Code: Select all

#!/bin/bash

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>echo</action>
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 number/grid2_$i$j.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid2_'$i$j'.svg</input>
				<action>echo '$m' > month</action>
				<action>year_to_month</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

amonth(){
	m="$1"
	Y="$2"
	
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
	echo "$Y-$m-1" > year_month
	echo "$Y" > year
	svg_word "$BY" 20 number/monthyear.svg
	svg_word "$Y" 20 number/year.svg

	#echo "$m $Y"	#debug
	
	row=1
	#cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			svg_number "$number_grid" 16 "number/grid_$row$column.svg"
		fi
		
		today=`date "+%_d"`
		if [ "$number_grid" == "$today" ];then echo "btn_grid_$row$column" > btn_today;fi
		
		done
		((row++))
	done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
	BY=`date -d "$new_month" "+%B %Y"`
	m=`date -d "$new_month" "+%m"`
	Y=`date -d "$new_month" "+%Y"`
	
	amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > year
	svg_word "$new_year" 20 number/year.svg
}
export -f change_year

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3"
}
export -f svg_word

svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number


refresh_btn_grid(){
	for i in {1..7};do
		for j in {1..7};do
			echo '				<action>refresh:btn_grid_'$i$j'</action>'
		done
	done	
}

month_to_year(){
	y=`cut -d "-" -f1 year_month`
	svg_word "$y" 20 number/year.svg
	echo "$y" > year
	echo 1 > tabpos
}
export -f month_to_year

year_to_month(){
	m=`cat month`
	y=`cat year`
	#BY=`date -d "$y-$m-1" "+%B %Y"`
	#svg_word "$BY" 20 number/monthyear.svg
	amonth "$m" "$y"
	echo 0 > tabpos
}
export -f year_to_month


# make arrow
echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/next.svg

echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/previous.svg



mkdir -p number
#amonth 4
amonth







echo '
<window title="kalendermuks">
<notebook show-tabs="false" shadow-type="0">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>month_to_year</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button2</action>
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/year.svg</input>
			<action>refresh:btn_grid_11</action>
			<variable>long_button2</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_year -1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_year +1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
	</hbox>
	'"`btn2`"'
</vbox>
<input file>tabpos</input>
<variable>nb_kalender</variable>
</notebook>
<action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>

</window>' > guikalender

gtkdialog -f guikalender
Attachments
now, it is easily jumping in to several year after/ago
now, it is easily jumping in to several year after/ago
debdog-20220223161548.jpg (16.53 KiB) Viewed 2559 times
month in year
month in year
debdog-20220223161512.jpg (9.87 KiB) Viewed 2559 times
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Changelog:
Now, the selected month and "today" are colored.

Code: Select all

#!/bin/bash

color="#398EE7"
echo "$color" > selected_color

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>echo</action>
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 number/grid2_$m.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid2_'$m'.svg</input>
				<action>echo '$m' > month</action>
				<action>year_to_month</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

amonth(){
	m="$1"
	Y="$2"
	
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
	echo "$Y-$m-1" > year_month
	echo "$m"|sed 's/^0*//' > month
	echo "$Y" > year
	
	svg_word "$BY" 20 number/monthyear.svg
	svg_word "$Y" 20 number/year.svg

	#echo "$m $Y"	#debug
	
	row=1
	#cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			if [ "$number_without_space" != "" ];then
			date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
			fi
			today=`date "+%Y%m%d"`
			if [ "$date_grid" == "$today" ];then 
				echo "btn_grid_$row$column" > btn_today
				svg_number_selected "$number_grid" 16 "number/grid_$row$column.svg"
			else
				svg_number "$number_grid" 16 "number/grid_$row$column.svg"
			fi
		fi
		
		
		done
		((row++))
	done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
	BY=`date -d "$new_month" "+%B %Y"`
	m=`date -d "$new_month" "+%m"`
	Y=`date -d "$new_month" "+%Y"`
	
	amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > year
	svg_word "$new_year" 20 number/year.svg
}
export -f change_year

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3"
}
export -f svg_word

svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number

svg_number_selected(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="5" y="25" style="fill:'$color'; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number_selected


refresh_btn_grid(){
	for i in {1..7};do
		for j in {1..7};do
			echo '				<action>refresh:btn_grid_'$i$j'</action>'
		done
	done	
}

refresh_btn2(){
	for i in {1..12};do
		echo '				<action>refresh:btn2_'$i'</action>'
	done	
}

month_to_year(){
	y=`cut -d "-" -f1 year_month`
	svg_word "$y" 20 number/year.svg
	
	m=`cat month`
	for i in {1..12};do
		b=`date -d "2022-$i-1" "+%b"`
		
		if [ "$i" == "$m" ];then
			svg_number_selected "$b" 14 number/grid2_$i.svg
		else
			svg_number "$b" 14 number/grid2_$i.svg
		fi
	done
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f month_to_year

year_to_month(){
	m=`cat month`
	y=`cat year`
	#BY=`date -d "$y-$m-1" "+%B %Y"`
	#svg_word "$BY" 20 number/monthyear.svg
	amonth "$m" "$y"
	echo 0 > tabpos
}
export -f year_to_month


# make arrow
echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/next.svg

echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/previous.svg



mkdir -p number
#amonth 4
amonth







echo '
<window title="kalendermuks">
<notebook show-tabs="false" shadow-type="0">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>month_to_year</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button2</action>
			'"`refresh_btn2`"'
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/year.svg</input>
			<action>refresh:btn_grid_11</action>
			<variable>long_button2</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_year -1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_year +1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
	</hbox>
	'"`btn2`"'
</vbox>
<input file>tabpos</input>
<variable>nb_kalender</variable>
</notebook>
<action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>

</window>' > guikalender

gtkdialog -f guikalender
Attachments
debdog-20220223175356.jpg
debdog-20220223175356.jpg (9.56 KiB) Viewed 2814 times
debdog-20220223175340.jpg
debdog-20220223175340.jpg (15.88 KiB) Viewed 2814 times
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

I found the `date' command has limitation.

Code: Select all

# date --date='2038-1-20'
date: invalid date ‘2038-1-20’
# date --date='2038-1-19'
Tue Jan 19 12:00:00 AM WIB 2038
# 

The max date that still can be reach is on 19 Jan 2038.
But when I use minixcal, it can reach year 2309
Is there any replacement of date command in linux?

edit:
That is on voidpup32.
But when I try on linuxmint 20.3, the date command reach soo many year.

Code: Select all

muktyas@muktyas-Inspiron-N4050:~$ date -d "2147485547-12-31"
Rab 31 Des 2147485547 12:00:00  WIB
muktyas@muktyas-Inspiron-N4050:~$ date -d "2147485548-1-1"
date: invalid date ‘2147485548-1-1’
muktyas@muktyas-Inspiron-N4050:~$ 
jamesbond
Posts: 717
Joined: Tue Aug 11, 2020 3:02 pm
Location: The Pale Blue Dot
Has thanked: 124 times
Been thanked: 402 times

Re: Gtkdialog Calendar

Post by jamesbond »

recobayu wrote: Thu Feb 24, 2022 12:51 am

I found the `date' command has limitation.

Code: Select all

# date --date='2038-1-20'
date: invalid date ‘2038-1-20’
# date --date='2038-1-19'
Tue Jan 19 12:00:00 AM WIB 2038
# 

The max date that still can be reach is on 19 Jan 2038.

This is well-known. It is called as Year 2038 problem.
This is because "time" is 32-bit, and it will overflow on 20 Jan 2038.
Solution is to use 64-bit time. (64-bit time does not imply 64-bit operating system.)

But when I use minixcal, it can reach year 2309
Is there any replacement of date command in linux?

edit:
That is on voidpup32.

I'm quite surprised to hear this.
Modern distros should no longer have this problem by now.
See the Wikipedia article. People have been working on this for a very long time by now.

But when I try on linuxmint 20.3, the date command reach soo many year.

Is this 64-bit or 32-bit?
64-bit systems should not have any problems at all.
Old 32-bit systems may have problems, but recent ones shouldn't.

recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Thank you @jamesbond for 2038 problem information.
voidpup32 is still using that `date' command. But the problem does not appear in linux mint 20.3 because it is 64 bit OS.

changelog:
Now, we can change the year by two decades on the calendar.
Also, the selected date is colored orange, echo-ed on terminal, and written on click_date.

Still problem does not fix yet:
day or empty button (not number) still can has orange dot, and give the error message on terminal.

Here is the code:

Code: Select all

#!/bin/bash

color="#398EE7"
echo "$color" > selected_color

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>svg_number_click number/grid_'$i$j'.svg</action>
				<action>refresh:btn_grid_'$i$j'</action>
				'"`refresh_btn_grid`"'
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 number/grid2_$m.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid2_'$m'.svg</input>
				<action>echo '$m' > month</action>
				<action>year_to_month</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

btn3(){
	touch top_left_year
	tly=`cat top_left_year`
	if [ "$tly" == "" ];then
		Y=`date "+%Y"`
		tly=$((Y-(Y%20)+1))		#top_left_year on grid
	fi
	
	Y="$tly"
	
	for i in {1..5};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			
			svg_number "$Y" 12 number/grid3_$i$j.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid3_'$i$j'.svg</input>
				<action>two_decades_to_year grid3_'$i$j'.svg</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button2</action>
				<variable>btn3_'$i$j'</variable>
			</button>'
			((Y++))
		done
		echo '
		</hbox>'
	done
}

amonth(){
	m="$1"
	Y="$2"
	
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
	echo "$Y-$m-1" > year_month
	echo "$m"|sed 's/^0*//' > month
	echo "$Y" > year
	
	svg_word "$BY" 20 number/monthyear.svg
	svg_word "$Y" 20 number/year.svg

	#echo "$m $Y"	#debug
	
	row=1
	cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	#cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			if [ "$number_without_space" != "" ];then
			date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
			fi
			today=`date "+%Y%m%d"`
			if [ "$date_grid" == "$today" ];then 
				echo "btn_grid_$row$column" > btn_today
				svg_number_selected "$number_grid" 16 "number/grid_$row$column.svg"
			else
				svg_number "$number_grid" 16 "number/grid_$row$column.svg"
			fi
		fi
		
		
		done
		((row++))
	done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
	BY=`date -d "$new_month" "+%B %Y"`
	m=`date -d "$new_month" "+%m"`
	Y=`date -d "$new_month" "+%Y"`
	
	amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > year
	svg_word "$new_year" 20 number/year.svg
}
export -f change_year

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3"
}
export -f svg_word

svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number

svg_number_selected(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="5" y="25" style="fill:'$color'; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number_selected

svg_number_click(){
	for i in {1..7};do
		for j in {1..7};do
			sed -i '/circle/d' number/grid_$i$j.svg
		done
	done	
	sed -i '2 a <circle cx="15" cy="2" r="2" style="fill:#FFA500" />' "$1"
	d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1`
	m=`cat month`
	y=`cat year`
	click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"`
	echo "$click_date"
	echo "$click_date" > click_date
}
export -f svg_number_click


refresh_btn_grid(){
	for i in {1..7};do
		for j in {1..7};do
			echo '				<action>refresh:btn_grid_'$i$j'</action>'
		done
	done	
}

refresh_btn2(){
	for i in {1..12};do
		echo '				<action>refresh:btn2_'$i'</action>'
	done	
}

refresh_btn3(){
	for i in {1..5};do
		for j in {1..4};do
			echo '				<action>refresh:btn3_'$i$j'</action>'
		done
	done	
}

change_two_decades(){
	change="$1"
	Y=`cat year`
	
	if [ "$1" == "+1" ];then
		Y=$((Y+20))
	elif [ "$1" == "-1" ];then
		Y=$((Y-20))
	fi
	echo "$Y" > year
	
	tly=$((Y-(Y%20)+1))	
	Y="$tly"
	for i in {1..5};do
		for j in {1..4};do
			svg_number "$Y" 12 number/grid3_$i$j.svg
			((Y++))
		done
	done
	Y=$((Y-1))
	svg_word "$tly - $Y" 20 number/two_decades.svg	
}
export -f change_two_decades

month_to_year(){
	y=`cut -d "-" -f1 year_month`
	svg_word "$y" 20 number/year.svg
	
	m=`cat month`
	for i in {1..12};do
		b=`date -d "2022-$i-1" "+%b"`
		
		if [ "$i" == "$m" ];then
			svg_number_selected "$b" 14 number/grid2_$i.svg
		else
			svg_number "$b" 14 number/grid2_$i.svg
		fi
	done
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f month_to_year

year_to_month(){
	m=`cat month`
	y=`cat year`
	#BY=`date -d "$y-$m-1" "+%B %Y"`
	#svg_word "$BY" 20 number/monthyear.svg
	amonth "$m" "$y"
	echo 0 > tabpos
}
export -f year_to_month

year_to_two_decades(){
	Y=`cat year`
	tly=$((Y-(Y%20)+1))	
	Y="$tly"
	for i in {1..5};do
		for j in {1..4};do
			svg_number "$Y" 12 number/grid3_$i$j.svg
			((Y++))
		done
	done
	svg_word "$tly - $((Y-1))" 20 number/two_decades.svg
	
	
	echo 2 > tabpos
}
export -f year_to_two_decades

two_decades_to_year(){
	y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
	
	svg_word "$y" 20 number/year.svg
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f two_decades_to_year


# make arrow
echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/next.svg

echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/previous.svg



mkdir -p number
#amonth 4
amonth







echo '
<window title="kalendermuks">
<notebook show-tabs="false" shadow-type="0">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>month_to_year</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button2</action>
			'"`refresh_btn2`"'
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			<action>refresh:long_button</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/year.svg</input>
			<action>year_to_two_decades</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button3</action>
			'"`refresh_btn3`"'
			<variable>long_button2</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_year -1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_year +1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
	</hbox>
	'"`btn2`"'
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/two_decades.svg</input>
			<action>refresh:btn_grid_11</action>
			<variable>long_button3</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_two_decades -1</action>
			<action>year_to_two_decades</action>
			<action>refresh:long_button3</action>
			'"`refresh_btn3`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_two_decades +1</action>
			<action>refresh:long_button3</action>
			'"`refresh_btn3`"'
		</button>
		
	</hbox>
	'"`btn3`"'
</vbox>
<input file>tabpos</input>
<variable>nb_kalender</variable>
</notebook>
<action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>

</window>' > guikalender

gtkdialog -f guikalender
Attachments
orange dot on click date
orange dot on click date
fossadog-20220226015903.jpg (47.05 KiB) Viewed 2728 times
two decades
two decades
fossadog-20220226015938.jpg (14 KiB) Viewed 2728 times
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Changelog:
1. Add today button on the top
2. Long Button on two decade, sensitive="false"
3. echo "click_date" when we click number and echo "Not a date" for else on terminal output
4. Exit by press Esc key

Code: Select all

#!/bin/bash

color="#398EE7"
echo "$color" > selected_color
mkdir -p number

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>svg_number_click number/grid_'$i$j'.svg</action>
				<action>refresh:btn_grid_'$i$j'</action>
				'"`refresh_btn_grid`"'
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 number/grid2_$m.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid2_'$m'.svg</input>
				<action>echo '$m' > month</action>
				<action>year_to_month</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

btn3(){
	touch top_left_year
	tly=`cat top_left_year`
	if [ "$tly" == "" ];then
		Y=`date "+%Y"`
		tly=$((Y-(Y%20)+1))		#top_left_year on grid
	fi
	
	Y="$tly"
	
	for i in {1..5};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			
			svg_number "$Y" 12 number/grid3_$i$j.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid3_'$i$j'.svg</input>
				<action>two_decades_to_year grid3_'$i$j'.svg</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button2</action>
				<variable>btn3_'$i$j'</variable>
			</button>'
			((Y++))
		done
		echo '
		</hbox>'
	done
}

amonth(){
	m="$1"
	Y="$2"
	
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
	echo "$Y-$m-1" > year_month
	echo "$m"|sed 's/^0*//' > month
	echo "$Y" > year
	
	svg_word "$BY" 20 number/monthyear.svg
	svg_word "$Y" 20 number/year.svg

	#echo "$m $Y"	#debug
	
	row=1
	cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	#cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			if [ "$number_without_space" != "" ];then
			date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
			fi
			today=`date "+%Y%m%d"`
			if [ "$date_grid" == "$today" ];then 
				echo "btn_grid_$row$column" > btn_today
				svg_number_selected "$number_grid" 16 "number/grid_$row$column.svg"
			else
				svg_number "$number_grid" 16 "number/grid_$row$column.svg"
			fi
		fi
		
		
		done
		((row++))
	done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
	BY=`date -d "$new_month" "+%B %Y"`
	m=`date -d "$new_month" "+%m"`
	Y=`date -d "$new_month" "+%Y"`
	
	amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > year
	svg_word "$new_year" 20 number/year.svg
}
export -f change_year

svg_now(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	#clock=`date "+%R"`
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="300" height="20">
  <rect width="300" height="20" style="fill:none; stroke-width:0" />
  <text x="2" y="90%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="left">'$1'</text>
</svg>' > "$3"
}
export -f svg_now

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3"
}
export -f svg_word

svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number

svg_number_selected(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="5" y="25" style="fill:'$color'; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number_selected

svg_number_click(){
	for i in {1..7};do
		for j in {1..7};do
			sed -i '/circle/d' number/grid_$i$j.svg
		done
	done	
	sed -i '2 a <circle cx="15" cy="2" r="2" style="fill:#FFA500" />' "$1"
	d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
	m=`cat month`
	y=`cat year`
	if [[ $d =~ [0-9] ]];then
	click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"`
	else
		click_date="Not a date"
	fi
	echo "$click_date"
	echo "$click_date" > click_date
}
export -f svg_number_click


refresh_btn_grid(){
	echo '				<action>refresh:long_button</action>'
	for i in {1..7};do
		for j in {1..7};do
			echo '				<action>refresh:btn_grid_'$i$j'</action>'
		done
	done	
}

refresh_btn2(){
	echo '				<action>refresh:long_button2</action>'
	for i in {1..12};do
		echo '				<action>refresh:btn2_'$i'</action>'
	done	
}

refresh_btn3(){
	echo '				<action>refresh:long_button3</action>'
	for i in {1..5};do
		for j in {1..4};do
			echo '				<action>refresh:btn3_'$i$j'</action>'
		done
	done	
}

change_two_decades(){
	change="$1"
	Y=`cat year`
	
	if [ "$1" == "+1" ];then
		Y=$((Y+20))
	elif [ "$1" == "-1" ];then
		Y=$((Y-20))
	fi
	echo "$Y" > year
	
	tly=$((Y-(Y%20)+1))	
	Y="$tly"
	for i in {1..5};do
		for j in {1..4};do
			svg_number "$Y" 12 number/grid3_$i$j.svg
			((Y++))
		done
	done
	Y=$((Y-1))
	svg_word "$tly - $Y" 20 number/two_decades.svg	
}
export -f change_two_decades

month_to_year(){
	y=`cut -d "-" -f1 year_month`
	svg_word "$y" 20 number/year.svg
	
	m=`cat month`
	for i in {1..12};do
		b=`date -d "2022-$i-1" "+%b"`
		
		if [ "$i" == "$m" ];then
			svg_number_selected "$b" 14 number/grid2_$i.svg
		else
			svg_number "$b" 14 number/grid2_$i.svg
		fi
	done
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f month_to_year

year_to_month(){
	m=`cat month`
	y=`cat year`
	#BY=`date -d "$y-$m-1" "+%B %Y"`
	#svg_word "$BY" 20 number/monthyear.svg
	amonth "$m" "$y"
	echo 0 > tabpos
}
export -f year_to_month

year_to_two_decades(){
	Y=`cat year`
	tly=$((Y-(Y%20)+1))	
	Y="$tly"
	for i in {1..5};do
		for j in {1..4};do
			svg_number "$Y" 12 number/grid3_$i$j.svg
			((Y++))
		done
	done
	svg_word "$tly - $((Y-1))" 20 number/two_decades.svg
	
	
	echo 2 > tabpos
}
export -f year_to_two_decades

two_decades_to_year(){
	y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
	
	svg_word "$y" 20 number/year.svg
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f two_decades_to_year


now(){
	today=`date "+%A, %d %B %Y"`
	svg_now "$today" 11 number/today.svg
	amonth
	echo 0 > tabpos
	
	echo "$today"
	echo "$today" > click_date
}
export -f now


# make arrow
echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/next.svg

echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/previous.svg



#amonth 4
#amonth
now






echo '
<window title="kalendermuks">
<vbox spacing="0">

<button xalign="0" relief="2" padding="0">
	<input file>number/today.svg</input>
	<action>now</action>
	<action>refresh:nb_kalender</action>
	<action>grabfocus:'"`cat btn_today`"'</action>
	'"`refresh_btn_grid`"'
</button>


<notebook show-tabs="false" shadow-type="0">
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>month_to_year</action>
			<action>refresh:nb_kalender</action>
			'"`refresh_btn2`"'
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/year.svg</input>
			<action>year_to_two_decades</action>
			<action>refresh:nb_kalender</action>
			'"`refresh_btn3`"'
			<variable>long_button2</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_year -1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_year +1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
	</hbox>
	'"`btn2`"'
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0" sensitive="false">
			<input file>number/two_decades.svg</input>
			<variable>long_button3</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_two_decades -1</action>
			<action>year_to_two_decades</action>
			'"`refresh_btn3`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_two_decades +1</action>
			'"`refresh_btn3`"'
		</button>
		
	</hbox>
	'"`btn3`"'
</vbox>
<input file>tabpos</input>
<variable>nb_kalender</variable>
</notebook>

</vbox>

<action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>
<action signal="key-press-event" condition="command_is_true([ $KEY_SYM = Escape ] && echo true )">exit:Esc</action>
</window>' > guikalender

gtkdialog -f guikalender
Attachments
fossadog-20220226235650.jpg
fossadog-20220226235650.jpg (30.58 KiB) Viewed 2692 times
recobayu
Posts: 64
Joined: Tue Jul 14, 2020 9:34 am
Has thanked: 11 times
Been thanked: 8 times

Re: Gtkdialog Calendar

Post by recobayu »

Bug:
Repeated date if the last number is on the first column.

Changelog:
Add hseparator and show-border="false" on notebook

Code: Select all

#!/bin/bash

color="#398EE7"
echo "$color" > selected_color
mkdir -p number

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>svg_number_click number/grid_'$i$j'.svg</action>
				<action>refresh:btn_grid_'$i$j'</action>
				'"`refresh_btn_grid`"'
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
	done
	echo '
	</hbox>'
done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 number/grid2_$m.svg
			
		echo '
		<button relief="2" width-request="80" height-request="70">
			<input file>number/grid2_'$m'.svg</input>
			<action>echo '$m' > month</action>
			<action>year_to_month</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

btn3(){
	touch top_left_year
	tly=`cat top_left_year`
	if [ "$tly" == "" ];then
		Y=`date "+%Y"`
		tly=$((Y-(Y%20)+1))		#top_left_year on grid
	fi
	
Y="$tly"

for i in {1..5};do
	echo '
	<hbox spacing="0">'
	for j in {1..4};do
		
		svg_number "$Y" 12 number/grid3_$i$j.svg
		
		echo '
		<button relief="2" width-request="80" height-request="70">
			<input file>number/grid3_'$i$j'.svg</input>
			<action>two_decades_to_year grid3_'$i$j'.svg</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button2</action>
			<variable>btn3_'$i$j'</variable>
		</button>'
		((Y++))
	done
	echo '
	</hbox>'
done
}

amonth(){
	m="$1"
	Y="$2"
	
#echo "$m $Y"	#debug
if [ "$m" == "" ];then m=`date +'%m'`;fi
if [ "$Y" == "" ];then Y=`date +'%Y'`;fi

BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
echo "$Y-$m-1" > year_month
echo "$m"|sed 's/^0*//' > month
echo "$Y" > year

svg_word "$BY" 20 number/monthyear.svg
svg_word "$Y" 20 number/year.svg

#echo "$m $Y"	#debug

row=1
cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
#cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	for column in {1..7};do
	number_grid=`echo "$line"|cut -d "," -f $column`
	number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
	
	if [ "$row" == "1" ];then
		svg_number "$number_grid" 10 "number/grid_$row$column.svg"
	else
		if [ "$number_without_space" != "" ];then
		date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
		fi
		today=`date "+%Y%m%d"`
		if [ "$date_grid" == "$today" ];then 
			echo "btn_grid_$row$column" > btn_today
			svg_number_selected "$number_grid" 16 "number/grid_$row$column.svg"
		else
			svg_number "$number_grid" 16 "number/grid_$row$column.svg"
		fi
	fi
	
	
	done
	((row++))
done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
BY=`date -d "$new_month" "+%B %Y"`
m=`date -d "$new_month" "+%m"`
Y=`date -d "$new_month" "+%Y"`

amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > year
	svg_word "$new_year" 20 number/year.svg
}
export -f change_year

svg_now(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	#clock=`date "+%R"`
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="300" height="20">
  <rect width="300" height="20" style="fill:none; stroke-width:0" />
  <text x="2" y="90%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="left">'$1'</text>
</svg>' > "$3"
}
export -f svg_now

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3" } export -f svg_word svg_number(){ echo '<?xml version="1.0" encoding="UTF-8"?> <svg width="30" height="30"> <rect width="30" height="30" style="fill:none; stroke-width:0" /> <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>
</svg>' > "$3" } export -f svg_number svg_number_selected(){ color=`cat selected_color` if [ "$color" == "" ];then color="#0077D6";fi echo '<?xml version="1.0" encoding="UTF-8"?> <svg width="30" height="30"> <rect width="30" height="5" y="25" style="fill:'$color'; stroke-width:0" /> <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>
</svg>' > "$3" } export -f svg_number_selected svg_number_click(){ for i in {1..7};do for j in {1..7};do sed -i '/circle/d' number/grid_$i$j.svg done done sed -i '2 a <circle cx="15" cy="2" r="2" style="fill:#FFA500" />' "$1" d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'` m=`cat month` y=`cat year` if [[ $d =~ [0-9] ]];then click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"` else click_date="Not a date" fi echo "$click_date" echo "$click_date" > click_date } export -f svg_number_click refresh_btn_grid(){ echo ' <action>refresh:long_button</action>' for i in {1..7};do for j in {1..7};do echo ' <action>refresh:btn_grid_'$i$j'</action>' done done } refresh_btn2(){ echo ' <action>refresh:long_button2</action>' for i in {1..12};do echo ' <action>refresh:btn2_'$i'</action>' done } refresh_btn3(){ echo ' <action>refresh:long_button3</action>' for i in {1..5};do for j in {1..4};do echo ' <action>refresh:btn3_'$i$j'</action>' done done } change_two_decades(){ change="$1" Y=`cat year` if [ "$1" == "+1" ];then Y=$((Y+20)) elif [ "$1" == "-1" ];then Y=$((Y-20)) fi echo "$Y" > year tly=$((Y-(Y%20)+1)) Y="$tly" for i in {1..5};do for j in {1..4};do svg_number "$Y" 12 number/grid3_$i$j.svg ((Y++)) done done Y=$((Y-1)) svg_word "$tly - $Y" 20 number/two_decades.svg } export -f change_two_decades month_to_year(){ y=`cut -d "-" -f1 year_month` svg_word "$y" 20 number/year.svg m=`cat month` for i in {1..12};do b=`date -d "2022-$i-1" "+%b"` if [ "$i" == "$m" ];then svg_number_selected "$b" 14 number/grid2_$i.svg else svg_number "$b" 14 number/grid2_$i.svg fi done echo "$y" > year echo 1 > tabpos } export -f month_to_year year_to_month(){ m=`cat month` y=`cat year` #BY=`date -d "$y-$m-1" "+%B %Y"` #svg_word "$BY" 20 number/monthyear.svg amonth "$m" "$y" echo 0 > tabpos } export -f year_to_month year_to_two_decades(){ Y=`cat year` tly=$((Y-(Y%20)+1)) Y="$tly" for i in {1..5};do for j in {1..4};do svg_number "$Y" 12 number/grid3_$i$j.svg ((Y++)) done done svg_word "$tly - $((Y-1))" 20 number/two_decades.svg echo 2 > tabpos } export -f year_to_two_decades two_decades_to_year(){ y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1` svg_word "$y" 20 number/year.svg echo "$y" > year echo 1 > tabpos } export -f two_decades_to_year now(){ today=`date "+%A, %d %B %Y"` svg_now "$today" 11 number/today.svg amonth echo 0 > tabpos echo "$today" echo "$today" > click_date } export -f now # make arrow echo '<?xml version="1.0" encoding="UTF-8"?> <svg height="30" width="30"> <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/> </svg>' > number/next.svg echo '<?xml version="1.0" encoding="UTF-8"?> <svg height="30" width="30"> <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/> </svg>' > number/previous.svg #amonth 4 #amonth now echo ' <window title="kalendermuks"> <vbox spacing="0"> <button xalign="0" relief="2" padding="0"> <input file>number/today.svg</input> <action>now</action> <action>refresh:nb_kalender</action> <action>grabfocus:'"`cat btn_today`"'</action> '"`refresh_btn_grid`"' </button> <hseparator></hseparator> <notebook show-tabs="false" show-border="false" > <vbox spacing="0"> <hbox spacing="0"> <button relief="2" width-request="230" height-request="40" xalign="0"> <input file>number/monthyear.svg</input> <action>month_to_year</action> <action>refresh:nb_kalender</action> '"`refresh_btn2`"' <variable>long_button</variable> </button> <button relief="2" width-request="46" height-request="40"> <input file>number/previous.svg</input> <action>change_month -1</action> '"`refresh_btn_grid`"' </button> <button relief="2" width-request="46" height-request="40"> <input file>number/next.svg</input> <action>change_month 1</action> '"`refresh_btn_grid`"' </button> </hbox> '"`btn`"' </vbox> <vbox> <hbox spacing="0"> <button relief="2" width-request="230" height-request="40" xalign="0"> <input file>number/year.svg</input> <action>year_to_two_decades</action> <action>refresh:nb_kalender</action> '"`refresh_btn3`"' <variable>long_button2</variable> </button> <button relief="2" width-request="46" height-request="40"> <input file>number/previous.svg</input> <action>change_year -1</action> <action>refresh:long_button2</action> </button> <button relief="2" width-request="46" height-request="40"> <input file>number/next.svg</input> <action>change_year +1</action> <action>refresh:long_button2</action> </button> </hbox> '"`btn2`"' </vbox> <vbox> <hbox spacing="0"> <button relief="2" width-request="230" height-request="40" xalign="0" sensitive="false"> <input file>number/two_decades.svg</input> <variable>long_button3</variable> </button> <button relief="2" width-request="46" height-request="40"> <input file>number/previous.svg</input> <action>change_two_decades -1</action> <action>year_to_two_decades</action> '"`refresh_btn3`"' </button> <button relief="2" width-request="46" height-request="40"> <input file>number/next.svg</input> <action>change_two_decades +1</action> '"`refresh_btn3`"' </button> </hbox> '"`btn3`"' </vbox> <input file>tabpos</input> <variable>nb_kalender</variable> </notebook> </vbox> <action signal="focus-in-event">grabfocus:'`cat btn_today`'</action> <action signal="key-press-event" condition="command_is_true([ $KEY_SYM = Escape ] && echo true )">exit:Esc</action> </window>' > guikalender gtkdialog -f guikalender

Another code that working directory in /tmp/gtkdialog-calendar:

Code: Select all

#!/bin/bash

cal_dir=/tmp/gtkdialog-calendar
export cal_dir
mkdir -p $cal_dir

color="#398EE7"
export color
echo "$color" > $cal_dir/selected_color
mkdir -p $cal_dir/number

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>'$cal_dir'/number/grid_'$i$j'.svg</input>
				<action>svg_number_click '$cal_dir'/number/grid_'$i$j'.svg</action>
				<action>refresh:btn_grid_'$i$j'</action>
				'"`refresh_btn_grid`"'
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
	done
	echo '
	</hbox>'
done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 $cal_dir/number/grid2_$m.svg
			
		echo '
		<button relief="2" width-request="80" height-request="70">
			<input file>'$cal_dir'/number/grid2_'$m'.svg</input>
			<action>echo '$m' > '$cal_dir'/month</action>
			<action>year_to_month</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

btn3(){
	touch $cal_dir/top_left_year
	tly=`cat $cal_dir/top_left_year`
	if [ "$tly" == "" ];then
		Y=`date "+%Y"`
		tly=$((Y-(Y%20)+1))		#top_left_year on grid
	fi
	
Y="$tly"

for i in {1..5};do
	echo '
	<hbox spacing="0">'
	for j in {1..4};do
		
		svg_number "$Y" 12 $cal_dir/number/grid3_$i$j.svg
		
		echo '
		<button relief="2" width-request="80" height-request="70">
			<input file>'$cal_dir'/number/grid3_'$i$j'.svg</input>
			<action>two_decades_to_year grid3_'$i$j'.svg</action>
			<action>refresh:nb_kalender</action>
			<action>refresh:long_button2</action>
			<variable>btn3_'$i$j'</variable>
		</button>'
		((Y++))
	done
	echo '
	</hbox>'
done
}

amonth(){
	m="$1"
	Y="$2"
	
#echo "$m $Y"	#debug
if [ "$m" == "" ];then m=`date +'%m'`;fi
if [ "$Y" == "" ];then Y=`date +'%Y'`;fi

BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
echo "$Y-$m-1" > $cal_dir/year_month
echo "$m"|sed 's/^0*//' > $cal_dir/month
echo "$Y" > $cal_dir/year

svg_word "$BY" 20 $cal_dir/number/monthyear.svg
svg_word "$Y" 20 $cal_dir/number/year.svg

#echo "$m $Y"	#debug

row=1
cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
#cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	for column in {1..7};do
	number_grid=`echo "$line"|cut -d "," -f $column`
	number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
	
	if [ "$row" == "1" ];then
		svg_number "$number_grid" 10 "$cal_dir/number/grid_$row$column.svg"
	else
		if [ "$number_without_space" != "" ];then
		date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
		fi
		today=`date "+%Y%m%d"`
		if [ "$date_grid" == "$today" ];then 
			echo "btn_grid_$row$column" > $cal_dir/btn_today
			svg_number_selected "$number_grid" 16 "$cal_dir/number/grid_$row$column.svg"
		else
			svg_number "$number_grid" 16 "$cal_dir/number/grid_$row$column.svg"
		fi
	fi
	
	
	done
	((row++))
done
}
export -f amonth

change_month(){
	current_month=`cat $cal_dir/year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
BY=`date -d "$new_month" "+%B %Y"`
m=`date -d "$new_month" "+%m"`
Y=`date -d "$new_month" "+%Y"`

amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat $cal_dir/year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > $cal_dir/year
	svg_word "$new_year" 20 $cal_dir/number/year.svg
}
export -f change_year

svg_now(){
	color=`cat $cal_dir/selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	#clock=`date "+%R"`
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="300" height="20">
  <rect width="300" height="20" style="fill:none; stroke-width:0" />
  <text x="2" y="90%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="left">'$1'</text>
</svg>' > "$3"
}
export -f svg_now

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3" } export -f svg_word svg_number(){ echo '<?xml version="1.0" encoding="UTF-8"?> <svg width="30" height="30"> <rect width="30" height="30" style="fill:none; stroke-width:0" /> <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>
</svg>' > "$3" } export -f svg_number svg_number_selected(){ color=`cat $cal_dir/selected_color` if [ "$color" == "" ];then color="#0077D6";fi echo '<?xml version="1.0" encoding="UTF-8"?> <svg width="30" height="30"> <rect width="30" height="5" y="25" style="fill:'$color'; stroke-width:0" /> <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>
</svg>' > "$3" } export -f svg_number_selected svg_number_click(){ for i in {1..7};do for j in {1..7};do sed -i '/circle/d' $cal_dir/number/grid_$i$j.svg done done sed -i '2 a <circle cx="15" cy="2" r="2" style="fill:'$color'" />' "$1" d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'` m=`cat $cal_dir/month` y=`cat $cal_dir/year` if [[ $d =~ [0-9] ]];then click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"` else click_date="Not a date" fi echo "$click_date" echo "$click_date" > $cal_dir/click_date } export -f svg_number_click refresh_btn_grid(){ echo ' <action>refresh:long_button</action>' for i in {1..7};do for j in {1..7};do echo ' <action>refresh:btn_grid_'$i$j'</action>' done done } refresh_btn2(){ echo ' <action>refresh:long_button2</action>' for i in {1..12};do echo ' <action>refresh:btn2_'$i'</action>' done } refresh_btn3(){ echo ' <action>refresh:long_button3</action>' for i in {1..5};do for j in {1..4};do echo ' <action>refresh:btn3_'$i$j'</action>' done done } change_two_decades(){ change="$1" Y=`cat $cal_dir/year` if [ "$1" == "+1" ];then Y=$((Y+20)) elif [ "$1" == "-1" ];then Y=$((Y-20)) fi echo "$Y" > $cal_dir/year tly=$((Y-(Y%20)+1)) Y="$tly" for i in {1..5};do for j in {1..4};do svg_number "$Y" 12 $cal_dir/number/grid3_$i$j.svg ((Y++)) done done Y=$((Y-1)) svg_word "$tly - $Y" 20 $cal_dir/number/two_decades.svg } export -f change_two_decades month_to_year(){ y=`cut -d "-" -f1 $cal_dir/year_month` svg_word "$y" 20 $cal_dir/number/year.svg m=`cat $cal_dir/month` for i in {1..12};do b=`date -d "2022-$i-1" "+%b"` if [ "$i" == "$m" ];then svg_number_selected "$b" 14 $cal_dir/number/grid2_$i.svg else svg_number "$b" 14 $cal_dir/number/grid2_$i.svg fi done echo "$y" > $cal_dir/year echo 1 > $cal_dir/tabpos } export -f month_to_year year_to_month(){ m=`cat $cal_dir/month` y=`cat $cal_dir/year` #BY=`date -d "$y-$m-1" "+%B %Y"` #svg_word "$BY" 20 number/monthyear.svg amonth "$m" "$y" echo 0 > $cal_dir/tabpos } export -f year_to_month year_to_two_decades(){ Y=`cat $cal_dir/year` tly=$((Y-(Y%20)+1)) Y="$tly" for i in {1..5};do for j in {1..4};do svg_number "$Y" 12 $cal_dir/number/grid3_$i$j.svg ((Y++)) done done svg_word "$tly - $((Y-1))" 20 $cal_dir/number/two_decades.svg echo 2 > $cal_dir/tabpos } export -f year_to_two_decades two_decades_to_year(){ y=`grep -o ">.*</text>" $cal_dir/number/"$1" |sed 's/>//g'|cut -d\< -f1` svg_word "$y" 20 $cal_dir/number/year.svg echo "$y" > $cal_dir/year echo 1 > $cal_dir/tabpos } export -f two_decades_to_year now(){ today=`date "+%A, %d %B %Y"` svg_now "$today" 11 $cal_dir/number/today.svg amonth echo 0 > $cal_dir/tabpos echo "$today" echo "$today" > $cal_dir/click_date } export -f now # make arrow echo '<?xml version="1.0" encoding="UTF-8"?> <svg height="30" width="30"> <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/> </svg>' > $cal_dir/number/next.svg echo '<?xml version="1.0" encoding="UTF-8"?> <svg height="30" width="30"> <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/> </svg>' > $cal_dir/number/previous.svg #amonth 4 #amonth now echo ' <window title="kalendermuks"> <vbox spacing="0"> <button xalign="0" relief="2" padding="0"> <input file>'$cal_dir'/number/today.svg</input> <action>now</action> <action>refresh:nb_kalender</action> <action>grabfocus:'"`cat $cal_dir/btn_today`"'</action> '"`refresh_btn_grid`"' </button> <hseparator></hseparator> <notebook show-tabs="false" show-border="false" > <vbox spacing="0"> <hbox spacing="0"> <button relief="2" width-request="230" height-request="40" xalign="0"> <input file>'$cal_dir/'number/monthyear.svg</input> <action>month_to_year</action> <action>refresh:nb_kalender</action> '"`refresh_btn2`"' <variable>long_button</variable> </button> <button relief="2" width-request="46" height-request="40"> <input file>'$cal_dir/'number/previous.svg</input> <action>change_month -1</action> '"`refresh_btn_grid`"' </button> <button relief="2" width-request="46" height-request="40"> <input file>'$cal_dir/'number/next.svg</input> <action>change_month 1</action> '"`refresh_btn_grid`"' </button> </hbox> '"`btn`"' </vbox> <vbox> <hbox spacing="0"> <button relief="2" width-request="230" height-request="40" xalign="0"> <input file>'$cal_dir/'number/year.svg</input> <action>year_to_two_decades</action> <action>refresh:nb_kalender</action> '"`refresh_btn3`"' <variable>long_button2</variable> </button> <button relief="2" width-request="46" height-request="40"> <input file>'$cal_dir/'number/previous.svg</input> <action>change_year -1</action> <action>refresh:long_button2</action> </button> <button relief="2" width-request="46" height-request="40"> <input file>'$cal_dir/'number/next.svg</input> <action>change_year +1</action> <action>refresh:long_button2</action> </button> </hbox> '"`btn2`"' </vbox> <vbox> <hbox spacing="0"> <button relief="2" width-request="230" height-request="40" xalign="0" sensitive="false"> <input file>'$cal_dir'/number/two_decades.svg</input> <variable>long_button3</variable> </button> <button relief="2" width-request="46" height-request="40"> <input file>'$cal_dir'/number/previous.svg</input> <action>change_two_decades -1</action> <action>year_to_two_decades</action> '"`refresh_btn3`"' </button> <button relief="2" width-request="46" height-request="40"> <input file>'$cal_dir'/number/next.svg</input> <action>change_two_decades +1</action> '"`refresh_btn3`"' </button> </hbox> '"`btn3`"' </vbox> <input file>'$cal_dir'/tabpos</input> <variable>nb_kalender</variable> </notebook> </vbox> <action signal="focus-in-event">grabfocus:'`cat $cal_dir/btn_today`'</action> <action signal="focus-out-event">exit:FocusOut</action> <action signal="key-press-event" condition="command_is_true([ $KEY_SYM = Escape ] && echo true )">exit:Esc</action> </window>' > $cal_dir/guikalender gtkdialog -f $cal_dir/guikalender -G 340x360+1030+380
Last edited by recobayu on Sun Jul 14, 2024 4:02 pm, edited 1 time in total.
User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: Gtkdialog Calendar

Post by misko_2083 »

recobayu wrote: Thu Feb 24, 2022 12:51 am

I found the `date' command has limitation.

Code: Select all

# date --date='2038-1-20'
date: invalid date ‘2038-1-20’
# date --date='2038-1-19'
Tue Jan 19 12:00:00 AM WIB 2038
# 

The max date that still can be reach is on 19 Jan 2038.
But when I use minixcal, it can reach year 2309
Is there any replacement of date command in linux?

There is awk, but not POSIX, that is if you even care about that.

man awk https://www.gnu.org/software/gawk/manua ... tions.html
^^^Scroll down to the bottom of the page where there is a script example of awk reproducing the date command behavior and formatting..

mktime Turn a datespec (YYYY MM DD HH MM SS) into a timestamp
strftime Format a specified time to the given format as defined by strftime()
systime Return the Unix Time stamp (Epoch)

Code: Select all

awk 'BEGIN { print "Seconds since Epoch: " mktime("2038 1 20 1 1 1") }'
Seconds since Epoch: 2147558461

awk 'BEGIN { print "Seconds since Epoch: " systime() }'
Seconds since Epoch: 1646043482

awk 'BEGIN { print strftime("Today is %A, %B %d, %Y.", systime()) }'
Today is Monday, February 28, 2022.

The Bash printf builtin command also support some date formats
by using %(datefmt)T where datefmt is a format string passed to
strftime and the corresponding argument is the Epoch time.

Code: Select all

TZ=UTC printf "%(%F)T\n" 2147558461
2038-01-20

TZ=UTC printf "This date occurred in week %(%W)T of the year %(%Y)T\n" $EPOCHSECONDS
This date occurred in week 09 of the year 2022

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
puppy_apprentice
Posts: 691
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: Gtkdialog Calendar

Post by puppy_apprentice »

An MM attempt on this topic.

don570
Posts: 688
Joined: Sat Nov 21, 2020 4:43 pm
Has thanked: 5 times
Been thanked: 117 times

Re: Gtkdialog Calendar

Post by don570 »

to recobayu

Very nice coding.
I might suggest a button to open a text file to act like a diary.
The date and a message could be entered and stored in the text file.


Zigbert who wrote pfind was one of the first coders that took advantage of SVG images


superhik
Posts: 42
Joined: Mon Jun 19, 2023 7:56 pm
Has thanked: 6 times
Been thanked: 19 times

Re: Gtkdialog Calendar

Post by superhik »

don570 wrote: Tue Jan 09, 2024 8:51 pm

to recobayu

Very nice coding.
I might suggest a button to open a text file to act like a diary.
The date and a message could be entered and stored in the text file.


Zigbert who wrote pfind was one of the first coders that took advantage of SVG images


I took the advantage of Cairo and made a custom calendar widget.
For now I'm only exploring the possibilities.
GtkDialog has limitations and bugs as well as GtkCallendar widget.
It save diary entries in separate files in user's data dir, which is in Debian $HOME/.local/share
that is $HOME/.local/share/diary_entries

Code: Select all

#include <gtk/gtk.h>
#include <glib.h>
#include <cairo.h>

typedef struct {
    GtkWidget *window;
    GtkWidget *drawing_area;
    GtkWidget *text_view;
    gchar *diary_dir;
    guint current_year;
    guint current_month;
    guint selected_day;
    GHashTable *marked_dates;
} AppWidgets;

static gboolean draw_calendar(GtkWidget *widget, cairo_t *cr, AppWidgets *app) {
    const gchar *day_names[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

guint days_in_month = g_date_get_days_in_month(app->current_month + 1, app->current_year);
GDate *date = g_date_new_dmy(1, app->current_month + 1, app->current_year);
GDateWeekday first_weekday = g_date_get_weekday(date);
g_date_free(date);

GDateTime *now = g_date_time_new_now_local();
guint today_day = g_date_time_get_day_of_month(now);
guint today_month = g_date_time_get_month(now);
guint today_year = g_date_time_get_year(now);
g_date_time_unref(now);

GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
gint cell_width = allocation.width / 7;
gint cell_height = allocation.height / 7;  // Adjusted for day names
cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
cairo_rectangle(cr, cell_width, cell_height, cell_width, cell_height);
cairo_paint(cr);

// Centering calculations
gint text_width, text_height;
cairo_text_extents_t extents;
cairo_set_font_size(cr, cell_height * 0.4); // Font size for day names
cairo_text_extents(cr, day_names[0], &extents);
text_width = extents.width;
text_height = extents.height;

// Calculate starting point for day names to center them
gint start_x = (cell_width - text_width) / 2;
gint start_y = cell_height * 0.6;

cairo_set_source_rgb(cr, 0, 0, 0);
// Draw day names
for (int i = 0; i < 7; i++) {
    cairo_move_to(cr, i * cell_width / 2, cell_height * 0.6 / 2);
    if (i == 6) {
        // Draw Sunday in red
        cairo_set_source_rgb(cr, 1, 0, 0);
    } else if (i == 5) {
       cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
    } else {
        cairo_set_source_rgb(cr, 0, 0, 0);
    }
    cairo_text_extents(cr, day_names[i], &extents);
    text_width = extents.width;
    cairo_move_to(cr, i * cell_width + start_x, start_y);
    cairo_show_text(cr, day_names[i]);
}

// Draw grid
cairo_set_line_width(cr, 1);
cairo_set_source_rgb(cr, 0, 0, 0);
for (int i = 0; i < 7; i++) {
    for (int j = 1; j < 7; j++) {
        cairo_rectangle(cr, i * cell_width, j * cell_height, cell_width, cell_height);
    }
}
cairo_stroke(cr);
cairo_set_font_size(cr, cell_height * 0.5); // Adjust font size proportionally
// Draw days
for (guint day = 1; day <= days_in_month; day++) {
    gint row = (day + first_weekday - 2) / 7 + 1;
    gint column = (day + first_weekday - 2) % 7;
    gchar *text = g_strdup_printf("%2u", day);

    // Calculate text extents for day number
    cairo_text_extents(cr, text, &extents);
    text_width = extents.width;
    text_height = extents.height;
    
    // Calculate starting point to center day number
    start_x = column * cell_width + (cell_width - text_width) / 2;
    start_y = row * cell_height + cell_height / 2 + text_height / 2;
    if (column == 6) {
        // Draw Sunday dates in red
        cairo_set_source_rgb(cr, 1, 0, 0);
    } else if (column == 5) {
       cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
    } else {
        cairo_set_source_rgb(cr, 0, 0, 0);
    }
    cairo_move_to(cr, start_x, start_y);
    cairo_show_text(cr, text);
    g_free(text);

    if (g_hash_table_contains(app->marked_dates, GINT_TO_POINTER(day))) {
        cairo_set_source_rgb(cr, 0, 0, 0); 
        // Calculate dynamic radius based on cell dimensions
        double radius = MIN(cell_width, cell_height) / 10.0;
        cairo_arc(cr, column * cell_width + cell_width - 1.5 * radius, row * cell_height + 1.5 * radius, radius, 0, 2 * G_PI);

        cairo_close_path(cr);
        cairo_fill(cr);
        cairo_set_source_rgb(cr, 0, 0, 0);
    }

    // Highlight the selected day
    if (day == app->selected_day) {
        cairo_set_source_rgba(cr, 1, 0.7, 1, 0.07);
        cairo_set_source_rgb(cr, 0, 0, 1);  // Blue color for selected day
        cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
        cairo_set_line_width(cr, 3);
        cairo_stroke(cr);
        cairo_set_source_rgba(cr, 0, 0.7, 1, 0.1);
        cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
        cairo_fill(cr);
        cairo_set_source_rgb(cr, 0, 0, 0);  // Set back to black for text
    }

    // Highlight today's date
    if (day == today_day && app->current_month + 1 == today_month && app->current_year == today_year) {
        cairo_set_source_rgba(cr, 0, 1, 0, 0.3);  // Green color with transparency
        cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
        cairo_fill(cr);
        cairo_set_source_rgb(cr, 0, 0, 0);  // Set back to black for text
    }

}

return FALSE;
}

static void mark_dates_with_entries(AppWidgets *app) {
    g_hash_table_remove_all(app->marked_dates);

GDir *dir = g_dir_open(app->diary_dir, 0, NULL);
if (!dir) return;

const gchar *filename;
while ((filename = g_dir_read_name(dir))) {
    guint entry_year, entry_month, entry_day;
    if (sscanf(filename, "%4u-%2u-%2u.txt", &entry_year, &entry_month, &entry_day) == 3) {
        if (entry_year == app->current_year && entry_month == app->current_month + 1) {
            g_hash_table_add(app->marked_dates, GINT_TO_POINTER(entry_day));
        }
    }
}
g_dir_close(dir);
gtk_widget_queue_draw(app->drawing_area);
}

static void on_day_selected(GtkWidget *widget, GdkEventButton *event, AppWidgets *app) {
    guint days_in_month = g_date_get_days_in_month(app->current_month + 1, app->current_year);
    GDate *date = g_date_new_dmy(1, app->current_month + 1, app->current_year);
    GDateWeekday first_weekday = g_date_get_weekday(date);
    g_date_free(date);

GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
gint cell_width = allocation.width / 7;
gint cell_height = allocation.height / 7;  // Adjusted for day names

gint column = event->x / cell_width;
gint row = (event->y / cell_height) - 1;  // Adjust for day names
gint day = row * 7 + column - first_weekday + 2;

if (day < 1 || day > days_in_month) return;

gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, day);
gchar *content = NULL;
g_file_get_contents(filename, &content, NULL, NULL);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
gtk_text_buffer_set_text(buffer, content ? content : "", -1);
g_free(content);
g_free(filename);

app->selected_day = day;
mark_dates_with_entries(app);
}

static void on_save_clicked(GtkButton *button, AppWidgets *app) {
    if (app->selected_day == 0) return; // No day selected

GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
GtkTextIter start, end;
gtk_text_buffer_get_bounds(buffer, &start, &end);
gchar *content = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);

gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, app->selected_day);
g_file_set_contents(filename, content, -1, NULL);
g_free(filename);
g_free(content);

mark_dates_with_entries(app);
}

static void on_month_changed(GtkComboBox *combo, AppWidgets *app) {
    app->current_month = gtk_combo_box_get_active(combo);
    mark_dates_with_entries(app);
}

static void on_year_changed(GtkSpinButton *spin, AppWidgets *app) {
    app->current_year = gtk_spin_button_get_value_as_int(spin);
    mark_dates_with_entries(app);
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

AppWidgets *app = g_slice_new(AppWidgets);

// Get the current date
GDateTime *now = g_date_time_new_now_local();
app->current_year = g_date_time_get_year(now);
app->current_month = g_date_time_get_month(now) - 1; // g_date_time_get_month() is 1-based
app->selected_day = g_date_time_get_day_of_month(now);
g_date_time_unref(now);

app->diary_dir = g_build_filename(g_get_user_data_dir(), "diary_entries", NULL);
g_mkdir_with_parents(app->diary_dir, 0755);
app->marked_dates = g_hash_table_new(g_direct_hash, g_direct_equal);

app->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(app->window), "Custom Calendar Widget");
gtk_window_set_default_size(GTK_WINDOW(app->window), 500, 600);
gtk_window_set_icon_name(GTK_WINDOW(app->window), "xfcalendar");

GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(app->window), vbox);

GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

GtkWidget *spin_year = gtk_spin_button_new_with_range(1900, 2100, 1);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_year), app->current_year);
gtk_box_pack_start(GTK_BOX(hbox), spin_year, FALSE, FALSE, 0);

GtkWidget *combo_month = gtk_combo_box_text_new();
const gchar *months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
for (int i = 0; i < 12; i++) {
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_month), months[i]);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_month), app->current_month);
gtk_box_pack_start(GTK_BOX(hbox), combo_month, FALSE, FALSE, 0);

app->drawing_area = gtk_drawing_area_new();
gtk_box_pack_start(GTK_BOX(vbox), app->drawing_area, TRUE, TRUE, 0);
gtk_widget_set_size_request(app->drawing_area, 500, 350);
g_signal_connect(app->drawing_area, "draw", G_CALLBACK(draw_calendar), app);
g_signal_connect(app->drawing_area, "button-press-event", G_CALLBACK(on_day_selected), app);
gtk_widget_add_events(app->drawing_area, GDK_BUTTON_PRESS_MASK);

app->text_view = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox), app->text_view, TRUE, TRUE, 0);

GtkWidget *save_button = gtk_button_new_with_label("Save");
gtk_box_pack_start(GTK_BOX(vbox), save_button, FALSE, FALSE, 0);
g_signal_connect(save_button, "clicked", G_CALLBACK(on_save_clicked), app);

g_signal_connect(spin_year, "value-changed", G_CALLBACK(on_year_changed), app);
g_signal_connect(combo_month, "changed", G_CALLBACK(on_month_changed), app);

gtk_widget_show_all(app->window);
g_signal_connect(app->window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

mark_dates_with_entries(app);

gtk_main();

g_hash_table_destroy(app->marked_dates);
g_free(app->diary_dir);
g_slice_free(AppWidgets, app);

return 0;
}

Needs gtk3 dev libs (e.g. libgtk-3-dev)
Compiles with:

Code: Select all

 gcc -o calendar `pkg-config --cflags gtk+-3.0` calendar.c `pkg-config --libs gtk+-3.0` -Wall

@rockedge will you do the honor to test it first in KLV?

Stealing from the poor to give to the rich!
bslit - Block Splitter Custom Calendar Widget + Diary

User avatar
rockedge
Site Admin
Posts: 6543
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2749 times
Been thanked: 2624 times
Contact:

Re: Gtkdialog Calendar

Post by rockedge »

Yes I will be testing it!

I tried this code in KLV-Airedale and works OOTB:

Code: Select all

#!/bin/bash

color="#398EE7"
echo "$color" > selected_color
mkdir -p number

btn(){
	for i in {1..7};do
		echo '
		<hbox spacing="0">'
		for j in {1..7};do
			echo '
			<button relief="2" width-request="46" height-request="40">
				<input file>number/grid_'$i$j'.svg</input>
				<action>svg_number_click number/grid_'$i$j'.svg</action>
				<action>refresh:btn_grid_'$i$j'</action>
				'"`refresh_btn_grid`"'
				<variable>btn_grid_'$i$j'</variable>
			</button>'
		
		done
		echo '
		</hbox>'
	done
}

btn2(){
	m=1
	for i in {1..3};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			b=`date -d "2022-$m-1" "+%b"`
			svg_number "$b" 14 number/grid2_$m.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid2_'$m'.svg</input>
				<action>echo '$m' > month</action>
				<action>year_to_month</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button</action>
'"`refresh_btn_grid`"'
				<variable>btn2_'$m'</variable>
			</button>'
			((m++))
		done
		echo '
		</hbox>'
	done
}

btn3(){
	touch top_left_year
	tly=`cat top_left_year`
	if [ "$tly" == "" ];then
		Y=`date "+%Y"`
		tly=$((Y-(Y%20)+1))		#top_left_year on grid
	fi
	
	Y="$tly"
	
	for i in {1..5};do
		echo '
		<hbox spacing="0">'
		for j in {1..4};do
			
			svg_number "$Y" 12 number/grid3_$i$j.svg
			
			echo '
			<button relief="2" width-request="80" height-request="70">
				<input file>number/grid3_'$i$j'.svg</input>
				<action>two_decades_to_year grid3_'$i$j'.svg</action>
				<action>refresh:nb_kalender</action>
				<action>refresh:long_button2</action>
				<variable>btn3_'$i$j'</variable>
			</button>'
			((Y++))
		done
		echo '
		</hbox>'
	done
}

amonth(){
	m="$1"
	Y="$2"
	
	#echo "$m $Y"	#debug
	if [ "$m" == "" ];then m=`date +'%m'`;fi
	if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
	
	BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
	echo "$Y-$m-1" > year_month
	echo "$m"|sed 's/^0*//' > month
	echo "$Y" > year
	
	svg_word "$BY" 20 number/monthyear.svg
	svg_word "$Y" 20 number/year.svg

	#echo "$m $Y"	#debug
	
	row=1
	cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
	#cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
		for column in {1..7};do
		number_grid=`echo "$line"|cut -d "," -f $column`
		number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
		
		if [ "$row" == "1" ];then
			svg_number "$number_grid" 10 "number/grid_$row$column.svg"
		else
			if [ "$number_without_space" != "" ];then
			date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
			fi
			today=`date "+%Y%m%d"`
			if [ "$date_grid" == "$today" ];then 
				echo "btn_grid_$row$column" > btn_today
				svg_number_selected "$number_grid" 16 "number/grid_$row$column.svg"
			else
				svg_number "$number_grid" 16 "number/grid_$row$column.svg"
			fi
		fi
		
		
		done
		((row++))
	done
}
export -f amonth

change_month(){
	current_month=`cat year_month`
	new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
	
	BY=`date -d "$new_month" "+%B %Y"`
	m=`date -d "$new_month" "+%m"`
	Y=`date -d "$new_month" "+%Y"`
	
	amonth "$m" "$Y"
}
export -f change_month


change_year(){
	current_year=`cat year`
	new_year=$(( current_year $1 ))
	echo "$new_year" > year
	svg_word "$new_year" 20 number/year.svg
}
export -f change_year

svg_now(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	#clock=`date "+%R"`
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="300" height="20">
  <rect width="300" height="20" style="fill:none; stroke-width:0" />
  <text x="2" y="90%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="left">'$1'</text>
</svg>' > "$3"
}
export -f svg_now

svg_word(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="200" height="30">
  <rect width="200" height="30" style="fill:none; stroke-width:0" />
  <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>    
</svg>' > "$3"
}
export -f svg_word

svg_number(){
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="30" style="fill:none; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number

svg_number_selected(){
	color=`cat selected_color`
	if [ "$color" == "" ];then color="#0077D6";fi
	echo '<?xml version="1.0" encoding="UTF-8"?>
<svg width="30" height="30">
  <rect width="30" height="5" y="25" style="fill:'$color'; stroke-width:0" />
  <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>    
</svg>' > "$3"
}
export -f svg_number_selected

svg_number_click(){
	for i in {1..7};do
		for j in {1..7};do
			sed -i '/circle/d' number/grid_$i$j.svg
		done
	done	
	sed -i '2 a <circle cx="15" cy="2" r="2" style="fill:#FFA500" />' "$1"
	d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
	m=`cat month`
	y=`cat year`
	if [[ $d =~ [0-9] ]];then
	click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"`
	else
		click_date="Not a date"
	fi
	echo "$click_date"
	echo "$click_date" > click_date
}
export -f svg_number_click


refresh_btn_grid(){
	echo '				<action>refresh:long_button</action>'
	for i in {1..7};do
		for j in {1..7};do
			echo '				<action>refresh:btn_grid_'$i$j'</action>'
		done
	done	
}

refresh_btn2(){
	echo '				<action>refresh:long_button2</action>'
	for i in {1..12};do
		echo '				<action>refresh:btn2_'$i'</action>'
	done	
}

refresh_btn3(){
	echo '				<action>refresh:long_button3</action>'
	for i in {1..5};do
		for j in {1..4};do
			echo '				<action>refresh:btn3_'$i$j'</action>'
		done
	done	
}

change_two_decades(){
	change="$1"
	Y=`cat year`
	
	if [ "$1" == "+1" ];then
		Y=$((Y+20))
	elif [ "$1" == "-1" ];then
		Y=$((Y-20))
	fi
	echo "$Y" > year
	
	tly=$((Y-(Y%20)+1))	
	Y="$tly"
	for i in {1..5};do
		for j in {1..4};do
			svg_number "$Y" 12 number/grid3_$i$j.svg
			((Y++))
		done
	done
	Y=$((Y-1))
	svg_word "$tly - $Y" 20 number/two_decades.svg	
}
export -f change_two_decades

month_to_year(){
	y=`cut -d "-" -f1 year_month`
	svg_word "$y" 20 number/year.svg
	
	m=`cat month`
	for i in {1..12};do
		b=`date -d "2022-$i-1" "+%b"`
		
		if [ "$i" == "$m" ];then
			svg_number_selected "$b" 14 number/grid2_$i.svg
		else
			svg_number "$b" 14 number/grid2_$i.svg
		fi
	done
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f month_to_year

year_to_month(){
	m=`cat month`
	y=`cat year`
	#BY=`date -d "$y-$m-1" "+%B %Y"`
	#svg_word "$BY" 20 number/monthyear.svg
	amonth "$m" "$y"
	echo 0 > tabpos
}
export -f year_to_month

year_to_two_decades(){
	Y=`cat year`
	tly=$((Y-(Y%20)+1))	
	Y="$tly"
	for i in {1..5};do
		for j in {1..4};do
			svg_number "$Y" 12 number/grid3_$i$j.svg
			((Y++))
		done
	done
	svg_word "$tly - $((Y-1))" 20 number/two_decades.svg
	
	
	echo 2 > tabpos
}
export -f year_to_two_decades

two_decades_to_year(){
	y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
	
	svg_word "$y" 20 number/year.svg
	
	echo "$y" > year
	echo 1 > tabpos
}
export -f two_decades_to_year


now(){
	today=`date "+%A, %d %B %Y"`
	svg_now "$today" 11 number/today.svg
	amonth
	echo 0 > tabpos
	
	echo "$today"
	echo "$today" > click_date
}
export -f now


# make arrow
echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,11 15,18 23,11" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/next.svg

echo '<?xml version="1.0" encoding="UTF-8"?>
<svg height="30" width="30">
  <path d="M7,18 15,11 23,18" stroke="black" stroke-width="1" fill="none"/>
</svg>' > number/previous.svg



#amonth 4
#amonth
now






echo '
<window title="kalendermuks">
<vbox spacing="0">

<button xalign="0" relief="2" padding="0">
	<input file>number/today.svg</input>
	<action>now</action>
	<action>refresh:nb_kalender</action>
	<action>grabfocus:'"`cat btn_today`"'</action>
	'"`refresh_btn_grid`"'
</button>
<hseparator></hseparator>

<notebook show-tabs="false" show-border="false" >
<vbox spacing="0">
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/monthyear.svg</input>
			<action>month_to_year</action>
			<action>refresh:nb_kalender</action>
			'"`refresh_btn2`"'
			<variable>long_button</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_month -1</action>
			'"`refresh_btn_grid`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_month 1</action>
			'"`refresh_btn_grid`"'
		</button>
		
	</hbox>
'"`btn`"'
	
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0">
			<input file>number/year.svg</input>
			<action>year_to_two_decades</action>
			<action>refresh:nb_kalender</action>
			'"`refresh_btn3`"'
			<variable>long_button2</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_year -1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_year +1</action>
			<action>refresh:long_button2</action>
			
		</button>
		
	</hbox>
	'"`btn2`"'
</vbox>

<vbox>
	<hbox spacing="0">
		<button relief="2" width-request="230" height-request="40" xalign="0" sensitive="false">
			<input file>number/two_decades.svg</input>
			<variable>long_button3</variable>
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/previous.svg</input>
			<action>change_two_decades -1</action>
			<action>year_to_two_decades</action>
			'"`refresh_btn3`"'
		</button>
		
		<button relief="2" width-request="46" height-request="40">
			<input file>number/next.svg</input>
			<action>change_two_decades +1</action>
			'"`refresh_btn3`"'
		</button>
		
	</hbox>
	'"`btn3`"'
</vbox>
<input file>tabpos</input>
<variable>nb_kalender</variable>
</notebook>

</vbox>

<action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>
<action signal="key-press-event" condition="command_is_true([ $KEY_SYM = Escape ] && echo true )">exit:Esc</action>
</window>' > guikalender

gtkdialog -f guikalender
Screenshot_2024-07-11_11-15-30.jpg
Screenshot_2024-07-11_11-15-30.jpg (18.74 KiB) Viewed 1437 times

So I believe the C program will compile and run! I Will post a report......

User avatar
rockedge
Site Admin
Posts: 6543
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2749 times
Been thanked: 2624 times
Contact:

Re: Gtkdialog Calendar

Post by rockedge »

Build failure! Encountered some errors on the first compile attempt!!
using gtk+3-devel 3.24.42_1

Code: Select all

root# gcc -o calendar `pkg-config --cflags gtk+-3.0` calendar.c `pkg-config --libs gtk+-3.0` -Wall
calendar.c:1:2: error: invalid preprocessing directive #!
    1 | #!/bin/bash
      |  ^
calendar.c:3:1: warning: data definition has no type or storage class
    3 | color="#398EE7"
      | ^~~~~
calendar.c:3:1: warning: type defaults to 'int' in declaration of 'color' [-Wimplicit-int]
calendar.c:3:7: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
    3 | color="#398EE7"
      |       ^~~~~~~~~
calendar.c:3:7: error: initializer element is not computable at load time
calendar.c:4:1: error: expected ',' or ';' before 'echo'
    4 | echo "$color" > selected_color
      | ^~~~
calendar.c:8:19: error: too many decimal points in number
    8 |         for i in {1..7};do
      |                   ^~~~
calendar.c:9:22: warning: missing terminating ' character
    9 |                 echo '
      |                      ^
calendar.c:9:22: error: missing terminating ' character
calendar.c:10:35: warning: missing terminating ' character
   10 |                 <hbox spacing="0">'
      |                                   ^
calendar.c:10:35: error: missing terminating ' character
calendar.c:11:27: error: too many decimal points in number
   11 |                 for j in {1..7};do
      |                           ^~~~
calendar.c:12:30: warning: missing terminating ' character
   12 |                         echo '
      |                              ^
calendar.c:12:30: error: missing terminating ' character
calendar.c:14:57: warning: multi-character character constant [-Wmultichar]
   14 |                                 <input file>number/grid_'$i$j'.svg</input>
      |                                                         ^~~~~~
calendar.c:15:70: warning: multi-character character constant [-Wmultichar]
   15 |                                 <action>svg_number_click number/grid_'$i$j'.svg</action>
      |                                                                      ^~~~~~
calendar.c:16:58: warning: multi-character character constant [-Wmultichar]
   16 |                                 <action>refresh:btn_grid_'$i$j'</action>
      |                                                          ^~~~~~
calendar.c:17:33: warning: character constant too long for its type
   17 |                                 '"`refresh_btn_grid`"'
      |                                 ^~~~~~~~~~~~~~~~~~~~~~
calendar.c:18:52: warning: multi-character character constant [-Wmultichar]
   18 |                                 <variable>btn_grid_'$i$j'</variable>
      |                                                    ^~~~~~
calendar.c:19:34: warning: missing terminating ' character
   19 |                         </button>'
      |                                  ^
calendar.c:19:34: error: missing terminating ' character
calendar.c:22:22: warning: missing terminating ' character
   22 |                 echo '
      |                      ^
calendar.c:22:22: error: missing terminating ' character
calendar.c:23:24: warning: missing terminating ' character
   23 |                 </hbox>'
      |                        ^
calendar.c:23:24: error: missing terminating ' character
calendar.c:27:1: warning: return type defaults to 'int' [-Wimplicit-int]
   27 | btn2(){
      | ^~~~
calendar.c: In function 'btn2':
calendar.c:28:9: error: 'm' undeclared (first use in this function)
   28 |         m=1
      |         ^
calendar.c:28:9: note: each undeclared identifier is reported only once for each function it appears in
calendar.c:28:12: error: expected ';' before 'for'
   28 |         m=1
      |            ^
      |            ;
   29 |         for i in {1..3};do
      |         ~~~ 
calendar.c:29:19: error: too many decimal points in number
   29 |         for i in {1..3};do
      |                   ^~~~
calendar.c:30:22: warning: missing terminating ' character
   30 |                 echo '
      |                      ^
calendar.c:30:22: error: missing terminating ' character
calendar.c:30:17: error: 'echo' undeclared (first use in this function)
   30 |                 echo '
      |                 ^~~~
calendar.c:31:18: error: 'hbox' undeclared (first use in this function)
   31 |                 <hbox spacing="0">'
      |                  ^~~~
calendar.c:31:22: error: expected ';' before 'spacing'
   31 |                 <hbox spacing="0">'
      |                      ^~~~~~~~
      |                      ;
calendar.c:31:35: warning: missing terminating ' character
   31 |                 <hbox spacing="0">'
      |                                   ^
calendar.c:31:35: error: missing terminating ' character
calendar.c:32:27: error: too many decimal points in number
   32 |                 for j in {1..4};do
      |                           ^~~~
calendar.c:32:33: error: expected 'while' before 'do'
   32 |                 for j in {1..4};do
      |                                 ^~
calendar.c:33:27: error: stray '`' in program
   33 |                         b=`date -d "2022-$m-1" "+%b"`
      |                           ^
calendar.c:33:53: error: stray '`' in program
   33 |                         b=`date -d "2022-$m-1" "+%b"`
      |                                                     ^
calendar.c:36:30: warning: missing terminating ' character
   36 |                         echo '
      |                              ^
calendar.c:36:30: error: missing terminating ' character
calendar.c:38:58: warning: multi-character character constant [-Wmultichar]
   38 |                                 <input file>number/grid2_'$m'.svg</input>
      |                                                          ^~~~
calendar.c:39:46: warning: multi-character character constant [-Wmultichar]
   39 |                                 <action>echo '$m' > month</action>
      |                                              ^~~~
calendar.c:43:1: warning: character constant too long for its type
   43 | '"`refresh_btn_grid`"'
      | ^~~~~~~~~~~~~~~~~~~~~~
calendar.c:44:48: warning: multi-character character constant [-Wmultichar]
   44 |                                 <variable>btn2_'$m'</variable>
      |                                                ^~~~
calendar.c:45:34: warning: missing terminating ' character
   45 |                         </button>'
      |                                  ^
calendar.c:45:34: error: missing terminating ' character
calendar.c:48:22: warning: missing terminating ' character
   48 |                 echo '
      |                      ^
calendar.c:48:22: error: missing terminating ' character
calendar.c:49:24: warning: missing terminating ' character
   49 |                 </hbox>'
      |                        ^
calendar.c:49:24: error: missing terminating ' character
calendar.c:53:1: warning: implicit declaration of function 'btn3'; did you mean 'btn2'? [-Wimplicit-function-declaration]
   53 | btn3(){
      | ^~~~
      | btn2
calendar.c:53:7: error: expected ';' before '{' token
   53 | btn3(){
      |       ^
      |       ;
calendar.c:55:13: error: stray '`' in program
   55 |         tly=`cat top_left_year`
      |             ^
calendar.c:55:31: error: stray '`' in program
   55 |         tly=`cat top_left_year`
      |                               ^
calendar.c:57:19: error: stray '`' in program
   57 |                 Y=`date "+%Y"`
      |                   ^
calendar.c:57:30: error: stray '`' in program
   57 |                 Y=`date "+%Y"`
      |                              ^
calendar.c:58:49: error: stray '#' in program
   58 |                 tly=$((Y-(Y%20)+1))             #top_left_year on grid
      |                                                 ^
calendar.c:63:19: error: too many decimal points in number
   63 |         for i in {1..5};do
      |                   ^~~~
calendar.c:64:22: warning: missing terminating ' character
   64 |                 echo '
      |                      ^
calendar.c:64:22: error: missing terminating ' character
calendar.c:65:35: warning: missing terminating ' character
   65 |                 <hbox spacing="0">'
      |                                   ^
calendar.c:65:35: error: missing terminating ' character
calendar.c:66:27: error: too many decimal points in number
   66 |                 for j in {1..4};do
      |                           ^~~~
calendar.c:70:30: warning: missing terminating ' character
   70 |                         echo '
      |                              ^
calendar.c:70:30: error: missing terminating ' character
calendar.c:72:58: warning: multi-character character constant [-Wmultichar]
   72 |                                 <input file>number/grid3_'$i$j'.svg</input>
      |                                                          ^~~~~~
calendar.c:73:67: warning: multi-character character constant [-Wmultichar]
   73 |                                 <action>two_decades_to_year grid3_'$i$j'.svg</action>
      |                                                                   ^~~~~~
calendar.c:76:48: warning: multi-character character constant [-Wmultichar]
   76 |                                 <variable>btn3_'$i$j'</variable>
      |                                                ^~~~~~
calendar.c:77:34: warning: missing terminating ' character
   77 |                         </button>'
      |                                  ^
calendar.c:77:34: error: missing terminating ' character
calendar.c:80:22: warning: missing terminating ' character
   80 |                 echo '
      |                      ^
calendar.c:80:22: error: missing terminating ' character
calendar.c:81:24: warning: missing terminating ' character
   81 |                 </hbox>'
      |                        ^
calendar.c:81:24: error: missing terminating ' character
calendar.c:89:10: error: invalid preprocessing directive #echo
   89 |         #echo "$m $Y"   #debug
      |          ^~~~
calendar.c:90:34: error: stray '`' in program
   90 |         if [ "$m" == "" ];then m=`date +'%m'`;fi
      |                                  ^
calendar.c:90:41: warning: multi-character character constant [-Wmultichar]
   90 |         if [ "$m" == "" ];then m=`date +'%m'`;fi
      |                                         ^~~~
calendar.c:90:45: error: stray '`' in program
   90 |         if [ "$m" == "" ];then m=`date +'%m'`;fi
      |                                             ^
calendar.c:91:34: error: stray '`' in program
   91 |         if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
      |                                  ^
calendar.c:91:41: warning: multi-character character constant [-Wmultichar]
   91 |         if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
      |                                         ^~~~
calendar.c:91:45: error: stray '`' in program
   91 |         if [ "$Y" == "" ];then Y=`date +'%Y'`;fi
      |                                             ^
calendar.c:93:12: error: stray '`' in program
   93 |         BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
      |            ^
calendar.c:93:33: warning: character constant too long for its type
   93 |         BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
      |                                 ^~~~~~~~
calendar.c:93:41: error: stray '`' in program
   93 |         BY=`date -d "$Y"-"$m"-1 '+%B %Y'`
      |                                         ^
calendar.c:95:23: warning: character constant too long for its type
   95 |         echo "$m"|sed 's/^0*//' > month
      |                       ^~~~~~~~~
calendar.c:101:10: error: invalid preprocessing directive #echo
  101 |         #echo "$m $Y"   #debug
      |          ^~~~
calendar.c:104:30: warning: character constant too long for its type
  104 |         cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:104:69: warning: unknown escape sequence: '\)'
  104 |         cal "$m" "$Y"|tr -cd '\11\12\15\40\60-\136\140-\176'|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
      |                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:104:69: warning: unknown escape sequence: '\)'
calendar.c:104:69: warning: character constant too long for its type
calendar.c:105:10: error: invalid preprocessing directive #cal
  105 |         #cal "$m" "$Y"|sed -e '1d;s/\(..\)\(.\)/\1,/g'|while read line;do
      |          ^~~
calendar.c:106:32: error: too many decimal points in number
  106 |                 for column in {1..7};do
      |                                ^~~~
calendar.c:107:29: error: stray '`' in program
  107 |                 number_grid=`echo "$line"|cut -d "," -f $column`
      |                             ^
calendar.c:107:64: error: stray '`' in program
  107 |                 number_grid=`echo "$line"|cut -d "," -f $column`
      |                                                                ^
calendar.c:108:38: error: stray '`' in program
  108 |                 number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
      |                                      ^
calendar.c:108:63: warning: character constant too long for its type
  108 |                 number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
      |                                                               ^~~~~~~~~~
calendar.c:108:73: error: stray '`' in program
  108 |                 number_without_space=`echo "$number_grid"|sed 's/^ *//g'`
      |                                                                         ^
calendar.c:114:35: error: stray '`' in program
  114 |                         date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
      |                                   ^
calendar.c:114:78: error: stray '`' in program
  114 |                         date_grid=`date -d "$Y"-"$m"-"$number_grid" "+%Y%m%d"`
      |                                                                              ^
calendar.c:116:31: error: stray '`' in program
  116 |                         today=`date "+%Y%m%d"`
      |                               ^
calendar.c:116:46: error: stray '`' in program
  116 |                         today=`date "+%Y%m%d"`
      |                                              ^
calendar.c:133:23: error: stray '`' in program
  133 |         current_month=`cat year_month`
      |                       ^
calendar.c:133:38: error: stray '`' in program
  133 |         current_month=`cat year_month`
      |                                      ^
calendar.c:134:19: error: stray '`' in program
  134 |         new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
      |                   ^
calendar.c:134:64: error: stray '`' in program
  134 |         new_month=`date -d "$current_month $1 month" "+%Y-%m-1"`
      |                                                                ^
calendar.c:136:12: error: stray '`' in program
  136 |         BY=`date -d "$new_month" "+%B %Y"`
      |            ^
calendar.c:136:42: error: stray '`' in program
  136 |         BY=`date -d "$new_month" "+%B %Y"`
      |                                          ^
calendar.c:137:11: error: stray '`' in program
  137 |         m=`date -d "$new_month" "+%m"`
      |           ^
calendar.c:137:38: error: stray '`' in program
  137 |         m=`date -d "$new_month" "+%m"`
      |                                      ^
calendar.c:138:11: error: stray '`' in program
  138 |         Y=`date -d "$new_month" "+%Y"`
      |           ^
calendar.c:138:38: error: stray '`' in program
  138 |         Y=`date -d "$new_month" "+%Y"`
      |                                      ^
calendar.c:146:22: error: stray '`' in program
  146 |         current_year=`cat year`
      |                      ^
calendar.c:146:31: error: stray '`' in program
  146 |         current_year=`cat year`
      |                               ^
calendar.c:154:15: error: stray '`' in program
  154 |         color=`cat selected_color`
      |               ^
calendar.c:154:34: error: stray '`' in program
  154 |         color=`cat selected_color`
      |                                  ^
calendar.c:156:10: error: invalid preprocessing directive #clock
  156 |         #clock=`date "+%R"`
      |          ^~~~~
calendar.c:157:14: warning: missing terminating ' character
  157 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^
calendar.c:157:14: error: missing terminating ' character
  157 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:160:96: warning: multi-character character constant [-Wmultichar]
  160 |   <text x="2" y="90%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="left">'$1'</text>
      |                                                                                                ^~~~
calendar.c:161:7: warning: missing terminating ' character
  161 | </svg>' > "$3"
      |       ^
calendar.c:161:7: error: missing terminating ' character
  161 | </svg>' > "$3"
      |       ^~~~~~~~
calendar.c:166:14: warning: missing terminating ' character
  166 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^
calendar.c:166:14: error: missing terminating ' character
  166 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:169:114: warning: multi-character character constant [-Wmultichar]
  169 |   <text x="2" y="70%" style="fill:black; font-family:sans; font-weight:bold; font-size:'$2';" text-anchor="left">'$1'</text>
      |                                                                                                                  ^~~~
calendar.c:170:7: warning: missing terminating ' character
  170 | </svg>' > "$3"
      |       ^
calendar.c:170:7: error: missing terminating ' character
  170 | </svg>' > "$3"
      |       ^~~~~~~~
calendar.c:175:14: warning: missing terminating ' character
  175 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^
calendar.c:175:14: error: missing terminating ' character
  175 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:178:100: warning: multi-character character constant [-Wmultichar]
  178 |   <text x="50%" y="70%" style="fill:black; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>
      |                                                                                                    ^~~~
calendar.c:179:7: warning: missing terminating ' character
  179 | </svg>' > "$3"
      |       ^
calendar.c:179:7: error: missing terminating ' character
  179 | </svg>' > "$3"
      |       ^~~~~~~~
calendar.c:184:15: error: stray '`' in program
  184 |         color=`cat selected_color`
      |               ^
calendar.c:184:34: error: stray '`' in program
  184 |         color=`cat selected_color`
      |                                  ^
calendar.c:186:14: warning: missing terminating ' character
  186 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^
calendar.c:186:14: error: missing terminating ' character
  186 |         echo '<?xml version="1.0" encoding="UTF-8"?>
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:189:118: warning: multi-character character constant [-Wmultichar]
  189 |   <text x="50%" y="70%" style="fill:black; font-weight:bold; font-family:sans; font-size:'$2';" text-anchor="middle">'$1'</text>
      |                                                                                                                      ^~~~
calendar.c:190:7: warning: missing terminating ' character
  190 | </svg>' > "$3"
      |       ^
calendar.c:190:7: error: missing terminating ' character
  190 | </svg>' > "$3"
      |       ^~~~~~~~
calendar.c:195:19: error: too many decimal points in number
  195 |         for i in {1..7};do
      |                   ^~~~
calendar.c:196:27: error: too many decimal points in number
  196 |                 for j in {1..7};do
      |                           ^~~~
calendar.c:197:32: warning: character constant too long for its type
  197 |                         sed -i '/circle/d' number/grid_$i$j.svg
      |                                ^~~~~~~~~~~
calendar.c:200:16: warning: character constant too long for its type
  200 |         sed -i '2 a <circle cx="15" cy="2" r="2" style="fill:#FFA500" />' "$1"
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:201:11: error: stray '`' in program
  201 |         d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
      |           ^
calendar.c:201:43: warning: character constant too long for its type
  201 |         d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
      |                                           ^~~~~~~~
calendar.c:201:58: error: stray '\' in program
  201 |         d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
      |                                                          ^
calendar.c:201:69: warning: character constant too long for its type
  201 |         d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
      |                                                                     ^~~~~~~~~~
calendar.c:201:79: error: stray '`' in program
  201 |         d=`grep -o ">.*</text>" "$1" |sed 's/>//g'|cut -d\< -f1|sed 's/^ *//g'`
      |                                                                               ^
calendar.c:202:11: error: stray '`' in program
  202 |         m=`cat month`
      |           ^
calendar.c:202:21: error: stray '`' in program
  202 |         m=`cat month`
      |                     ^
calendar.c:203:11: error: stray '`' in program
  203 |         y=`cat year`
      |           ^
calendar.c:203:20: error: stray '`' in program
  203 |         y=`cat year`
      |                    ^
calendar.c:205:20: error: stray '`' in program
  205 |         click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"`
      |                    ^
calendar.c:205:55: error: stray '`' in program
  205 |         click_date=`date -d "$y-$m-$d" "+%A, %d %B %Y"`
      |                                                       ^
calendar.c:216:14: warning: character constant too long for its type
  216 |         echo '                          <action>refresh:long_button</action>'
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:217:19: error: too many decimal points in number
  217 |         for i in {1..7};do
      |                   ^~~~
calendar.c:218:27: error: too many decimal points in number
  218 |                 for j in {1..7};do
      |                           ^~~~
calendar.c:219:30: warning: character constant too long for its type
  219 |                         echo '                          <action>refresh:btn_grid_'$i$j'</action>'
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:219:87: warning: character constant too long for its type
  219 |                         echo '                          <action>refresh:btn_grid_'$i$j'</action>'
      |                                                                                       ^~~~~~~~~~~
calendar.c:225:14: warning: character constant too long for its type
  225 |         echo '                          <action>refresh:long_button2</action>'
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:226:19: error: too many decimal points in number
  226 |         for i in {1..12};do
      |                   ^~~~~
calendar.c:227:22: warning: character constant too long for its type
  227 |                 echo '                          <action>refresh:btn2_'$i'</action>'
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:227:73: warning: character constant too long for its type
  227 |                 echo '                          <action>refresh:btn2_'$i'</action>'
      |                                                                         ^~~~~~~~~~~
calendar.c:232:14: warning: character constant too long for its type
  232 |         echo '                          <action>refresh:long_button3</action>'
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:233:19: error: too many decimal points in number
  233 |         for i in {1..5};do
      |                   ^~~~
calendar.c:234:27: error: too many decimal points in number
  234 |                 for j in {1..4};do
      |                           ^~~~
calendar.c:235:30: warning: character constant too long for its type
  235 |                         echo '                          <action>refresh:btn3_'$i$j'</action>'
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:235:83: warning: character constant too long for its type
  235 |                         echo '                          <action>refresh:btn3_'$i$j'</action>'
      |                                                                                   ^~~~~~~~~~~
calendar.c:242:11: error: stray '`' in program
  242 |         Y=`cat year`
      |           ^
calendar.c:242:20: error: stray '`' in program
  242 |         Y=`cat year`
      |                    ^
calendar.c:253:19: error: too many decimal points in number
  253 |         for i in {1..5};do
      |                   ^~~~
calendar.c:254:27: error: too many decimal points in number
  254 |                 for j in {1..4};do
      |                           ^~~~
calendar.c:265:11: error: stray '`' in program
  265 |         y=`cut -d "-" -f1 year_month`
      |           ^
calendar.c:265:37: error: stray '`' in program
  265 |         y=`cut -d "-" -f1 year_month`
      |                                     ^
calendar.c:268:11: error: stray '`' in program
  268 |         m=`cat month`
      |           ^
calendar.c:268:21: error: stray '`' in program
  268 |         m=`cat month`
      |                     ^
calendar.c:269:19: error: too many decimal points in number
  269 |         for i in {1..12};do
      |                   ^~~~~
calendar.c:270:19: error: stray '`' in program
  270 |                 b=`date -d "2022-$i-1" "+%b"`
      |                   ^
calendar.c:270:45: error: stray '`' in program
  270 |                 b=`date -d "2022-$i-1" "+%b"`
      |                                             ^
calendar.c:285:11: error: stray '`' in program
  285 |         m=`cat month`
      |           ^
calendar.c:285:21: error: stray '`' in program
  285 |         m=`cat month`
      |                     ^
calendar.c:286:11: error: stray '`' in program
  286 |         y=`cat year`
      |           ^
calendar.c:286:20: error: stray '`' in program
  286 |         y=`cat year`
      |                    ^
calendar.c:287:10: error: invalid preprocessing directive #BY
  287 |         #BY=`date -d "$y-$m-1" "+%B %Y"`
      |          ^~
calendar.c:288:10: error: invalid preprocessing directive #svg_word
  288 |         #svg_word "$BY" 20 number/monthyear.svg
      |          ^~~~~~~~
calendar.c:295:11: error: stray '`' in program
  295 |         Y=`cat year`
      |           ^
calendar.c:295:20: error: stray '`' in program
  295 |         Y=`cat year`
      |                    ^
calendar.c:298:19: error: too many decimal points in number
  298 |         for i in {1..5};do
      |                   ^~~~
calendar.c:299:27: error: too many decimal points in number
  299 |                 for j in {1..4};do
      |                           ^~~~
calendar.c:312:11: error: stray '`' in program
  312 |         y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
      |           ^
calendar.c:312:50: warning: character constant too long for its type
  312 |         y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
      |                                                  ^~~~~~~~
calendar.c:312:65: error: stray '\' in program
  312 |         y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
      |                                                                 ^
calendar.c:312:71: error: stray '`' in program
  312 |         y=`grep -o ">.*</text>" number/"$1" |sed 's/>//g'|cut -d\< -f1`
      |                                                                       ^
calendar.c:323:15: error: stray '`' in program
  323 |         today=`date "+%A, %d %B %Y"`
      |               ^
calendar.c:323:36: error: stray '`' in program
  323 |         today=`date "+%A, %d %B %Y"`
      |                                    ^
calendar.c:334:3: error: invalid preprocessing directive #make
  334 | # make arrow
      |   ^~~~
calendar.c:335:6: warning: missing terminating ' character
  335 | echo '<?xml version="1.0" encoding="UTF-8"?>
      |      ^
calendar.c:335:6: error: missing terminating ' character
  335 | echo '<?xml version="1.0" encoding="UTF-8"?>
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:338:7: warning: missing terminating ' character
  338 | </svg>' > number/next.svg
      |       ^
calendar.c:338:7: error: missing terminating ' character
  338 | </svg>' > number/next.svg
      |       ^~~~~~~~~~~~~~~~~~~
calendar.c:340:6: warning: missing terminating ' character
  340 | echo '<?xml version="1.0" encoding="UTF-8"?>
      |      ^
calendar.c:340:6: error: missing terminating ' character
  340 | echo '<?xml version="1.0" encoding="UTF-8"?>
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calendar.c:343:7: warning: missing terminating ' character
  343 | </svg>' > number/previous.svg
      |       ^
calendar.c:343:7: error: missing terminating ' character
  343 | </svg>' > number/previous.svg
      |       ^~~~~~~~~~~~~~~~~~~~~~~
calendar.c:347:2: error: invalid preprocessing directive #amonth
  347 | #amonth 4
      |  ^~~~~~
calendar.c:348:2: error: invalid preprocessing directive #amonth
  348 | #amonth
      |  ^~~~~~
calendar.c:356:6: warning: missing terminating ' character
  356 | echo '
      |      ^
calendar.c:356:6: error: missing terminating ' character
calendar.c:364:27: warning: character constant too long for its type
  364 |         <action>grabfocus:'"`cat btn_today`"'</action>
      |                           ^~~~~~~~~~~~~~~~~~~
calendar.c:365:9: warning: character constant too long for its type
  365 |         '"`refresh_btn_grid`"'
      |         ^~~~~~~~~~~~~~~~~~~~~~
calendar.c:376:25: warning: character constant too long for its type
  376 |                         '"`refresh_btn2`"'
      |                         ^~~~~~~~~~~~~~~~~~
calendar.c:383:25: warning: character constant too long for its type
  383 |                         '"`refresh_btn_grid`"'
      |                         ^~~~~~~~~~~~~~~~~~~~~~
calendar.c:389:25: warning: character constant too long for its type
  389 |                         '"`refresh_btn_grid`"'
      |                         ^~~~~~~~~~~~~~~~~~~~~~
calendar.c:393:1: warning: character constant too long for its type
  393 | '"`btn`"'
      | ^~~~~~~~~
calendar.c:403:25: warning: character constant too long for its type
  403 |                         '"`refresh_btn3`"'
      |                         ^~~~~~~~~~~~~~~~~~
calendar.c:422:9: warning: character constant too long for its type
  422 |         '"`btn2`"'
      |         ^~~~~~~~~~
calendar.c:436:25: warning: character constant too long for its type
  436 |                         '"`refresh_btn3`"'
      |                         ^~~~~~~~~~~~~~~~~~
calendar.c:442:25: warning: character constant too long for its type
  442 |                         '"`refresh_btn3`"'
      |                         ^~~~~~~~~~~~~~~~~~
calendar.c:446:9: warning: character constant too long for its type
  446 |         '"`btn3`"'
      |         ^~~~~~~~~~
calendar.c:454:43: warning: character constant too long for its type
  454 | <action signal="focus-in-event">grabfocus:'`cat btn_today`'</action>
      |                                           ^~~~~~~~~~~~~~~~~
calendar.c:456:10: warning: missing terminating ' character
  456 | </window>' > guikalender
      |          ^
calendar.c:456:10: error: missing terminating ' character
  456 | </window>' > guikalender
      |          ^~~~~~~~~~~~~~~
calendar.c:458:1: error: expected declaration or statement at end of input
  458 | gtkdialog -f guikalender
      | ^~~~~~~~~
calendar.c:459: warning: control reaches end of non-void function [-Wreturn-type]
root# 
[code]
superhik
Posts: 42
Joined: Mon Jun 19, 2023 7:56 pm
Has thanked: 6 times
Been thanked: 19 times

Re: Gtkdialog Calendar

Post by superhik »

Of course it failed, you tried to compile a bash script.
#!/bin/bash is in the first line.
Bash scripts can't compile with gcc.
That's the wrong file rockedge. :D
I've made my app in C.

Stealing from the poor to give to the rich!
bslit - Block Splitter Custom Calendar Widget + Diary

User avatar
rockedge
Site Admin
Posts: 6543
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2749 times
Been thanked: 2624 times
Contact:

Re: Gtkdialog Calendar

Post by rockedge »

@superhik Yes I know. I was compiling this ->
calendar.c

Code: Select all

#include <gtk/gtk.h>
#include <glib.h>
#include <cairo.h>

typedef struct {
    GtkWidget *window;
    GtkWidget *drawing_area;
    GtkWidget *text_view;
    gchar *diary_dir;
    guint current_year;
    guint current_month;
    guint selected_day;
    GHashTable *marked_dates;
} AppWidgets;

static gboolean draw_calendar(GtkWidget *widget, cairo_t *cr, AppWidgets *app) {
    const gchar *day_names[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

guint days_in_month = g_date_get_days_in_month(app->current_month + 1, app->current_year);
GDate *date = g_date_new_dmy(1, app->current_month + 1, app->current_year);
GDateWeekday first_weekday = g_date_get_weekday(date);
g_date_free(date);

GDateTime *now = g_date_time_new_now_local();
guint today_day = g_date_time_get_day_of_month(now);
guint today_month = g_date_time_get_month(now);
guint today_year = g_date_time_get_year(now);
g_date_time_unref(now);

GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
gint cell_width = allocation.width / 7;
gint cell_height = allocation.height / 7;  // Adjusted for day names
cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
cairo_rectangle(cr, cell_width, cell_height, cell_width, cell_height);
cairo_paint(cr);

// Centering calculations
gint text_width, text_height;
cairo_text_extents_t extents;
cairo_set_font_size(cr, cell_height * 0.4); // Font size for day names
cairo_text_extents(cr, day_names[0], &extents);
text_width = extents.width;
text_height = extents.height;

// Calculate starting point for day names to center them
gint start_x = (cell_width - text_width) / 2;
gint start_y = cell_height * 0.6;

cairo_set_source_rgb(cr, 0, 0, 0);
// Draw day names
for (int i = 0; i < 7; i++) {
    cairo_move_to(cr, i * cell_width / 2, cell_height * 0.6 / 2);
    if (i == 6) {
        // Draw Sunday in red
        cairo_set_source_rgb(cr, 1, 0, 0);
    } else if (i == 5) {
       cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
    } else {
        cairo_set_source_rgb(cr, 0, 0, 0);
    }
    cairo_text_extents(cr, day_names[i], &extents);
    text_width = extents.width;
    cairo_move_to(cr, i * cell_width + start_x, start_y);
    cairo_show_text(cr, day_names[i]);
}

// Draw grid
cairo_set_line_width(cr, 1);
cairo_set_source_rgb(cr, 0, 0, 0);
for (int i = 0; i < 7; i++) {
    for (int j = 1; j < 7; j++) {
        cairo_rectangle(cr, i * cell_width, j * cell_height, cell_width, cell_height);
    }
}
cairo_stroke(cr);
cairo_set_font_size(cr, cell_height * 0.5); // Adjust font size proportionally
// Draw days
for (guint day = 1; day <= days_in_month; day++) {
    gint row = (day + first_weekday - 2) / 7 + 1;
    gint column = (day + first_weekday - 2) % 7;
    gchar *text = g_strdup_printf("%2u", day);

    // Calculate text extents for day number
    cairo_text_extents(cr, text, &extents);
    text_width = extents.width;
    text_height = extents.height;
    
    // Calculate starting point to center day number
    start_x = column * cell_width + (cell_width - text_width) / 2;
    start_y = row * cell_height + cell_height / 2 + text_height / 2;
    if (column == 6) {
        // Draw Sunday dates in red
        cairo_set_source_rgb(cr, 1, 0, 0);
    } else if (column == 5) {
       cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
    } else {
        cairo_set_source_rgb(cr, 0, 0, 0);
    }
    cairo_move_to(cr, start_x, start_y);
    cairo_show_text(cr, text);
    g_free(text);

    if (g_hash_table_contains(app->marked_dates, GINT_TO_POINTER(day))) {
        cairo_set_source_rgb(cr, 0, 0, 0); 
        // Calculate dynamic radius based on cell dimensions
        double radius = MIN(cell_width, cell_height) / 10.0;
        cairo_arc(cr, column * cell_width + cell_width - 1.5 * radius, row * cell_height + 1.5 * radius, radius, 0, 2 * G_PI);

        cairo_close_path(cr);
        cairo_fill(cr);
        cairo_set_source_rgb(cr, 0, 0, 0);
    }

    // Highlight the selected day
    if (day == app->selected_day) {
        cairo_set_source_rgba(cr, 1, 0.7, 1, 0.07);
        cairo_set_source_rgb(cr, 0, 0, 1);  // Blue color for selected day
        cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
        cairo_set_line_width(cr, 3);
        cairo_stroke(cr);
        cairo_set_source_rgba(cr, 0, 0.7, 1, 0.1);
        cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
        cairo_fill(cr);
        cairo_set_source_rgb(cr, 0, 0, 0);  // Set back to black for text
    }

    // Highlight today's date
    if (day == today_day && app->current_month + 1 == today_month && app->current_year == today_year) {
        cairo_set_source_rgba(cr, 0, 1, 0, 0.3);  // Green color with transparency
        cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
        cairo_fill(cr);
        cairo_set_source_rgb(cr, 0, 0, 0);  // Set back to black for text
    }

}

return FALSE;
}

static void mark_dates_with_entries(AppWidgets *app) {
    g_hash_table_remove_all(app->marked_dates);

GDir *dir = g_dir_open(app->diary_dir, 0, NULL);
if (!dir) return;

const gchar *filename;
while ((filename = g_dir_read_name(dir))) {
    guint entry_year, entry_month, entry_day;
    if (sscanf(filename, "%4u-%2u-%2u.txt", &entry_year, &entry_month, &entry_day) == 3) {
        if (entry_year == app->current_year && entry_month == app->current_month + 1) {
            g_hash_table_add(app->marked_dates, GINT_TO_POINTER(entry_day));
        }
    }
}
g_dir_close(dir);
gtk_widget_queue_draw(app->drawing_area);
}

static void on_day_selected(GtkWidget *widget, GdkEventButton *event, AppWidgets *app) {
    guint days_in_month = g_date_get_days_in_month(app->current_month + 1, app->current_year);
    GDate *date = g_date_new_dmy(1, app->current_month + 1, app->current_year);
    GDateWeekday first_weekday = g_date_get_weekday(date);
    g_date_free(date);

GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
gint cell_width = allocation.width / 7;
gint cell_height = allocation.height / 7;  // Adjusted for day names

gint column = event->x / cell_width;
gint row = (event->y / cell_height) - 1;  // Adjust for day names
gint day = row * 7 + column - first_weekday + 2;

if (day < 1 || day > days_in_month) return;

gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, day);
gchar *content = NULL;
g_file_get_contents(filename, &content, NULL, NULL);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
gtk_text_buffer_set_text(buffer, content ? content : "", -1);
g_free(content);
g_free(filename);

app->selected_day = day;
mark_dates_with_entries(app);
}

static void on_save_clicked(GtkButton *button, AppWidgets *app) {
    if (app->selected_day == 0) return; // No day selected

GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
GtkTextIter start, end;
gtk_text_buffer_get_bounds(buffer, &start, &end);
gchar *content = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);

gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, app->selected_day);
g_file_set_contents(filename, content, -1, NULL);
g_free(filename);
g_free(content);

mark_dates_with_entries(app);
}

static void on_month_changed(GtkComboBox *combo, AppWidgets *app) {
    app->current_month = gtk_combo_box_get_active(combo);
    mark_dates_with_entries(app);
}

static void on_year_changed(GtkSpinButton *spin, AppWidgets *app) {
    app->current_year = gtk_spin_button_get_value_as_int(spin);
    mark_dates_with_entries(app);
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

AppWidgets *app = g_slice_new(AppWidgets);

// Get the current date
GDateTime *now = g_date_time_new_now_local();
app->current_year = g_date_time_get_year(now);
app->current_month = g_date_time_get_month(now) - 1; // g_date_time_get_month() is 1-based
app->selected_day = g_date_time_get_day_of_month(now);
g_date_time_unref(now);

app->diary_dir = g_build_filename(g_get_user_data_dir(), "diary_entries", NULL);
g_mkdir_with_parents(app->diary_dir, 0755);
app->marked_dates = g_hash_table_new(g_direct_hash, g_direct_equal);

app->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(app->window), "Custom Calendar Widget");
gtk_window_set_default_size(GTK_WINDOW(app->window), 500, 600);
gtk_window_set_icon_name(GTK_WINDOW(app->window), "xfcalendar");

GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(app->window), vbox);

GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

GtkWidget *spin_year = gtk_spin_button_new_with_range(1900, 2100, 1);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_year), app->current_year);
gtk_box_pack_start(GTK_BOX(hbox), spin_year, FALSE, FALSE, 0);

GtkWidget *combo_month = gtk_combo_box_text_new();
const gchar *months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
for (int i = 0; i < 12; i++) {
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_month), months[i]);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_month), app->current_month);
gtk_box_pack_start(GTK_BOX(hbox), combo_month, FALSE, FALSE, 0);

app->drawing_area = gtk_drawing_area_new();
gtk_box_pack_start(GTK_BOX(vbox), app->drawing_area, TRUE, TRUE, 0);
gtk_widget_set_size_request(app->drawing_area, 500, 350);
g_signal_connect(app->drawing_area, "draw", G_CALLBACK(draw_calendar), app);
g_signal_connect(app->drawing_area, "button-press-event", G_CALLBACK(on_day_selected), app);
gtk_widget_add_events(app->drawing_area, GDK_BUTTON_PRESS_MASK);

app->text_view = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox), app->text_view, TRUE, TRUE, 0);

GtkWidget *save_button = gtk_button_new_with_label("Save");
gtk_box_pack_start(GTK_BOX(vbox), save_button, FALSE, FALSE, 0);
g_signal_connect(save_button, "clicked", G_CALLBACK(on_save_clicked), app);

g_signal_connect(spin_year, "value-changed", G_CALLBACK(on_year_changed), app);
g_signal_connect(combo_month, "changed", G_CALLBACK(on_month_changed), app);

gtk_widget_show_all(app->window);
g_signal_connect(app->window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

mark_dates_with_entries(app);

gtk_main();

g_hash_table_destroy(app->marked_dates);
g_free(app->diary_dir);
g_slice_free(AppWidgets, app);

return 0;
}

That was a build attempt on KLV-Airedale and now I am going to give it a build run on a Noblepup64-FR

I will try it again on KLV.

User avatar
rockedge
Site Admin
Posts: 6543
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2749 times
Been thanked: 2624 times
Contact:

Re: Gtkdialog Calendar

Post by rockedge »

calendar.c compiled smoothly, error free, in Noblepup64-FR

Code: Select all

gcc -o calendar `pkg-config --cflags gtk+-3.0` calendar.c `pkg-config --libs gtk+-3.0` -Wall

and runs ->

Screenshot(12).jpg
Screenshot(12).jpg (44.62 KiB) Viewed 1419 times

Now to transfer this one to KLV-Airedale already compiled in Noblepup64-FR

superhik
Posts: 42
Joined: Mon Jun 19, 2023 7:56 pm
Has thanked: 6 times
Been thanked: 19 times

Re: Gtkdialog Calendar

Post by superhik »

It should look good on dark and light themes. Also when resizing the window, dates and date names will increase font size but should remain in center of the grid cells. Current date is green. If there is a diary entry it will add a small circle to the date. Have fun, suggest features, and report bugs.

Stealing from the poor to give to the rich!
bslit - Block Splitter Custom Calendar Widget + Diary

User avatar
rockedge
Site Admin
Posts: 6543
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2749 times
Been thanked: 2624 times
Contact:

Re: Gtkdialog Calendar

Post by rockedge »

@superhik Here is calendar in KLV-Airedale-sr14 ->

Screenshot_2024-07-11_14-35-06.jpg
Screenshot_2024-07-11_14-35-06.jpg (49.85 KiB) Viewed 1384 times
superhik
Posts: 42
Joined: Mon Jun 19, 2023 7:56 pm
Has thanked: 6 times
Been thanked: 19 times

Re: Gtkdialog Calendar

Post by superhik »

Looks good Rockedge.

Code: Select all

#include <gtk/gtk.h>
#include <glib.h>
#include <cairo.h>

typedef struct {
    GtkWidget *window;
    GtkWidget *drawing_area;
    GtkWidget *text_view;
    GtkWidget *save_button;
    GtkWidget *remove_button;
    GtkWidget *spin_year;
    GtkWidget *combo_month;
    gchar *diary_dir;
    guint current_year;
    guint current_month;
    guint selected_day;
    GHashTable *marked_dates;
} AppWidgets;

static gboolean draw_calendar(GtkWidget *widget, cairo_t *cr, AppWidgets *app) {
    const gchar *day_names[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

    guint days_in_month = g_date_get_days_in_month(app->current_month + 1, app->current_year);
    GDate *date = g_date_new_dmy(1, app->current_month + 1, app->current_year);
    GDateWeekday first_weekday = g_date_get_weekday(date);
    g_date_free(date);

    GDateTime *now = g_date_time_new_now_local();
    guint today_day = g_date_time_get_day_of_month(now);
    guint today_month = g_date_time_get_month(now);
    guint today_year = g_date_time_get_year(now);
    g_date_time_unref(now);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);
    gint cell_width = allocation.width / 7;
    gint cell_height = allocation.height / 7;  // Adjusted for day names
    cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
    cairo_rectangle(cr, cell_width, cell_height, cell_width, cell_height);
    cairo_paint(cr);

    // Centering calculations
    gint text_width, text_height;
    cairo_text_extents_t extents;
    cairo_set_font_size(cr, cell_height * 0.4); // Font size for day names
    cairo_text_extents(cr, day_names[0], &extents);
    text_width = extents.width;
    text_height = extents.height;

    // Calculate starting point for day names to center them
    gint start_x = (cell_width - text_width) / 2;
    gint start_y = cell_height * 0.6;

    cairo_set_source_rgb(cr, 0, 0, 0);
    // Draw day names
    for (int i = 0; i < 7; i++) {
        cairo_move_to(cr, i * cell_width / 2, cell_height * 0.6 / 2);
        if (i == 6) {
            // Draw Sunday in red
            cairo_set_source_rgb(cr, 1, 0, 0);
        } else if (i == 5) {
           cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
        } else {
            cairo_set_source_rgb(cr, 0, 0, 0);
        }
        cairo_text_extents(cr, day_names[i], &extents);
        text_width = extents.width;
        cairo_move_to(cr, i * cell_width + start_x, start_y);
        cairo_show_text(cr, day_names[i]);
    }

    // Draw grid
    cairo_set_line_width(cr, 1);
    cairo_set_source_rgb(cr, 0, 0, 0);
    for (int i = 0; i < 7; i++) {
        for (int j = 1; j < 7; j++) {
            cairo_rectangle(cr, i * cell_width, j * cell_height, cell_width, cell_height);
        }
    }
    cairo_stroke(cr);
    cairo_set_font_size(cr, cell_height * 0.5); // Adjust font size proportionally
    // Draw days
    for (guint day = 1; day <= days_in_month; day++) {
        gint row = (day + first_weekday - 2) / 7 + 1;
        gint column = (day + first_weekday - 2) % 7;
        gchar *text = g_strdup_printf("%2u", day);

        // Calculate text extents for day number
        cairo_text_extents(cr, text, &extents);
        text_width = extents.width;
        text_height = extents.height;
        
        // Calculate starting point to center day number
        start_x = column * cell_width + (cell_width - text_width) / 2;
        start_y = row * cell_height + cell_height / 2 + text_height / 2;
        if (column == 6) {
            // Draw Sunday dates in red
            cairo_set_source_rgb(cr, 1, 0, 0);
        } else if (column == 5) {
           cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
        } else {
            cairo_set_source_rgb(cr, 0, 0, 0);
        }
        cairo_move_to(cr, start_x, start_y);
        cairo_show_text(cr, text);
        g_free(text);

        if (g_hash_table_contains(app->marked_dates, GINT_TO_POINTER(day))) {
            cairo_set_source_rgb(cr, 0, 0, 0); 
            // Calculate dynamic radius based on cell dimensions
            double radius = MIN(cell_width, cell_height) / 10.0;
            cairo_arc(cr, column * cell_width + cell_width - 1.5 * radius, row * cell_height + 1.5 * radius, radius, 0, 2 * G_PI);

            cairo_close_path(cr);
            cairo_fill(cr);
            cairo_set_source_rgb(cr, 0, 0, 0);
        }

        // Highlight the selected day
        if (day == app->selected_day) {
            cairo_set_source_rgba(cr, 1, 0.7, 1, 0.07);
            cairo_set_source_rgb(cr, 0, 0, 1);  // Blue color for selected day
            cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
            cairo_set_line_width(cr, 3);
            cairo_stroke(cr);
            cairo_set_source_rgba(cr, 0, 0.7, 1, 0.1);
            cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
            cairo_fill(cr);
            cairo_set_source_rgb(cr, 0, 0, 0);  // Set back to black for text
        }

        // Highlight today's date
        if (day == today_day && app->current_month + 1 == today_month && app->current_year == today_year) {
            cairo_set_source_rgba(cr, 0, 1, 0, 0.3);  // Green color with transparency
            cairo_rectangle(cr, column * cell_width, row * cell_height, cell_width, cell_height);
            cairo_fill(cr);
            cairo_set_source_rgb(cr, 0, 0, 0);  // Set back to black for text
        }

    }

    return FALSE;
}

static void mark_dates_with_entries(AppWidgets *app) {
    g_hash_table_remove_all(app->marked_dates);

    GDir *dir = g_dir_open(app->diary_dir, 0, NULL);
    if (!dir) return;

    const gchar *filename;
    while ((filename = g_dir_read_name(dir))) {
        guint entry_year, entry_month, entry_day;
        if (sscanf(filename, "%4u-%2u-%2u.txt", &entry_year, &entry_month, &entry_day) == 3) {
            if (entry_year == app->current_year && entry_month == app->current_month + 1) {
                g_hash_table_add(app->marked_dates, GINT_TO_POINTER(entry_day));
            }
        }
    }
    g_dir_close(dir);
    gtk_widget_queue_draw(app->drawing_area);
}

static void on_day_selected(GtkWidget *widget, GdkEventButton *event, AppWidgets *app) {
    guint days_in_month = g_date_get_days_in_month(app->current_month + 1, app->current_year);
    GDate *date = g_date_new_dmy(1, app->current_month + 1, app->current_year);
    GDateWeekday first_weekday = g_date_get_weekday(date);
    g_date_free(date);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);
    gint cell_width = allocation.width / 7;
    gint cell_height = allocation.height / 7;  // Adjusted for day names

    gint column = event->x / cell_width;
    gint row = (event->y / cell_height) - 1;  // Adjust for day names
    gint day = row * 7 + column - first_weekday + 2;

    if (day < 1 || day > days_in_month) return;

    gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, day);
    gchar *content = NULL;
    g_file_get_contents(filename, &content, NULL, NULL);
    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
    gtk_text_buffer_set_text(buffer, content ? content : "", -1);
    g_free(content);
    g_free(filename);

    app->selected_day = day;
    mark_dates_with_entries(app);
}

static void on_save_clicked(GtkButton *button, AppWidgets *app) {
    if (app->selected_day == 0) return; // No day selected

    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
    GtkTextIter start, end;
    gtk_text_buffer_get_bounds(buffer, &start, &end);
    gchar *content = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);

    gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, app->selected_day);
    g_file_set_contents(filename, content, -1, NULL);
    g_free(filename);
    g_free(content);

    mark_dates_with_entries(app);
}

static void on_month_changed(GtkComboBox *combo, AppWidgets *app) {
    app->current_month = gtk_combo_box_get_active(combo);
    mark_dates_with_entries(app);
}

static void on_year_changed(GtkSpinButton *spin, AppWidgets *app) {
    app->current_year = gtk_spin_button_get_value_as_int(spin);
    mark_dates_with_entries(app);
}

static void on_remove_entry_clicked(GtkWidget *button, AppWidgets *app) {
    if (app->selected_day == 0) return;

    gchar *filename = g_strdup_printf("%s/%u-%02u-%02u.txt", app->diary_dir, app->current_year, app->current_month + 1, app->selected_day);
    remove(filename);
    g_free(filename);

    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(app->text_view));
    gtk_text_buffer_set_text(buffer, "", -1);

    mark_dates_with_entries(app);
}

static void on_today_button_clicked(GtkWidget *button, AppWidgets *app) {
    GDateTime *now = g_date_time_new_now_local();
    guint today_year = g_date_time_get_year(now);
    guint today_month = g_date_time_get_month(now) - 1; // Adjust for zero-based index
    guint today_day = g_date_time_get_day_of_month(now);
    g_date_time_unref(now);

    // Update the current year, month, and selected day
    app->current_year = today_year;
    app->current_month = today_month;
    app->selected_day = today_day;

    // Update the spin button for the year
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(app->spin_year), app->current_year);

    // Update the combo box for the month
    gtk_combo_box_set_active(GTK_COMBO_BOX(app->combo_month), app->current_month);

    // Redraw the calendar
    gtk_widget_queue_draw(app->drawing_area);

    // Mark dates with entries
    mark_dates_with_entries(app);
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    AppWidgets *app = g_slice_new(AppWidgets);

    // Get the current date
    GDateTime *now = g_date_time_new_now_local();
    app->current_year = g_date_time_get_year(now);
    app->current_month = g_date_time_get_month(now) - 1; // g_date_time_get_month() is 1-based
    app->selected_day = g_date_time_get_day_of_month(now);
    g_date_time_unref(now);

    app->diary_dir = g_build_filename(g_get_user_data_dir(), "diary_entries", NULL);
    g_mkdir_with_parents(app->diary_dir, 0755);
    app->marked_dates = g_hash_table_new(g_direct_hash, g_direct_equal);

    app->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(app->window), "Custom Calendar Widget");
    gtk_window_set_default_size(GTK_WINDOW(app->window), 500, 600);
    gtk_window_set_icon_name(GTK_WINDOW(app->window), "xfcalendar");

    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
    gtk_container_add(GTK_CONTAINER(app->window), vbox);

    GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

    app->spin_year = gtk_spin_button_new_with_range(1900, 2100, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(app->spin_year), app->current_year);
    gtk_box_pack_start(GTK_BOX(hbox), app->spin_year, FALSE, FALSE, 0);

    app->combo_month = gtk_combo_box_text_new();
    const gchar *months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    for (int i = 0; i < 12; i++) {
        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(app->combo_month), months[i]);
    }
    gtk_combo_box_set_active(GTK_COMBO_BOX(app->combo_month), app->current_month);
    gtk_box_pack_start(GTK_BOX(hbox), app->combo_month, FALSE, FALSE, 0);

    GtkWidget *current_day_button = gtk_button_new_with_label("Today");
    g_signal_connect(current_day_button, "clicked", G_CALLBACK(on_today_button_clicked), app);
    gtk_box_pack_start(GTK_BOX(hbox), current_day_button, FALSE, FALSE, 0);

    app->drawing_area = gtk_drawing_area_new();
    gtk_box_pack_start(GTK_BOX(vbox), app->drawing_area, TRUE, TRUE, 0);
    gtk_widget_set_size_request(app->drawing_area, 500, 350);
    g_signal_connect(app->drawing_area, "draw", G_CALLBACK(draw_calendar), app);
    g_signal_connect(app->drawing_area, "button-press-event", G_CALLBACK(on_day_selected), app);
    gtk_widget_add_events(app->drawing_area, GDK_BUTTON_PRESS_MASK);

    GtkWidget *text_label = gtk_label_new("Date Entry:");
    gtk_box_pack_start(GTK_BOX(vbox), text_label, FALSE, FALSE, 0);

    app->text_view = gtk_text_view_new();
    gtk_box_pack_start(GTK_BOX(vbox), app->text_view, TRUE, TRUE, 0);

    GtkWidget *hboxb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
    gtk_container_add(GTK_CONTAINER(vbox), hboxb);

    app->remove_button = gtk_button_new_with_label("Remove Entry");
    g_signal_connect(app->remove_button, "clicked", G_CALLBACK(on_remove_entry_clicked), app);
    gtk_box_pack_start(GTK_BOX(hboxb), app->remove_button, FALSE, FALSE, 0);

    app->save_button = gtk_button_new_with_label("Save Entry");
    gtk_box_pack_start(GTK_BOX(hboxb), app->save_button, FALSE, FALSE, 0);
    g_signal_connect(app->save_button, "clicked", G_CALLBACK(on_save_clicked), app);

    g_signal_connect(app->spin_year, "value-changed", G_CALLBACK(on_year_changed), app);
    g_signal_connect(app->combo_month, "changed", G_CALLBACK(on_month_changed), app);

    gtk_widget_show_all(app->window);
    g_signal_connect(app->window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    mark_dates_with_entries(app);

    gtk_main();

    g_hash_table_destroy(app->marked_dates);
    g_free(app->diary_dir);
    g_slice_free(AppWidgets, app);

    return 0;
}

Added a button to select today's date.
Added a label "Date entry" to inform about the text entry.
Added a button to remove an entry.
This application needs an adequate name but I still haven't decided.

Stealing from the poor to give to the rich!
bslit - Block Splitter Custom Calendar Widget + Diary

User avatar
rockedge
Site Admin
Posts: 6543
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2749 times
Been thanked: 2624 times
Contact:

Re: Gtkdialog Calendar

Post by rockedge »

@superhik new version compiled successfully!

Screenshot(15).jpg
Screenshot(15).jpg (46.73 KiB) Viewed 1236 times
User avatar
greengeek
Posts: 1384
Joined: Thu Jul 16, 2020 11:06 pm
Has thanked: 535 times
Been thanked: 192 times

Re: Gtkdialog Calendar

Post by greengeek »

superhik wrote: Thu Jul 11, 2024 1:43 pm

I took the advantage of Cairo and made a custom calendar widget.

Compiles with:

Code: Select all

 gcc -o calendar `pkg-config --cflags gtk+-3.0` calendar.c `pkg-config --libs gtk+-3.0` -Wall

@rockedge will you do the honor to test it first in KLV?

Is it possible to make a C utility available? Or is it necessary for each user to compile specifically for their target pup? (Using a cutdown Fossa64 9.5 here)
Cheers!

Post Reply

Return to “Programming”