Compare commits

..

7 Commits

Author SHA1 Message Date
leca c334c587b5 cargo fmt 2024-05-24 11:05:40 +03:00
leca 8086928d43 update icon & ui changes 2024-05-20 02:27:01 +03:00
leca 6e7bca2579 ui changes 2024-05-19 16:07:40 +03:00
leca 021a6c67ea add percentage in cards game 2024-05-18 02:01:48 +03:00
leca c67ae2834d update gitignore 2024-05-17 12:01:23 +03:00
leca 61410dc6f9 change logo 2024-05-17 02:22:52 +03:00
leca c6135a6a6b now marked as learning but without picture are not displayed 2024-05-17 00:33:26 +03:00
31 changed files with 599 additions and 1084 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ resources/gschemas.compiled
learn-hieroglyph.AppImage learn-hieroglyph.AppImage
*.AppImage* *.AppImage*
AppDir/usr/lib AppDir/usr/lib
package

BIN
AppDir/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 30 KiB

89
assets/card_icon.svg Normal file
View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="90.163986mm"
height="112.68744mm"
viewBox="0 0 90.163986 112.68744"
version="1.1"
id="svg1"
sodipodi:docname="card_icon.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.8971354"
inkscape:cx="128.35141"
inkscape:cy="200.8291"
inkscape:window-width="1920"
inkscape:window-height="1014"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g12"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Japanese card"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-51.274923,-70.345579)">
<path
id="rect10"
style="fill:#929292;fill-opacity:1;stroke:none;stroke-width:4.89601;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:label="card"
d="m 94.947693,70.345577 c -3.783115,0 -6.829041,2.837666 -6.829041,6.362919 v 10.504268 h 12.096418 c 5.00742,0 9.2754,3.87563 9.2754,8.810832 v 65.246664 h 25.11992 c 3.78311,0 6.82852,-2.83767 6.82852,-6.36292 V 76.708496 c 0,-3.525253 -3.04541,-6.362919 -6.82852,-6.362919 z m -6.829041,21.761979 v 62.799784 c 0,3.52525 3.045926,6.36292 6.829041,6.36292 h 9.647987 V 96.023596 c 0,-2.115297 -1.82179,-3.91604 -4.38061,-3.91604 z" />
<path
id="text1"
style="font-size:50.4312px;fill:#ff6600;stroke:none;stroke-width:0.588;stroke-linecap:round;fill-opacity:1;stroke-dasharray:none"
d="M 113.79204 94.128623 L 113.79204 110.51884 C 113.79204 113.58025 112.83421 118.83754 109.48997 124.07925 L 109.48997 130.21273 C 113.52372 125.47929 115.26381 120.64343 115.80897 117.83157 C 116.81759 122.72339 121.75994 134.32259 136.38497 139.87002 C 136.93972 138.81096 138.15001 137.24746 138.95691 136.39013 C 121.4573 130.1871 117.87654 116.26778 117.87654 110.46819 L 117.87654 94.128623 L 115.85961 94.128623 L 113.79204 94.128623 z M 132.6529 103.55957 C 130.93824 107.99751 127.8116 114.04902 125.29004 117.78093 L 128.46711 119.29401 C 131.08953 115.66297 134.31723 109.91344 136.73792 105.17291 L 132.6529 103.55957 z M 100.98248 103.66034 C 100.22602 109.2582 98.460574 114.8057 94.375651 117.83157 L 97.654004 120.05056 C 101.89417 116.81088 103.64815 111.14026 104.5957 105.46333 L 104.5957 104.43084 L 100.98248 103.66034 z M 104.5957 129.89853 C 101.741 132.5164 98.055253 134.89267 93.316801 136.69243 C 94.1237 137.54976 95.384426 139.06312 95.888737 139.87002 C 99.321538 138.4558 102.19275 136.73547 104.5957 134.87187 L 104.5957 129.89853 z " />
</g>
<g
inkscape:groupmode="layer"
id="g12"
inkscape:label="English card"
style="display:inline"
transform="translate(-51.274923,-70.345579)">
<g
id="rect12"
inkscape:label="card">
<path
style="color:#000000;fill:#929292;-inkscape-stroke:none"
d="m 60.551661,89.65992 h 39.662799 c 3.78312,0 6.82874,2.838023 6.82874,6.36328 v 78.19853 c 0,3.52526 -3.04562,6.36328 -6.82874,6.36328 H 60.551661 c -3.783118,0 -6.828734,-2.83802 -6.828734,-6.36328 V 96.0232 c 0,-3.525257 3.045616,-6.36328 6.828734,-6.36328 z"
id="path1" />
</g>
<text
xml:space="preserve"
style="font-size:27.469px;display:none;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.3;stroke-linejoin:miter;stroke-dasharray:0.15, 0.15;stroke-dashoffset:0;stroke-opacity:1"
x="56.103771"
y="143.9433"
id="text19"><tspan
sodipodi:role="line"
id="tspan19"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.3;stroke-dasharray:0.15, 0.15;stroke-dashoffset:0;stroke-opacity:1"
x="56.103771"
y="143.9433">Fire</tspan></text>
<path
id="path2"
style="fill:#ff6600;stroke-width:0.587999;stroke-linecap:round"
d="m 96.046768,147.46361 c -3e-6,7.95179 -6.446204,14.39799 -14.397995,14.39799 -7.951791,0 -15.221495,-1.71232 -18.534078,-10.28789 0.325733,-2.68065 -1.610862,-8.24352 5.767352,-20.98554 1.975724,-3.68972 2.354248,-4.20972 4.504133,-10.60172 0.686189,-2.04016 1.199385,-3.09942 1.326455,-9.59185 20.033003,10.33218 4.428156,25.36404 8.568935,28.30226 2.448888,1.73769 4.428078,0.30331 5.512508,-0.90019 1.17534,-1.30438 2.056525,-5.09313 1.654658,-7.07018 4.136948,4.21622 5.598033,14.24733 5.598032,16.73712 z"
sodipodi:nodetypes="ssccscsscs" />
<path
id="path3"
style="fill:#ff9f00;fill-opacity:1;stroke-width:0.385198;stroke-linecap:round"
d="m 91.054159,152.69252 c -2.037,4.79443 -5.547824,9.11832 -10.757044,9.11832 -5.209221,0 -9.971606,-1.12174 -12.141681,-6.7396 0.213388,-1.75609 -3.495907,-5.53979 1.337563,-13.88709 1.294298,-2.41714 1.472536,-2.96699 3.438785,-6.94519 0.624791,-1.26411 4.551264,-7.95768 4.634507,-12.21087 5.212751,4.93313 3.721343,10.03235 3.402984,13.38327 -0.372277,3.91844 -0.768862,10.45791 0.693336,11.49546 1.604268,1.13836 4.146843,0.9302 5.095748,0.45494 1.312356,-0.65727 3.610152,-5.4413 3.346889,-6.73647 2.710116,2.76205 1.71597,10.26182 0.948913,12.06723 z"
sodipodi:nodetypes="ssccscssscs" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

326
assets/hrk.svg Normal file
View File

@ -0,0 +1,326 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="170.11633mm"
height="159.7771mm"
viewBox="0 0 170.11633 159.7771"
version="1.1"
id="svg1"
inkscape:export-filename="hrk.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="ArrowWide"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Wide arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:butt"
d="M 3,-3 0,0 3,3"
transform="rotate(180,0.125,0)"
sodipodi:nodetypes="ccc"
id="path93" />
</marker>
<marker
style="overflow:visible"
id="ArrowWideRounded"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide, rounded arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:round"
d="m -2.75,3 3,-3 -3,-3"
sodipodi:nodetypes="ccc"
id="path2" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-15.94387,-32.544143)">
<circle
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:1.56449;stroke-linecap:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#ArrowWide);marker-mid:url(#ArrowWideRounded);marker-end:url(#ArrowWideRounded)"
id="path1"
cx="95.936882"
cy="130.48886"
r="56.356659" />
<g
id="g67"
inkscape:transform-center-x="60.401617"
inkscape:transform-center-y="11.970845"
transform="rotate(20.524935,98.801223,133.05533)"
style="display:none">
<path
style="fill:none;stroke:#0000ff;stroke-width:0.259914;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="M 47.784653,78.293317 V 242.59901"
id="path63" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.259914;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="m 47.784653,242.59901 c 0,0 0,0 0,0"
id="path64" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.259914;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="M 47.784653,78.293317 V 242.59901"
id="path65" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.259914;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="m 46.928756,183.2203 1.711795,1.71179 m 0,-1.71179 -1.711795,1.71179"
id="path66" />
<g
x="0"
y="0"
id="g63"
transform="matrix(0.25991425,0,0,0.25991425,55.181812,240.53269)">
<rect
style="fill:#333333;fill-opacity:0.5;stroke-width:0"
x="-25.440008"
y="-7.3800001"
width="56.88002"
height="13.38"
id="rect63" />
<text
xml:space="preserve"
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.55906;stroke-dasharray:7.55906, 30.2362;stroke-dashoffset:0;stroke-opacity:1"
x="2"
y="2"
id="text63"><tspan
sodipodi:role="line"
style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;text-align:center;letter-spacing:0;word-spacing:0;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan63"
x="2"
y="2">164.31 mm</tspan></text>
</g>
<g
x="0"
y="0"
id="g66"
transform="matrix(0.25991425,0,0,0.25991425,47.402579,248.33142)">
<rect
style="fill:#337f33;fill-opacity:0.5;stroke-width:0"
x="-12.840007"
y="-7.3899999"
width="31.680014"
height="13.39"
id="rect66" />
<text
xml:space="preserve"
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.55906;stroke-dasharray:7.55906, 30.2362;stroke-dashoffset:0;stroke-opacity:1"
x="2"
y="2"
id="text66"><tspan
sodipodi:role="line"
style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;text-align:center;letter-spacing:0;word-spacing:0;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan66"
x="2"
y="2">0.00 °</tspan></text>
</g>
</g>
<g
id="g71"
inkscape:transform-center-x="30.565858"
inkscape:transform-center-y="-19.827309"
transform="rotate(20.524935,98.801223,133.05533)"
style="display:none">
<path
style="fill:none;stroke:#0000ff;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="M 98.648347,133.19544 71.219492,63.238599"
id="path68" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="M 71.219492,63.238599 C 17.367689,84.352951 6.5661811,155.84514 51.77649,191.92644"
id="path69" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="m 98.648347,133.19544 -46.871857,58.731"
id="path70" />
<g
x="0"
y="0"
id="g68"
transform="matrix(0.26458333,0,0,0.26458333,78.809064,61.127224)">
<rect
style="fill:#333333;fill-opacity:0.5;stroke-width:0"
x="-22.805008"
y="-7.3200002"
width="51.610016"
height="13.32"
id="rect68" />
<text
xml:space="preserve"
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.55906;stroke-dasharray:7.55906, 30.2362;stroke-dashoffset:0;stroke-opacity:1"
x="2"
y="2"
id="text68"><tspan
sodipodi:role="line"
style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;text-align:center;letter-spacing:0;word-spacing:0;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan68"
x="2"
y="2">75.14 mm</tspan></text>
</g>
<g
x="0"
y="0"
id="g70"
transform="matrix(0.26458333,0,0,0.26458333,23.907844,122.51363)">
<rect
style="fill:#337f33;fill-opacity:0.5;stroke-width:0"
x="-18.360012"
y="-7.3899999"
width="42.720024"
height="13.39"
id="rect67" />
<text
xml:space="preserve"
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.55906;stroke-dasharray:7.55906, 30.2362;stroke-dashoffset:0;stroke-opacity:1"
x="2"
y="2"
id="text67"><tspan
sodipodi:role="line"
style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;text-align:center;letter-spacing:0;word-spacing:0;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan67"
x="2"
y="2">120.00 °</tspan></text>
</g>
</g>
<g
id="g76"
inkscape:transform-center-x="-8.5806806"
inkscape:transform-center-y="42.094739"
transform="rotate(20.524935,98.801223,133.05533)"
style="display:none">
<path
style="fill:none;stroke:#0000ff;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="M 98.954166,133.08542 177.8,144.99167"
id="path72" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="m 177.8,144.99167 c -9.16635,60.70161 -80.611317,88.71191 -128.590655,50.4145"
id="path73" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="M 98.954166,133.08542 49.209345,195.40617"
id="path74" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.5"
d="m 165.9544,142.4632 1.74255,1.74254 m 0,-1.74254 -1.74255,1.74254"
id="path75" />
<g
x="0"
y="0"
id="g72"
transform="matrix(0.26458333,0,0,0.26458333,185.38957,142.88823)">
<rect
style="fill:#333333;fill-opacity:0.5;stroke-width:0"
x="-22.805008"
y="-7.3800001"
width="51.610016"
height="13.38"
id="rect72" />
<text
xml:space="preserve"
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.55906;stroke-dasharray:7.55906, 30.2362;stroke-dashoffset:0;stroke-opacity:1"
x="2"
y="2"
id="text72"><tspan
sodipodi:role="line"
style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;text-align:center;letter-spacing:0;word-spacing:0;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan72"
x="2"
y="2">79.74 mm</tspan></text>
</g>
<g
x="0"
y="0"
id="g75"
transform="matrix(0.26458333,0,0,0.26458333,127.68251,207.86727)">
<rect
style="fill:#337f33;fill-opacity:0.5;stroke-width:0"
x="-20.215014"
y="-7.3899999"
width="46.430031"
height="13.39"
id="rect71" />
<text
xml:space="preserve"
style="fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:7.55906;stroke-dasharray:7.55906, 30.2362;stroke-dashoffset:0;stroke-opacity:1"
x="2"
y="2"
id="text71"><tspan
sodipodi:role="line"
style="font-style:normal;font-weight:normal;font-size:10px;line-height:125%;text-align:center;letter-spacing:0;word-spacing:0;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan71"
x="2"
y="2">-120.01 °</tspan></text>
</g>
</g>
<text
xml:space="preserve"
style="font-size:56.5097px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.77984;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
x="15.879345"
y="201.85991"
id="text88"
transform="scale(1.0601061,0.9433018)"><tspan
sodipodi:role="line"
id="tspan88"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.77984;stroke-dasharray:none"
x="15.879345"
y="201.85991">A</tspan></text>
<text
xml:space="preserve"
style="font-size:56.5097px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.77984;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
x="123.53018"
y="199.27646"
id="text88-5"
transform="scale(1.0601061,0.9433018)"><tspan
sodipodi:role="line"
id="tspan88-3"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.77984;stroke-dasharray:none"
x="123.53018"
y="199.27646">あ</tspan></text>
<text
xml:space="preserve"
style="font-size:56.5097px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.77984;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
x="61.696327"
y="76.469696"
id="text88-5-9"
transform="scale(1.0601061,0.9433018)"><tspan
sodipodi:role="line"
id="tspan88-3-1"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.77984;stroke-dasharray:none"
x="61.696327"
y="76.469696">ア</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 34 KiB

BIN
logo.kra Normal file

Binary file not shown.

View File

@ -5,19 +5,39 @@
<child> <child>
<object class="GtkBox" id="content"> <object class="GtkBox" id="content">
<property name="orientation">horizontal</property> <property name="orientation">horizontal</property>
<property name="orientation">horizontal</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<child> <child>
<object class="GtkButton" id="edit_button"> <object class="GtkButton" id="edit_button">
<property name="label">Edit cards</property> <property name="label">Edit cards</property>
<property name="valign">GTK_ALIGN_FILL</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<property name="margin-top">375</property>
<property name="margin-bottom">375</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkButton" id="start_button"> <object class="GtkButton" id="start_button">
<property name="label">start game</property> <property name="label">start game</property>
<property name="valign">GTK_ALIGN_FILL</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<property name="margin-top">375</property>
<property name="margin-bottom">375</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkButton" id="back_button"> <object class="GtkButton" id="back_button">
<property name="label">go back</property> <property name="label">go back</property>
<property name="valign">GTK_ALIGN_FILL</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<property name="margin-top">375</property>
<property name="margin-bottom">375</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
</object> </object>
</child> </child>
</object> </object>

View File

@ -2,23 +2,74 @@
<interface> <interface>
<template class="MenuScene" parent="GtkApplicationWindow"> <template class="MenuScene" parent="GtkApplicationWindow">
<property name="title">Menu</property> <property name="title">Menu</property>
<property name="height-request">1000</property>
<property name="width-request">1000</property>
<child> <child>
<object class="GtkBox" id="content"> <object class="GtkBox" id="content">
<property name="orientation">horizontal</property> <property name="orientation">horizontal</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<child> <child>
<object class="GtkButton" id="hiragana_and_katakana"> <object class="GtkButton" id="hiragana_and_katakana">
<property name="label">Practice hiragana and katakana</property> <property name="valign">GTK_ALIGN_FILL</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<property name="margin-top">375</property>
<property name="margin-bottom">375</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<style> <style>
<class name="hiragana_and_katakana" /> <class name="hiragana_and_katakana" />
</style> </style>
<child>
<object class="GtkBox">
<property name="homogeneous">true</property>
<child>
<object class="GtkImage">
<property name="file">assets/hrk.svg</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Practice hiragana and katakana</property>
<property name="width-chars">24</property>
<property name="wrap">true</property>
<property name="wrap-mode">PANGO_WRAP_WORD</property>
<property name="natural-wrap-mode">GTK_NATURAL_WRAP_WORD</property>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkButton" id="memory_cards"> <object class="GtkButton" id="memory_cards">
<property name="label">Practice vocabulary with memory cards</property> <property name="valign">GTK_ALIGN_FILL</property>
<property name="halign">GTK_ALIGN_CENTER</property>
<property name="margin-top">375</property>
<property name="margin-bottom">375</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<style> <style>
<class name="memory_cards"/> <class name="memory_cards" />
</style> </style>
<child>
<object class="GtkBox">
<property name="homogeneous">true</property>
<child>
<object class="GtkImage">
<property name="file">assets/card_icon.svg</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Practice vocabulary with memory cards</property>
<property name="width-chars">24</property>
<property name="wrap">true</property>
<property name="wrap-mode">PANGO_WRAP_WORD</property>
<property name="natural-wrap-mode">GTK_NATURAL_WRAP_WORD</property>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>

View File

@ -4,13 +4,23 @@ pub struct Card {
hieroglyph: Option<String>, hieroglyph: Option<String>,
reading: Option<String>, reading: Option<String>,
translation: Option<String>, translation: Option<String>,
is_learning: Option<bool> is_learning: Option<bool>,
} }
impl Card { impl Card {
pub fn new(image_path: Option<String>, hieroglyph: Option<String>, reading: Option<String>, translation: Option<String>, is_learning: Option<bool>) -> Card { pub fn new(
image_path: Option<String>,
hieroglyph: Option<String>,
reading: Option<String>,
translation: Option<String>,
is_learning: Option<bool>,
) -> Card {
Card { Card {
image_path, hieroglyph, reading, translation, is_learning image_path,
hieroglyph,
reading,
translation,
is_learning,
} }
} }
@ -33,5 +43,4 @@ impl Card {
pub fn is_learning(&self) -> Option<bool> { pub fn is_learning(&self) -> Option<bool> {
self.is_learning.clone() self.is_learning.clone()
} }
} }

View File

@ -27,4 +27,4 @@ impl ObjectSubclass for CardGObject {
} }
#[glib::derived_properties] #[glib::derived_properties]
impl ObjectImpl for CardGObject {} impl ObjectImpl for CardGObject {}

View File

@ -1,7 +1,7 @@
mod imp; mod imp;
use crate::card::Card;
use glib::Object; use glib::Object;
use gtk::glib; use gtk::glib;
use crate::card::Card;
glib::wrapper! { glib::wrapper! {
pub struct CardGObject(ObjectSubclass<imp::CardGObject>); pub struct CardGObject(ObjectSubclass<imp::CardGObject>);
@ -10,17 +10,14 @@ glib::wrapper! {
impl CardGObject { impl CardGObject {
pub fn new(c: Option<Card>) -> Self { pub fn new(c: Option<Card>) -> Self {
match c { match c {
Some(c) => { Some(c) => Object::builder()
Object::builder()
.property("imagepath", c.image_path().unwrap()) .property("imagepath", c.image_path().unwrap())
.property("hieroglyph", c.hieroglyph().unwrap()) .property("hieroglyph", c.hieroglyph().unwrap())
.property("reading", c.reading().unwrap()) .property("reading", c.reading().unwrap())
.property("translation", c.translation().unwrap()) .property("translation", c.translation().unwrap())
.property("islearning", c.is_learning().unwrap()) .property("islearning", c.is_learning().unwrap())
.build() .build(),
}, None => Object::builder().build(),
None => Object::builder().build()
} }
} }
} }

View File

@ -20,11 +20,14 @@ pub fn init() {
}; };
match fs::create_dir_all(&program_home_path) { match fs::create_dir_all(&program_home_path) {
Ok(_) => {}, Ok(_) => {}
Err(error) => match error.kind() { Err(error) => match error.kind() {
ErrorKind::AlreadyExists => {}, ErrorKind::AlreadyExists => {}
_ => panic!("Could not create app home folder: {}", &program_home_path.to_str().unwrap()) _ => panic!(
} "Could not create app home folder: {}",
&program_home_path.to_str().unwrap()
),
},
}; };
let mut binding = PROGRAM_HOME_PATH.write().unwrap(); let mut binding = PROGRAM_HOME_PATH.write().unwrap();
@ -40,17 +43,21 @@ pub fn init() {
let connection = Connection::open(db_path).unwrap(); let connection = Connection::open(db_path).unwrap();
connection.execute("CREATE TABLE IF NOT EXISTS cards ( connection
.execute(
"CREATE TABLE IF NOT EXISTS cards (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
imagename CHAR(64), imagename CHAR(64),
hieroglyph VARCHAR(64), hieroglyph VARCHAR(64),
reading VARCHAR(64), reading VARCHAR(64),
translation VARCHAR(128), translation VARCHAR(128),
is_learning BOOLEAN DEFAULT FALSE is_learning BOOLEAN DEFAULT FALSE
)",()).unwrap(); )",
(),
)
.unwrap();
} }
pub fn get_program_home_path() -> String { pub fn get_program_home_path() -> String {
(*PROGRAM_HOME_PATH.read().unwrap()).clone() (*PROGRAM_HOME_PATH.read().unwrap()).clone()
} }

View File

@ -1,5 +1,5 @@
use rusqlite::Connection;
use core::panic; use core::panic;
use rusqlite::Connection;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::{ErrorKind, Write}; use std::io::{ErrorKind, Write};
@ -48,7 +48,7 @@ async fn download_dictionary(path: String) {
let mut file = match File::create(&path) { let mut file = match File::create(&path) {
Err(e) => panic!("Could not create dictionary file. {}", e), Err(e) => panic!("Could not create dictionary file. {}", e),
Ok(file) => file Ok(file) => file,
}; };
let content = response.unwrap().bytes().await.unwrap(); let content = response.unwrap().bytes().await.unwrap();
file.write_all(&content).unwrap(); file.write_all(&content).unwrap();
@ -72,7 +72,7 @@ fn read_and_parse(path: &String) -> Vec<DictionaryEntry> {
_ => { _ => {
println!("Unexpected error. Can't load dictionary. Assuming it's empty"); println!("Unexpected error. Can't load dictionary. Assuming it's empty");
return Vec::new(); return Vec::new();
}, }
}, },
}; };

View File

@ -1,12 +1,12 @@
#![windows_subsystem = "windows"] #![windows_subsystem = "windows"]
mod card;
mod card_gobject;
mod db; mod db;
mod dictionary;
mod game; mod game;
mod ui; mod ui;
mod widgets; mod widgets;
mod dictionary;
mod card;
mod card_gobject;
use crate::ui::menu::MenuScene; use crate::ui::menu::MenuScene;
@ -192,4 +192,4 @@ fn connect_close_requrest<W: IsA<Window>>(app: &Application, w: &W) {
true true
}), }),
); );
} }

View File

@ -297,20 +297,19 @@ async fn new_card_setup<W: IsA<gtk::Window>>(window: Rc<W>) {
let conn = Connection::open(get_db_path()).unwrap(); let conn = Connection::open(get_db_path()).unwrap();
conn.execute("INSERT OR REPLACE INTO cards ( id, conn.execute("INSERT OR REPLACE INTO cards ( id,
imagename, imagename,
hieroglyph, hieroglyph,
reading, reading,
translation, translation,
is_learning is_learning
) VALUES ( ) VALUES (
(SELECT id FROM cards WHERE hieroglyph = ?2), (SELECT id FROM cards WHERE hieroglyph = ?2),
?1, ?1,
?2, ?2,
?3, ?3,
?4, ?4,
(SELECT is_learning FROM cards WHERE hieroglyph = ?2 OR TRUE (SELECT is_learning FROM cards WHERE hieroglyph = ?2 OR TRUE)
) )", (&new_filename, &hieroglyph, &reading, &translation)).unwrap();
)", (&new_filename, &hieroglyph, &reading, &translation)).unwrap();
w.close(); w.close();
}), }),
); );

View File

@ -91,7 +91,7 @@ impl MemoryCardsGameScene {
fn generate_card() -> Option<CardDisplay> { fn generate_card() -> Option<CardDisplay> {
let connection = Connection::open(get_db_path()).unwrap(); let connection = Connection::open(get_db_path()).unwrap();
let mut stmt = connection.prepare("SELECT imagename, hieroglyph, reading, translation FROM cards WHERE is_learning = TRUE ORDER BY RANDOM() LIMIT 1").unwrap(); let mut stmt = connection.prepare("SELECT imagename, hieroglyph, reading, translation FROM cards WHERE is_learning = TRUE AND imagename != '' ORDER BY RANDOM() LIMIT 1").unwrap();
let random_card_iter = stmt let random_card_iter = stmt
.query_map((), |row| { .query_map((), |row| {
Ok(Card::new( Ok(Card::new(

View File

@ -22,9 +22,11 @@ impl MemoryCardsGameScene {
pub fn update_stats(&self) { pub fn update_stats(&self) {
self.imp().stats_label.set_text(&format!( self.imp().stats_label.set_text(&format!(
"Correct|Incorrect: {}|{}", "Correct|Incorrect: {}|{} ({:.2}%)",
self.imp().correct.borrow(), self.imp().correct.borrow(),
self.imp().incorrect.borrow() self.imp().incorrect.borrow(),
100.0 * f64::from(*self.imp().correct.borrow() as i32)
/ f64::from((*self.imp().incorrect.borrow() + *self.imp().correct.borrow()) as i32)
)); ));
} }

View File

@ -1,4 +1,4 @@
pub mod edit; pub mod edit;
pub mod game; pub mod game;
pub mod new;
pub mod setup; pub mod setup;
pub mod new;

View File

@ -40,7 +40,6 @@ impl ObjectImpl for MemoryCardsNewScene {
} }
} }
impl WidgetImpl for MemoryCardsNewScene {} impl WidgetImpl for MemoryCardsNewScene {}
impl WindowImpl for MemoryCardsNewScene {} impl WindowImpl for MemoryCardsNewScene {}

View File

@ -2,7 +2,10 @@ mod imp;
use glib::Object; use glib::Object;
use gtk::{ use gtk::{
gio, glib::{self, subclass::types::ObjectSubclassIsExt}, prelude::*, Application, Button, Entry, Picture gio,
glib::{self, subclass::types::ObjectSubclassIsExt},
prelude::*,
Application, Button, Entry, Picture,
}; };
glib::wrapper! { glib::wrapper! {

View File

@ -30,7 +30,7 @@ impl ObjectSubclass for MemoryCardsSetupScene {
impl ObjectImpl for MemoryCardsSetupScene { impl ObjectImpl for MemoryCardsSetupScene {
fn constructed(&self) { fn constructed(&self) {
self.parent_constructed(); self.parent_constructed();
} }
} }

View File

@ -1,7 +1,11 @@
mod imp; mod imp;
use glib::Object; use glib::Object;
use gtk::{gio, glib::{self, subclass::types::ObjectSubclassIsExt}, Application, Button}; use gtk::{
gio,
glib::{self, subclass::types::ObjectSubclassIsExt},
Application, Button,
};
glib::wrapper! { glib::wrapper! {
pub struct MemoryCardsSetupScene(ObjectSubclass<imp::MemoryCardsSetupScene>) pub struct MemoryCardsSetupScene(ObjectSubclass<imp::MemoryCardsSetupScene>)
@ -14,7 +18,7 @@ impl MemoryCardsSetupScene {
pub fn new(app: &Application) -> Self { pub fn new(app: &Application) -> Self {
Object::builder().property("application", app).build() Object::builder().property("application", app).build()
} }
pub fn get_edit_button(&self) -> &Button { pub fn get_edit_button(&self) -> &Button {
self.imp().edit_button.as_ref() self.imp().edit_button.as_ref()
} }

View File

@ -60,12 +60,11 @@ impl ObjectImpl for GuessingScene {
let answer_entry_binding = &self.answer_entry.get(); let answer_entry_binding = &self.answer_entry.get();
let stats_label_binding = &self.stats_label.get(); let stats_label_binding = &self.stats_label.get();
/* /*
"Memory management when writing a gtk-rs app can be a bit tricky." "Memory management when writing a gtk-rs app can be a bit tricky."
(c) https://gtk-rs.org/gtk4-rs/stable/latest/book/g_object_memory_management.html (c) https://gtk-rs.org/gtk4-rs/stable/latest/book/g_object_memory_management.html
*/ */
let iteration = closure_local!(@strong self_binding, let iteration = closure_local!(@strong self_binding,

View File

@ -2,11 +2,15 @@ mod imp;
use std::ops::Deref; use std::ops::Deref;
use glib::Object;
use gtk::{gio::{self, prelude::*}, glib::{self, subclass::types::ObjectSubclassIsExt}, Application, Button};
use gtk::gio::Settings;
use rand::Rng;
use crate::{game::*, APP_ID}; use crate::{game::*, APP_ID};
use glib::Object;
use gtk::gio::Settings;
use gtk::{
gio::{self, prelude::*},
glib::{self, subclass::types::ObjectSubclassIsExt},
Application, Button,
};
use rand::Rng;
glib::wrapper! { glib::wrapper! {
pub struct GuessingScene(ObjectSubclass<imp::GuessingScene>) pub struct GuessingScene(ObjectSubclass<imp::GuessingScene>)
@ -66,9 +70,11 @@ impl GuessingScene {
&self.imp().question.borrow(), &self.imp().question.borrow(),
); );
let binding = generate_question_text(&self.imp().question.borrow(), self.imp().exact_kana.borrow().deref()); let binding = generate_question_text(
&self.imp().question.borrow(),
self.imp().exact_kana.borrow().deref(),
);
let text: &str = &(binding.as_str()); let text: &str = &(binding.as_str());
self.imp().question_label.set_label(text); self.imp().question_label.set_label(text);
} }
} }

View File

@ -1,7 +1,11 @@
mod imp; mod imp;
use glib::Object; use glib::Object;
use gtk::{gio, glib::{self, subclass::types::ObjectSubclassIsExt}, Application, Button}; use gtk::{
gio,
glib::{self, subclass::types::ObjectSubclassIsExt},
Application, Button,
};
glib::wrapper! { glib::wrapper! {
pub struct GuessingSetupScene(ObjectSubclass<imp::GuessingSetupScene>) pub struct GuessingSetupScene(ObjectSubclass<imp::GuessingSetupScene>)

View File

@ -1,7 +1,11 @@
mod imp; mod imp;
use glib::Object; use glib::Object;
use gtk::{gio, glib::{self, subclass::types::ObjectSubclassIsExt}, Application, Button}; use gtk::{
gio,
glib::{self, subclass::types::ObjectSubclassIsExt},
Application, Button,
};
glib::wrapper! { glib::wrapper! {
pub struct MenuScene(ObjectSubclass<imp::MenuScene>) pub struct MenuScene(ObjectSubclass<imp::MenuScene>)
@ -22,5 +26,4 @@ impl MenuScene {
pub fn get_memory_cards_button(&self) -> &Button { pub fn get_memory_cards_button(&self) -> &Button {
self.imp().memory_cards.as_ref() self.imp().memory_cards.as_ref()
} }
} }

View File

@ -3,7 +3,7 @@ use std::cell::RefCell;
use glib::subclass::InitializingObject; use glib::subclass::InitializingObject;
use glib::Properties; use glib::Properties;
use gtk::subclass::prelude::*; use gtk::subclass::prelude::*;
use gtk::{glib, prelude::*, BoxLayout, CompositeTemplate, Entry, Label, Image}; use gtk::{glib, prelude::*, BoxLayout, CompositeTemplate, Entry, Image, Label};
#[derive(CompositeTemplate, Properties, Default)] #[derive(CompositeTemplate, Properties, Default)]
#[properties(wrapper_type = super::CardDisplay)] #[properties(wrapper_type = super::CardDisplay)]

View File

@ -1,9 +1,12 @@
mod imp; mod imp;
use glib::Object; use glib::Object;
use gtk::{gio, glib::{self, subclass::types::ObjectSubclassIsExt}, prelude::*, Entry, Image}; use gtk::{
gio,
glib::{self, subclass::types::ObjectSubclassIsExt},
prelude::*,
Entry, Image,
};
glib::wrapper! { glib::wrapper! {
pub struct CardDisplay(ObjectSubclass<imp::CardDisplay>) pub struct CardDisplay(ObjectSubclass<imp::CardDisplay>)
@ -13,7 +16,12 @@ glib::wrapper! {
} }
impl CardDisplay { impl CardDisplay {
pub fn new(image_path: &String, hieroglyph: &String, reading: Option<&String>, translation: &String) -> Self { pub fn new(
image_path: &String,
hieroglyph: &String,
reading: Option<&String>,
translation: &String,
) -> Self {
Object::builder() Object::builder()
.property("imagepath", image_path) .property("imagepath", image_path)
.property("translation", translation) .property("translation", translation)

View File

@ -5,7 +5,6 @@ use glib::Properties;
use gtk::subclass::prelude::*; use gtk::subclass::prelude::*;
use gtk::{glib, prelude::*, Button, CompositeTemplate, Image, Label, Switch}; use gtk::{glib, prelude::*, Button, CompositeTemplate, Image, Label, Switch};
#[derive(CompositeTemplate, Properties, Default)] #[derive(CompositeTemplate, Properties, Default)]
#[properties(wrapper_type = super::CardEntry)] #[properties(wrapper_type = super::CardEntry)]
#[template(resource = "/org/foxarmy/learn-hieroglyph/widgets/card_entry/template.ui.xml")] #[template(resource = "/org/foxarmy/learn-hieroglyph/widgets/card_entry/template.ui.xml")]

View File

@ -1,3 +1,3 @@
pub mod labled_switch; pub mod card_display;
pub mod card_entry; pub mod card_entry;
pub mod card_display; pub mod labled_switch;