Compare commits

..

41 Commits

Author SHA1 Message Date
2c355ec966 Resolve diverged APIs to keep string input working 2019-08-05 17:37:08 +00:00
a19bbdc870 Remove unused assignment 2019-08-05 14:36:50 +00:00
8e0b4f05f8 Don't check for touches on hidden keys 2019-08-05 14:36:50 +00:00
1010b916ef Tidy up keymap generation, add bounds check 2019-08-05 14:36:50 +00:00
c475ed6619 Add checks for new purposes 2019-08-05 14:36:50 +00:00
687b260e29 Add keyboard information for new purposes 2019-08-05 14:36:50 +00:00
ecc46733da Add an initial URL keyboard and support for text macros
Text associated with a symbol on a key is sent using the keymap
associated with each keyboard, so the individual symbols need to be
defined in order to be usable in a text macro.
2019-08-05 14:36:50 +00:00
d6b59d16fd Merge branch 'keyboard-signal' into 'master'
gtk-keyboard: Remove unused signal connections

See merge request Librem5/squeekboard!120
2019-08-05 14:27:09 +00:00
a6e220a2ae Merge branch 'adjust-icon-scaling' into 'master'
Correct icon size for scaling

See merge request Librem5/squeekboard!121
2019-08-05 12:06:13 +00:00
593946779e Correct icon size for scaling 2019-08-05 13:21:01 +02:00
537ded4b58 Merge branch 'release-keys-when-focus-is-lost' into 'master'
Release pressed keys when dragging outside the keyboard

See merge request Librem5/squeekboard!119
2019-08-04 11:00:20 +00:00
25a6a00f0f Merge branch 'fix-key-press-checks' into 'master'
Use keyboard's coordinate system to check for presses

See merge request Librem5/squeekboard!118
2019-08-04 10:52:58 +00:00
8298a1412b gtk-keyboard: Remove unused signal connections 2019-08-04 10:23:57 +00:00
47eb25d07f Merge branch 'use-css-provider' into 'master'
Use CSS provider instead of custom classes

See merge request Librem5/squeekboard!108
2019-08-04 10:21:22 +00:00
0057c80b2e Release pressed keys when dragging outside the keyboard
If no keys are under the touch position when dragging then release all
existing pressed keys. This fixes the problem where the last pressed key
causes events to be sent while the touch position moves outside the
keyboard extent.
2019-08-02 15:31:18 +00:00
da88831689 Fix key rendering to only scale once 2019-08-02 17:04:16 +02:00
7b6c6e51b3 Fix background rendering 2019-08-02 17:04:16 +02:00
42b2b3b8f6 Replace the Eek theme support with GTK classes
This brings the appearance of the keyboard basically in line with what
was there before. The background and key borders still need to be fixed
and the text and icons should probably be drawn using the style context.
2019-08-02 17:04:16 +02:00
64680664e3 Use a CSS provider and style context instead of the old theme support 2019-08-02 17:04:16 +02:00
87dd9b4374 Remove references to the removed theme classes 2019-08-02 17:04:16 +02:00
c7d5e8d152 Remove theme classes for future replacement 2019-08-02 17:04:16 +02:00
4cd15c074e Merge branch 'fixes' into 'master'
Fixes

See merge request Librem5/squeekboard!115
2019-08-02 15:03:33 +00:00
9bfdabdf57 Merge branch 'textproperty' into 'master'
Removed text categories

See merge request Librem5/squeekboard!114
2019-08-02 14:36:41 +00:00
9375bc212b Use keyboard's coordinate system to check for presses 2019-08-02 14:05:36 +00:00
3829b52127 Merge branch 'center-keyboard' into 'master'
Center the keyboard horizontally

Closes #68

See merge request Librem5/squeekboard!104
2019-08-02 13:45:34 +00:00
f852cab0f9 Fix warnings, add gtk-doc strings 2019-08-02 12:49:15 +02:00
f53babcd68 Add gtk-doc style comment 2019-08-02 12:48:35 +02:00
016c1086e6 Center the keyboard horizontally
Also simplify individual key rendering to make the rendering model more
coherent.
2019-08-02 12:48:35 +02:00
f7dd4c84b1 renderer: Render label directly 2019-08-02 09:21:38 +00:00
c1c0cb6b31 Fix unused function 2019-08-01 20:30:57 +00:00
e5858bf698 context: Remove vestigial key-activated 2019-08-01 20:25:07 +00:00
b8389f6736 symbol: Simplify symbol storage 2019-08-01 20:25:01 +00:00
6c1c979414 section: Removed multiple rows in section, row/column in key 2019-08-01 20:10:59 +00:00
43df82355a EekKey: Remove column and row fields 2019-08-01 20:10:59 +00:00
d8b26040f9 symbolclass: Remove with surroundings
Collaterals: Enabled strict checking of initializers, fixed scripts generating keycode mappings.
2019-08-01 20:08:37 +00:00
bdf29bf57b symbol: forget serializing 2019-08-01 19:59:34 +00:00
24358c39a6 Merge branch 'font_size' into 'master'
fonts: Reset font size to a constant

See merge request Librem5/squeekboard!112
2019-08-01 17:25:38 +00:00
504285c08f fonts: Reset font size to a constant
The font size will only be affected by the scaling factor, and not by an attempt to fit the labels into buttons.

Left to do: adjust it based on CSS.
2019-08-01 17:25:38 +00:00
b7eb4026f6 Merge branch 'fix-tests' into 'master'
Use headless init functions to prevent test breakage

See merge request Librem5/squeekboard!109
2019-08-01 17:08:24 +00:00
ad5e4f58bb Remove use of xvfb to check that the tests run headless 2019-08-01 18:15:42 +02:00
9344a13bed Use headless init functions to prevent test breakage 2019-08-01 16:00:59 +02:00
50 changed files with 1067 additions and 5020 deletions

View File

@ -28,4 +28,4 @@ test:
dependencies: dependencies:
- build_meson - build_meson
script: script:
- xvfb-run -s -noreset ninja -C _build test - ninja -C _build test

View File

@ -0,0 +1,98 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline4" />
<key name="AD02" oref="outline4" />
<key name="AD03" oref="outline4" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline4" />
<key name="AC02" oref="outline4" />
<key name="AC03" oref="outline4" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AB01" oref="outline4" />
<key name="AB02" oref="outline4" />
<key name="AB03" oref="outline4" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="BKSP" oref="altline" />
<key name="AB04" oref="outline4" />
<key name="RTRN" oref="altline" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="altline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="48.39024" y="0.000000"/>
<point x="48.39024" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="120.5853" y="0.000000"/>
<point x="120.5853" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
</geometry>

View File

@ -0,0 +1,105 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline2" />
<key name="AD02" oref="outline2" />
<key name="AD03" oref="outline2" />
<key name="AD04" oref="outline2" />
<key name="AD05" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline2" />
<key name="AC02" oref="outline2" />
<key name="AC03" oref="outline2" />
<key name="AC04" oref="outline2" />
<key name="AC05" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AB01" oref="outline2" />
<key name="AB02" oref="outline2" />
<key name="AB03" oref="outline2" />
<key name="AB04" oref="outline2" />
<key name="AB05" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="BKSP" oref="altline" />
<key name="AB06" oref="outline2" />
<key name="SPCE" oref="spaceline" />
<key name="RTRN" oref="outline7" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="altline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="48.39024" y="0.000000"/>
<point x="48.39024" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="120.5853" y="0.000000"/>
<point x="120.5853" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
</geometry>

View File

@ -0,0 +1,126 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline2" />
<key name="AD02" oref="outline2" />
<key name="AD03" oref="outline2" />
<key name="AD04" oref="outline2" />
<key name="AD05" oref="outline2" />
<key name="AD06" oref="outline2" />
<key name="AD07" oref="outline2" />
<key name="AD08" oref="outline2" />
<key name="AD09" oref="outline2" />
<key name="AD10" oref="outline2" />
<key name="AE01" oref="outline6" />
<key name="AE02" oref="outline2" />
<key name="AE03" oref="outline6" />
<key name="AE04" oref="outline6" />
<key name="AE05" oref="outline6" />
<key name="AE06" oref="outline6" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline2" />
<key name="AC02" oref="outline2" />
<key name="AC03" oref="outline2" />
<key name="AC04" oref="outline2" />
<key name="AC05" oref="outline2" />
<key name="AC06" oref="outline2" />
<key name="AC07" oref="outline2" />
<key name="AC08" oref="outline2" />
<key name="AC09" oref="outline2" />
<key name="AC10" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="LFSH" oref="altline" />
<key name="AB01" oref="outline2" />
<key name="AB02" oref="outline2" />
<key name="AB03" oref="outline2" />
<key name="AB04" oref="outline2" />
<key name="AB05" oref="outline2" />
<key name="AB06" oref="outline2" />
<key name="AB07" oref="outline2" />
<key name="BKSP" oref="altline" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key keycode="0" name="ABC123" oref="altline" />
<key name="I149" oref="altline" />
<key name="SPCE" oref="spaceline" />
<key name="AB08" oref="outline2" />
<key name="RTRN" oref="outline7" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="altline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="48.39024" y="0.000000"/>
<point x="48.39024" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="150.5853" y="0.000000"/>
<point x="150.5853" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
</geometry>

View File

@ -90,11 +90,17 @@
longname="Telugu (Inscript)" language="te"/> longname="Telugu (Inscript)" language="te"/>
<!-- Common keyboards --> <!-- Common keyboards -->
<keyboard id="digits" name="digits"
geometry="digits" symbols="special/digits"
longname="Digits" language="all"/>
<keyboard id="number" name="number" <keyboard id="number" name="number"
geometry="number-keypad" symbols="special/number" geometry="number-keypad" symbols="special/number"
longname="Numeric keypad" language="all"/> longname="Numeric keypad" language="all"/>
<keyboard id="phone" name="phone" <keyboard id="phone" name="phone"
geometry="number-keypad" symbols="special/number" geometry="phone-keypad" symbols="special/phone"
longname="Phone keypad" language="all"/> longname="Phone keypad" language="all"/>
<keyboard id="url" name="url"
geometry="url" symbols="special/url"
longname="Uniform Resource Locator" language="all"/>
</keyboards> </keyboards>

View File

@ -0,0 +1,39 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<key name="AD01">
<symbol label="1">1</symbol>
</key>
<key name="AD02">
<symbol label="2">2</symbol>
</key>
<key name="AD03">
<symbol label="3">3</symbol>
</key>
<key name="AC01">
<symbol label="4">4</symbol>
</key>
<key name="AC02">
<symbol label="5">5</symbol>
</key>
<key name="AC03">
<symbol label="6">6</symbol>
</key>
<key name="AB01">
<symbol label="7">7</symbol>
</key>
<key name="AB02">
<symbol label="8">8</symbol>
</key>
<key name="AB03">
<symbol label="9">9</symbol>
</key>
<key name="AB04">
<symbol label="0">0</symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
</symbols>

View File

@ -10,10 +10,10 @@
<symbol label="3">3</symbol> <symbol label="3">3</symbol>
</key> </key>
<key name="AD04"> <key name="AD04">
<symbol label="(">parenleft</symbol> <symbol label=".">period</symbol>
</key> </key>
<key name="AD05"> <key name="AD05">
<symbol label=")">parenright</symbol> <symbol label=",">comma</symbol>
</key> </key>
<key name="AC01"> <key name="AC01">
<symbol label="4">4</symbol> <symbol label="4">4</symbol>
@ -25,7 +25,7 @@
<symbol label="6">6</symbol> <symbol label="6">6</symbol>
</key> </key>
<key name="AC04"> <key name="AC04">
<symbol label="#">numbersign</symbol> <symbol label="/">slash</symbol>
</key> </key>
<key name="AC05"> <key name="AC05">
<symbol label="*">asterisk</symbol> <symbol label="*">asterisk</symbol>

View File

@ -0,0 +1,60 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<key name="AD01">
<symbol label="1">1</symbol>
</key>
<key name="AD02">
<symbol label="2">2</symbol>
</key>
<key name="AD03">
<symbol label="3">3</symbol>
</key>
<key name="AD04">
<symbol label="(">parenleft</symbol>
</key>
<key name="AD05">
<symbol label=")">parenright</symbol>
</key>
<key name="AC01">
<symbol label="4">4</symbol>
</key>
<key name="AC02">
<symbol label="5">5</symbol>
</key>
<key name="AC03">
<symbol label="6">6</symbol>
</key>
<key name="AC04">
<symbol label="#">numbersign</symbol>
</key>
<key name="AC05">
<symbol label="*">asterisk</symbol>
</key>
<key name="AB01">
<symbol label="7">7</symbol>
</key>
<key name="AB02">
<symbol label="8">8</symbol>
</key>
<key name="AB03">
<symbol label="9">9</symbol>
</key>
<key name="AB04">
<symbol label="+">plus</symbol>
</key>
<key name="AB05">
<symbol label="-">minus</symbol>
</key>
<key name="AB06">
<symbol label="0">0</symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="SPCE">
<symbol label=" ">space</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
</symbols>

View File

@ -0,0 +1,231 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<key name="AD01">
<symbol label="q">q</symbol>
<symbol label="Q">Q</symbol>
<symbol label=""></symbol>
<symbol label="1">1</symbol>
</key>
<key name="AD02">
<symbol label="w">w</symbol>
<symbol label="W">W</symbol>
<symbol label=""></symbol>
<symbol label="2">2</symbol>
</key>
<key name="AD03">
<symbol label="e">e</symbol>
<symbol label="E">E</symbol>
<symbol label=""></symbol>
<symbol label="3">3</symbol>
</key>
<key name="AD04">
<symbol label="r">r</symbol>
<symbol label="R">R</symbol>
<symbol label=""></symbol>
<symbol label="4">4</symbol>
</key>
<key name="AD05">
<symbol label="t">t</symbol>
<symbol label="T">T</symbol>
<symbol label=""></symbol>
<symbol label="5">5</symbol>
</key>
<key name="AD06">
<symbol label="y">y</symbol>
<symbol label="Y">Y</symbol>
<symbol label=""></symbol>
<symbol label="6">6</symbol>
</key>
<key name="AD07">
<symbol label="u">u</symbol>
<symbol label="U">U</symbol>
<symbol label=""></symbol>
<symbol label="7">7</symbol>
</key>
<key name="AD08">
<symbol label="i">i</symbol>
<symbol label="I">I</symbol>
<symbol label=""></symbol>
<symbol label="8">8</symbol>
</key>
<key name="AD09">
<symbol label="o">o</symbol>
<symbol label="O">O</symbol>
<symbol label=""></symbol>
<symbol label="9">9</symbol>
</key>
<key name="AD10">
<symbol label="p">p</symbol>
<symbol label="P">P</symbol>
<symbol label=""></symbol>
<symbol label="0">0</symbol>
</key>
<key name="AC01">
<symbol label="a">a</symbol>
<symbol label="A">A</symbol>
<symbol label="@">at</symbol>
<symbol label="~">asciitilde</symbol>
</key>
<key name="AC02">
<symbol label="s">s</symbol>
<symbol label="S">S</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="&#174;">U00AE</symbol>
</key>
<key name="AC03">
<symbol label="d">d</symbol>
<symbol label="D">D</symbol>
<symbol label="$">dollar</symbol>
<symbol label="&#163;">U00A3</symbol>
</key>
<key name="AC04">
<symbol label="f">f</symbol>
<symbol label="F">F</symbol>
<symbol label="%">percent</symbol>
<symbol label="&#8364;">EuroSign</symbol>
</key>
<key name="AC05">
<symbol label="g">g</symbol>
<symbol label="G">G</symbol>
<symbol label="&amp;">ampersand</symbol>
<symbol label="&#165;">U00A5</symbol>
</key>
<key name="AC06">
<symbol label="h">h</symbol>
<symbol label="H">H</symbol>
<symbol label="-">minus</symbol>
<symbol label="^">asciicircum</symbol>
</key>
<key name="AC07">
<symbol label="j">j</symbol>
<symbol label="J">J</symbol>
<symbol label="_">underscore</symbol>
<symbol label="&#176;">degree</symbol>
</key>
<key name="AC08">
<symbol label="k">k</symbol>
<symbol label="K">K</symbol>
<symbol label="+">plus</symbol>
<symbol label="=">equal</symbol>
</key>
<key name="AC09">
<symbol label="l">l</symbol>
<symbol label="L">L</symbol>
<symbol label="(">parenleft</symbol>
<symbol label="{">braceleft</symbol>
</key>
<key name="AC10">
<symbol label=""></symbol>
<symbol label=""></symbol>
<symbol label=")">parenright</symbol>
<symbol label="}">braceright</symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="LFSH">
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
<keysym keyval="65505" label="123">Shift_L</keysym>
<keysym keyval="65505" label="URL">Shift_L</keysym>
</key>
<key name="AB01">
<symbol label="z">z</symbol>
<symbol label="Z">Z</symbol>
<symbol label=",">comma</symbol>
<symbol label="\">backslash</symbol>
</key>
<key name="AB02">
<symbol label="x">x</symbol>
<symbol label="X">X</symbol>
<symbol label="&quot;">quotedbl</symbol>
<symbol label="/">slash</symbol>
</key>
<key name="AB03">
<symbol label="c">c</symbol>
<symbol label="C">C</symbol>
<symbol label="'">quoteright</symbol>
<symbol label="&lt;">less</symbol>
</key>
<key name="AB04">
<symbol label="v">v</symbol>
<symbol label="V">V</symbol>
<symbol label=":">colon</symbol>
<symbol label="&gt;">greater</symbol>
</key>
<key name="AB05">
<symbol label="b">b</symbol>
<symbol label="B">B</symbol>
<symbol label=";">semicolon</symbol>
<symbol label="=">equal</symbol>
</key>
<key name="AB06">
<symbol label="n">n</symbol>
<symbol label="N">N</symbol>
<symbol label="!">exclam</symbol>
<symbol label="[">bracketleft</symbol>
</key>
<key name="AB07">
<symbol label="m">m</symbol>
<symbol label="M">M</symbol>
<symbol label="?">question</symbol>
<symbol label="]">bracketright</symbol>
</key>
<key name="AB08">
<symbol label=".">period</symbol>
</key>
<key name="ABC123">
<symbol label="URL">show-url</symbol>
<symbol label="URL">show-url</symbol>
<symbol label="ABC">show-letters</symbol>
<symbol label="ABC">show-letters</symbol>
</key>
<key name="I149">
<symbol label="&#9786;" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
</key>
<key name="SPCE">
<symbol label=" ">space</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
<!-- Extra URL mode buttons -->
<key name="AE01">
<symbol label=""></symbol>
<symbol label=""></symbol>
<text label="https">https</text>
<symbol label=""></symbol>
</key>
<key name="AE02">
<symbol label=""></symbol>
<symbol label=""></symbol>
<text label="://">://</text>
<symbol label=""></symbol>
</key>
<key name="AE03">
<symbol label=""></symbol>
<symbol label=""></symbol>
<text label="www.">www.</text>
<symbol label=""></symbol>
</key>
<key name="AE04">
<symbol label=""></symbol>
<symbol label=""></symbol>
<text label=".com">.com</text>
<symbol label=""></symbol>
</key>
<key name="AE05">
<symbol label=""></symbol>
<symbol label=""></symbol>
<text label=".org">.org</text>
<symbol label=""></symbol>
</key>
<key name="AE06">
<symbol label=""></symbol>
<symbol label=""></symbol>
<text label=".net">.net</text>
<symbol label=""></symbol>
</key>
</symbols>

View File

@ -2,10 +2,19 @@
<gresources> <gresources>
<gresource prefix="/sm/puri/squeekboard"> <gresource prefix="/sm/puri/squeekboard">
<file compressed="true">style.css</file> <file compressed="true">style.css</file>
<!-- Keyboard layouts -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/digits.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/phone-keypad.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/url.xml</file>
<!-- Keyboard definitions -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
<!-- Natural language keyboards -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
@ -35,7 +44,13 @@
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
<!-- Special purpose keyboards -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/digits.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file> <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/phone.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/url.xml</file>
<file>icons/key-enter.svg</file> <file>icons/key-enter.svg</file>
<file>icons/key-shift.svg</file> <file>icons/key-shift.svg</file>
<file>icons/keyboard-mode-symbolic.svg</file> <file>icons/keyboard-mode-symbolic.svg</file>

View File

@ -50,7 +50,7 @@ static void
eek_container_real_add_child (EekContainer *self, eek_container_real_add_child (EekContainer *self,
EekElement *child) EekElement *child)
{ {
EekContainerPrivate *priv = eek_container_get_instance_private (self); EekContainerPrivate *priv = (EekContainerPrivate*)eek_container_get_instance_private (self);
g_return_if_fail (EEK_IS_ELEMENT(child)); g_return_if_fail (EEK_IS_ELEMENT(child));
g_object_ref (child); g_object_ref (child);

View File

@ -55,7 +55,8 @@ typedef struct _EekGtkKeyboardPrivate
{ {
EekRenderer *renderer; EekRenderer *renderer;
EekKeyboard *keyboard; EekKeyboard *keyboard;
EekTheme *theme; GtkCssProvider *css_provider;
GtkStyleContext *scontext;
GdkEventSequence *sequence; // unowned reference GdkEventSequence *sequence; // unowned reference
} EekGtkKeyboardPrivate; } EekGtkKeyboardPrivate;
@ -66,16 +67,6 @@ static void on_key_pressed (EekKey *key,
EekGtkKeyboard *self); EekGtkKeyboard *self);
static void on_key_released (EekKey *key, static void on_key_released (EekKey *key,
EekGtkKeyboard *self); EekGtkKeyboard *self);
static void on_key_locked (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data);
static void on_key_unlocked (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data);
static void on_symbol_index_changed (EekKeyboard *keyboard,
gint group,
gint level,
gpointer user_data);
static void render_pressed_key (GtkWidget *widget, static void render_pressed_key (GtkWidget *widget,
EekKey *key); EekKey *key);
static void render_locked_key (GtkWidget *widget, static void render_locked_key (GtkWidget *widget,
@ -109,12 +100,9 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
gtk_widget_get_allocation (self, &allocation); gtk_widget_get_allocation (self, &allocation);
if (!priv->renderer) { if (!priv->renderer) {
PangoContext *pcontext; PangoContext *pcontext = gtk_widget_get_pango_context (self);
pcontext = gtk_widget_get_pango_context (self); priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
if (priv->theme)
eek_renderer_set_theme (priv->renderer, priv->theme);
eek_renderer_set_allocation_size (priv->renderer, eek_renderer_set_allocation_size (priv->renderer,
allocation.width, allocation.width,
@ -159,7 +147,8 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
} }
static void depress(EekGtkKeyboard *self, static void depress(EekGtkKeyboard *self,
gdouble x, gdouble y, guint32 time) { gdouble x, gdouble y, guint32 time)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
@ -173,16 +162,17 @@ static void drag(EekGtkKeyboard *self,
gdouble x, gdouble y, guint32 time) { gdouble x, gdouble y, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
if (key) {
GList *list, *head; GList *list, *head;
gboolean found = FALSE;
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (priv->keyboard);
if (key) {
gboolean found = FALSE;
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
if (head->data == key) if (head->data == key) {
found = TRUE; found = TRUE;
else { } else {
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time); eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
on_key_released(key, self); on_key_released(key, self);
} }
@ -193,6 +183,12 @@ static void drag(EekGtkKeyboard *self,
eek_keyboard_press_key(priv->keyboard, key, time); eek_keyboard_press_key(priv->keyboard, key, time);
on_key_pressed(key, self); on_key_pressed(key, self);
} }
} else {
for (head = list; head; head = g_list_next (head)) {
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
on_key_released(key, self);
}
g_list_free (list);
} }
} }
@ -333,18 +329,10 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
return; return;
if (priv->keyboard) { if (priv->keyboard) {
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
g_object_unref (priv->keyboard); g_object_unref (priv->keyboard);
} }
priv->keyboard = g_object_ref (keyboard); priv->keyboard = g_object_ref (keyboard);
g_signal_connect (priv->keyboard, "key-locked",
G_CALLBACK(on_key_locked), self);
g_signal_connect (priv->keyboard, "key-unlocked",
G_CALLBACK(on_key_unlocked), self);
g_signal_connect (priv->keyboard, "symbol-index-changed",
G_CALLBACK(on_symbol_index_changed), self);
} }
static void static void
@ -380,7 +368,6 @@ eek_gtk_keyboard_dispose (GObject *object)
if (priv->keyboard) { if (priv->keyboard) {
GList *list, *head; GList *list, *head;
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
list = eek_keyboard_get_pressed_keys (priv->keyboard); list = eek_keyboard_get_pressed_keys (priv->keyboard);
for (head = list; head; head = g_list_next (head)) { for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed"); g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
@ -392,11 +379,6 @@ eek_gtk_keyboard_dispose (GObject *object)
priv->keyboard = NULL; priv->keyboard = NULL;
} }
if (priv->theme) {
g_object_unref (priv->theme);
priv->theme = NULL;
}
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object); G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
} }
@ -437,7 +419,20 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
static void static void
eek_gtk_keyboard_init (EekGtkKeyboard *self) eek_gtk_keyboard_init (EekGtkKeyboard *self)
{ {
/* void */ EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
/* Create a default CSS provider and load a style sheet */
priv->css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (priv->css_provider,
"/sm/puri/squeekboard/style.css");
/* Apply the style to the widget */
priv->scontext = gtk_widget_get_style_context (GTK_WIDGET(self));
gtk_style_context_add_class (priv->scontext, "keyboard");
gtk_style_context_add_provider (priv->scontext,
GTK_STYLE_PROVIDER(priv->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_style_context_set_state (priv->scontext, GTK_STATE_FLAG_NORMAL);
} }
/** /**
@ -482,27 +477,15 @@ render_pressed_key (GtkWidget *widget,
{ {
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekBounds bounds, large_bounds;
GdkWindow *window = gtk_widget_get_window (widget); GdkWindow *window = gtk_widget_get_window (widget);
cairo_region_t *region = gdk_window_get_clip_region (window); cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context); cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
gdouble scale = eek_renderer_get_scale (priv->renderer);
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
cairo_save (cr);
cairo_scale (cr, scale, scale);
cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE); eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
cairo_restore (cr);
/* /*
cairo_save (cr);
cairo_translate (cr, large_bounds.x, large_bounds.y);
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE); eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
cairo_restore (cr);
*/ */
gdk_window_end_draw_frame (window, context); gdk_window_end_draw_frame (window, context);
@ -515,21 +498,13 @@ render_locked_key (GtkWidget *widget,
{ {
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekBounds bounds;
GdkWindow *window = gtk_widget_get_window (widget); GdkWindow *window = gtk_widget_get_window (widget);
cairo_region_t *region = gdk_window_get_clip_region (window); cairo_region_t *region = gdk_window_get_clip_region (window);
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context); cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
gdouble scale = eek_renderer_get_scale (priv->renderer);
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
cairo_save (cr);
cairo_scale (cr, scale, scale);
cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE); eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
cairo_restore (cr);
gdk_window_end_draw_frame (window, context); gdk_window_end_draw_frame (window, context);
@ -542,7 +517,6 @@ render_released_key (GtkWidget *widget,
{ {
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
EekBounds bounds, large_bounds;
GdkWindow *window = gtk_widget_get_window (widget); GdkWindow *window = gtk_widget_get_window (widget);
cairo_region_t *region = gdk_window_get_clip_region (window); cairo_region_t *region = gdk_window_get_clip_region (window);
@ -599,57 +573,3 @@ on_key_released (EekKey *key,
NULL); NULL);
#endif #endif
} }
static void
on_key_locked (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data)
{
GtkWidget *widget = user_data;
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
render_locked_key (widget, key);
gtk_widget_queue_draw (widget);
}
static void
on_key_unlocked (EekKeyboard *keyboard,
EekKey *key,
gpointer user_data)
{
GtkWidget *widget = user_data;
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
render_released_key (widget, key);
gtk_widget_queue_draw (GTK_WIDGET(widget));
}
static void
on_symbol_index_changed (EekKeyboard *keyboard,
gint group,
gint level,
gpointer user_data)
{
GtkWidget *widget = user_data;
gtk_widget_queue_draw (widget);
}
void
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
EekTheme *theme)
{
g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
g_return_if_fail (EEK_IS_THEME(theme));
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
priv->theme = g_object_ref (theme);
}

View File

@ -46,8 +46,6 @@ struct _EekGtkKeyboardClass
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST; GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard); GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
void eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
EekTheme *theme);
G_END_DECLS G_END_DECLS
#endif /* EEK_GTK_KEYBOARD_H */ #endif /* EEK_GTK_KEYBOARD_H */

View File

@ -38,8 +38,6 @@ enum {
PROP_0, PROP_0,
PROP_KEYCODE, PROP_KEYCODE,
PROP_SYMBOL_MATRIX, PROP_SYMBOL_MATRIX,
PROP_COLUMN,
PROP_ROW,
PROP_OREF, PROP_OREF,
PROP_LAST PROP_LAST
}; };
@ -56,8 +54,6 @@ typedef struct _EekKeyPrivate
{ {
guint keycode; guint keycode;
EekSymbolMatrix *symbol_matrix; EekSymbolMatrix *symbol_matrix;
gint column;
gint row;
gulong oref; // UI outline reference gulong oref; // UI outline reference
gboolean is_pressed; gboolean is_pressed;
gboolean is_locked; gboolean is_locked;
@ -105,8 +101,6 @@ eek_key_set_property (GObject *object,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekSymbolMatrix *matrix; EekSymbolMatrix *matrix;
gint column, row;
switch (prop_id) { switch (prop_id) {
case PROP_KEYCODE: case PROP_KEYCODE:
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value)); eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
@ -115,14 +109,6 @@ eek_key_set_property (GObject *object,
matrix = g_value_get_boxed (value); matrix = g_value_get_boxed (value);
eek_key_set_symbol_matrix (EEK_KEY(object), matrix); eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
break; break;
case PROP_COLUMN:
eek_key_get_index (EEK_KEY(object), &column, &row);
eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
break;
case PROP_ROW:
eek_key_get_index (EEK_KEY(object), &column, &row);
eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
break;
case PROP_OREF: case PROP_OREF:
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value)); eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
break; break;
@ -138,8 +124,6 @@ eek_key_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
gint column, row;
switch (prop_id) { switch (prop_id) {
case PROP_KEYCODE: case PROP_KEYCODE:
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object))); g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
@ -148,14 +132,6 @@ eek_key_get_property (GObject *object,
g_value_set_boxed (value, g_value_set_boxed (value,
eek_key_get_symbol_matrix (EEK_KEY(object))); eek_key_get_symbol_matrix (EEK_KEY(object)));
break; break;
case PROP_COLUMN:
eek_key_get_index (EEK_KEY(object), &column, &row);
g_value_set_int (value, column);
break;
case PROP_ROW:
eek_key_get_index (EEK_KEY(object), &column, &row);
g_value_set_int (value, row);
break;
case PROP_OREF: case PROP_OREF:
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object))); g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
break; break;
@ -203,30 +179,6 @@ eek_key_class_init (EekKeyClass *klass)
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec); g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
/**
* EekKey:column:
*
* The column index of #EekKey in the parent #EekSection.
*/
pspec = g_param_spec_int ("column",
"Column",
"Column index of the key in section",
-1, G_MAXINT, -1,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
/**
* EekKey:row:
*
* The row index of #EekKey in the parent #EekSection.
*/
pspec = g_param_spec_int ("row",
"Row",
"Row index of the key in section",
-1, G_MAXINT, -1,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ROW, pspec);
/** /**
* EekKey:oref: * EekKey:oref:
* *
@ -478,59 +430,6 @@ eek_key_get_symbol_at_index (EekKey *key,
level]; level];
} }
/**
* eek_key_set_index:
* @key: an #EekKey
* @column: column index of @key in #EekSection
* @row: row index of @key in #EekSection
*
* Set the location of @key in #EekSection with @column and @row.
*/
void
eek_key_set_index (EekKey *key,
gint column,
gint row)
{
g_return_if_fail (EEK_IS_KEY(key));
g_return_if_fail (0 <= column);
g_return_if_fail (0 <= row);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
if (priv->column != column) {
priv->column = column;
g_object_notify (G_OBJECT(key), "column");
}
if (priv->row != row) {
priv->row = row;
g_object_notify (G_OBJECT(key), "row");
}
}
/**
* eek_key_get_index:
* @key: an #EekKey
* @column: (allow-none): pointer where the column index of @key in #EekSection will be stored
* @row: (allow-none): pointer where the row index of @key in #EekSection will be stored
*
* Get the location of @key in #EekSection.
*/
void
eek_key_get_index (EekKey *key,
gint *column,
gint *row)
{
g_return_if_fail (EEK_IS_KEY(key));
g_return_if_fail (column != NULL || row != NULL);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
if (column != NULL)
*column = priv->column;
if (row != NULL)
*row = priv->row;
}
/** /**
* eek_key_set_oref: * eek_key_set_oref:
* @key: an #EekKey * @key: an #EekKey

View File

@ -73,13 +73,6 @@ EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
gint fallback_group, gint fallback_group,
gint fallback_level); gint fallback_level);
void eek_key_set_index (EekKey *key,
gint column,
gint row);
void eek_key_get_index (EekKey *key,
gint *column,
gint *row);
void eek_key_set_oref (EekKey *key, void eek_key_set_oref (EekKey *key,
guint oref); guint oref);
guint eek_key_get_oref (EekKey *key); guint eek_key_get_oref (EekKey *key);

View File

@ -75,8 +75,10 @@ struct _EekKeyboardPrivate
GList *locked_keys; GList *locked_keys;
GArray *outline_array; GArray *outline_array;
/* Map key names to key objects: */ /* Map key names to key objects */
GHashTable *names; GHashTable *names;
/* Map characters to symbols and levels */
GHashTable *character_map;
/* modifiers dynamically assigned at run time */ /* modifiers dynamically assigned at run time */
EekModifierType num_lock_mask; EekModifierType num_lock_mask;
@ -405,6 +407,7 @@ eek_keyboard_finalize (GObject *object)
(GDestroyNotify) eek_modifier_key_free); (GDestroyNotify) eek_modifier_key_free);
g_hash_table_destroy (priv->names); g_hash_table_destroy (priv->names);
g_hash_table_destroy (priv->character_map);
for (i = 0; i < priv->outline_array->len; i++) { for (i = 0; i < priv->outline_array->len; i++) {
EekOutline *outline = &g_array_index (priv->outline_array, EekOutline *outline = &g_array_index (priv->outline_array,
@ -533,6 +536,8 @@ eek_keyboard_init (EekKeyboard *self)
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE; self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline)); self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
self->priv->names = g_hash_table_new (g_str_hash, g_str_equal); self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
self->priv->character_map = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, g_free);
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0); eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
self->scale = 1.0; self->scale = 1.0;
} }
@ -845,7 +850,7 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
/* Get the symbols for all the levels defined for the key, then /* Get the symbols for all the levels defined for the key, then
pad it out with the first symbol for all levels up to the fourth. */ pad it out with the first symbol for all levels up to the fourth. */
for (i = 0; i < matrix->num_levels; ++i) for (i = 0; (i < matrix->num_levels) && (i < 4); ++i)
syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i); syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i);
while (i < 4) { while (i < 4) {
@ -857,14 +862,12 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
Generate strings for each of these groups, where an empty group is Generate strings for each of these groups, where an empty group is
treated specially. */ treated specially. */
gchar *groups[2]; gchar *groups[2] = {NULL, NULL};
for (i = 0, j = 0; i < 2; ++i, j += 2) { for (i = 0, j = 0; i < 2; ++i, j += 2) {
if (syms[j] && syms[j + 1]) if (syms[j] && syms[j + 1])
groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]), groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]),
eek_symbol_get_name(syms[j + 1]), eek_symbol_get_name(syms[j + 1]),
NULL); NULL);
else
groups[i] = "";
} }
/* Append a key definition to the symbols section. */ /* Append a key definition to the symbols section. */
@ -890,3 +893,29 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
g_free(symbols); g_free(symbols);
return keymap; return keymap;
} }
void
eek_keyboard_register_symbol (EekKeyboard *keyboard,
EekSymbol *symbol,
EekKey *key,
guint level)
{
const gchar *label = eek_symbol_get_label(symbol);
if (label) {
EekKeyPress *key_press = g_malloc0 (sizeof(EekKeyPress));
key_press->key = key;
key_press->level = level;
g_hash_table_insert (keyboard->priv->character_map,
(gpointer)label,
key_press);
}
}
EekKeyPress *
eek_keyboard_get_key_press (EekKeyboard *keyboard,
gchar *ch)
{
return g_hash_table_lookup (keyboard->priv->character_map, ch);
}

View File

@ -124,6 +124,11 @@ struct _EekModifierKey {
}; };
typedef struct _EekModifierKey EekModifierKey; typedef struct _EekModifierKey EekModifierKey;
struct _EekKeyPress {
EekKey *key;
guint level;
};
typedef struct _EekKeyPress EekKeyPress;
EekKeyboard *eek_keyboard_new (EekboardContextService *manager, EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
EekLayout *layout, EekLayout *layout,
@ -198,5 +203,15 @@ void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timest
gchar * eek_keyboard_get_keymap gchar * eek_keyboard_get_keymap
(EekKeyboard *keyboard); (EekKeyboard *keyboard);
void eek_keyboard_register_symbol
(EekKeyboard *keyboard,
EekSymbol *symbol,
EekKey *key,
guint level);
EekKeyPress * eek_keyboard_get_key_press
(EekKeyboard *keyboard,
gchar *ch);
G_END_DECLS G_END_DECLS
#endif /* EEK_KEYBOARD_H */ #endif /* EEK_KEYBOARD_H */

View File

@ -48,15 +48,9 @@
#define EEK_KEYSYM_Hyper_L 0xffed #define EEK_KEYSYM_Hyper_L 0xffed
#define EEK_KEYSYM_Hyper_R 0xffee #define EEK_KEYSYM_Hyper_R 0xffee
typedef struct _EekKeysymPrivate
{
guint xkeysym;
} EekKeysymPrivate;
struct _EekKeysymEntry { struct _EekKeysymEntry {
guint xkeysym; guint xkeysym;
const gchar *name; const gchar *name;
EekSymbolCategory category;
}; };
typedef struct _EekKeysymEntry EekKeysymEntry; typedef struct _EekKeysymEntry EekKeysymEntry;
@ -65,54 +59,6 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
#include "eek-unicode-keysym-entries.h" #include "eek-unicode-keysym-entries.h"
#include "eek-xkeysym-keysym-entries.h" #include "eek-xkeysym-keysym-entries.h"
static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
0, /* GTypeFlags */
G_ADD_PRIVATE (EekKeysym)
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init))
static EekSerializableIface *eek_keysym_parent_serializable_iface;
static void
eek_keysym_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
EEK_KEYSYM(self));
eek_keysym_parent_serializable_iface->serialize (self, builder);
g_variant_builder_add (builder, "u", priv->xkeysym);
}
static gsize
eek_keysym_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
EEK_KEYSYM(self));
index = eek_keysym_parent_serializable_iface->deserialize (self,
variant,
index);
g_variant_get_child (variant, index++, "u", &priv->xkeysym);
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
eek_keysym_parent_serializable_iface =
g_type_interface_peek_parent (iface);
iface->serialize = eek_keysym_real_serialize;
iface->deserialize = eek_keysym_real_deserialize;
}
static gchar * static gchar *
unichar_to_utf8 (gunichar uc) unichar_to_utf8 (gunichar uc)
@ -197,18 +143,6 @@ get_modifier_mask (guint xkeysym)
return 0; return 0;
} }
static void
eek_keysym_class_init (EekKeysymClass *klass)
{
/* void */
}
static void
eek_keysym_init (EekKeysym *self)
{
/* void */
}
/** /**
* eek_keysym_new_with_modifier: * eek_keysym_new_with_modifier:
* @xkeysym: an X keysym value * @xkeysym: an X keysym value
@ -217,16 +151,12 @@ eek_keysym_init (EekKeysym *self)
* Create an #EekKeysym with given X keysym value @xkeysym and * Create an #EekKeysym with given X keysym value @xkeysym and
* modifier @modifier_mask. * modifier @modifier_mask.
*/ */
EekKeysym * EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
eek_keysym_new_with_modifier (guint xkeysym,
EekModifierType modifier_mask) EekModifierType modifier_mask)
{ {
EekKeysym *keysym;
EekKeysymPrivate *priv;
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry, EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
*unichar_entry; *unichar_entry;
gchar *name, *label; gchar *name, *label;
EekSymbolCategory category;
gunichar uc; gunichar uc;
special_entry = special_entry =
@ -246,23 +176,17 @@ eek_keysym_new_with_modifier (guint xkeysym,
unichar_entry = g_slice_new (EekKeysymEntry); unichar_entry = g_slice_new (EekKeysymEntry);
unichar_entry->xkeysym = xkeysym; unichar_entry->xkeysym = xkeysym;
unichar_entry->name = unichar_to_utf8 (uc); unichar_entry->name = unichar_to_utf8 (uc);
unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
} }
/* name and category */
name = NULL; name = NULL;
if (xkeysym_entry) { if (xkeysym_entry) {
name = g_strdup (xkeysym_entry->name); name = g_strdup (xkeysym_entry->name);
category = xkeysym_entry->category;
} else if (unichar_entry) { } else if (unichar_entry) {
name = g_strdup (unichar_entry->name); name = g_strdup (unichar_entry->name);
category = unichar_entry->category;
} else if (unicode_entry) { } else if (unicode_entry) {
name = g_strdup (unicode_entry->name); name = g_strdup (unicode_entry->name);
category = unicode_entry->category;
} else { } else {
name = g_strdup (""); name = g_strdup ("");
category = EEK_SYMBOL_CATEGORY_UNKNOWN;
} }
/* label */ /* label */
@ -275,12 +199,10 @@ eek_keysym_new_with_modifier (guint xkeysym,
else else
label = g_strdup (name); label = g_strdup (name);
keysym = g_object_new (EEK_TYPE_KEYSYM, EekSymbol *keysym = eek_symbol_new(name);
"name", name, eek_symbol_set_label(keysym, label);
"label", label, eek_symbol_set_modifier_mask(keysym, modifier_mask);
"category", category,
"modifier-mask", modifier_mask,
NULL);
g_free (name); g_free (name);
g_free (label); g_free (label);
@ -289,8 +211,7 @@ eek_keysym_new_with_modifier (guint xkeysym,
g_slice_free (EekKeysymEntry, unichar_entry); g_slice_free (EekKeysymEntry, unichar_entry);
} }
priv = eek_keysym_get_instance_private (keysym); keysym->xkeysym = xkeysym;
priv->xkeysym = xkeysym;
return keysym; return keysym;
} }
@ -301,7 +222,7 @@ eek_keysym_new_with_modifier (guint xkeysym,
* *
* Create an #EekKeysym with given X keysym value @xkeysym. * Create an #EekKeysym with given X keysym value @xkeysym.
*/ */
EekKeysym * EekSymbol*
eek_keysym_new (guint xkeysym) eek_keysym_new (guint xkeysym)
{ {
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym)); return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
@ -313,22 +234,16 @@ eek_keysym_new (guint xkeysym)
* *
* Create an #EekKeysym with an X keysym value looked up by @name. * Create an #EekKeysym with an X keysym value looked up by @name.
*/ */
EekKeysym * EekSymbol*
eek_keysym_new_from_name (const gchar *name) eek_keysym_new_from_name (const gchar *name)
{ {
gint i; for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym); return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
// g_warning ("can't find keysym entry for %s", name); EekSymbol *ret = eek_symbol_new(name);
return g_object_new (EEK_TYPE_KEYSYM, eek_symbol_set_label(ret, name);
"name", name, return ret;
"label", name,
"category", EEK_SYMBOL_CATEGORY_UNKNOWN,
"modifier-mask", 0,
NULL);
} }
/** /**
@ -338,11 +253,10 @@ eek_keysym_new_from_name (const gchar *name)
* Get an X keysym value associated with @keysym * Get an X keysym value associated with @keysym
*/ */
guint guint
eek_keysym_get_xkeysym (EekKeysym *keysym) eek_keysym_get_xkeysym (EekSymbol *keysym)
{ {
EekKeysymPrivate *priv; if (keysym->xkeysym == 0) {
g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
g_assert (EEK_IS_KEYSYM(keysym)); }
priv = eek_keysym_get_instance_private (keysym); return keysym->xkeysym;
return priv->xkeysym;
} }

View File

@ -37,20 +37,11 @@ G_BEGIN_DECLS
*/ */
#define EEK_INVALID_KEYSYM (0) #define EEK_INVALID_KEYSYM (0)
#define EEK_TYPE_KEYSYM (eek_keysym_get_type()) EekSymbol *eek_keysym_new (guint xkeysym);
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol) guint eek_keysym_get_xkeysym (EekSymbol *keysym);
struct _EekKeysymClass { EekSymbol *eek_keysym_new_from_name (const gchar *name);
/*< private >*/ EekSymbol *eek_keysym_new_with_modifier (guint xkeysym,
EekSymbolClass parent_class;
};
GType eek_keysym_get_type (void) G_GNUC_CONST;
EekKeysym *eek_keysym_new (guint xkeysym);
guint eek_keysym_get_xkeysym (EekKeysym *keysym);
EekKeysym *eek_keysym_new_from_name (const gchar *name);
EekKeysym *eek_keysym_new_with_modifier (guint xkeysym,
EekModifierType modifier_mask); EekModifierType modifier_mask);
G_END_DECLS G_END_DECLS

View File

@ -33,6 +33,7 @@ enum {
PROP_0, PROP_0,
PROP_KEYBOARD, PROP_KEYBOARD,
PROP_PCONTEXT, PROP_PCONTEXT,
PROP_STYLE_CONTEXT,
PROP_LAST PROP_LAST
}; };
@ -40,6 +41,9 @@ typedef struct _EekRendererPrivate
{ {
EekKeyboard *keyboard; EekKeyboard *keyboard;
PangoContext *pcontext; PangoContext *pcontext;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
GtkStyleContext *key_context;
EekColor default_foreground_color; EekColor default_foreground_color;
EekColor default_background_color; EekColor default_background_color;
@ -60,7 +64,6 @@ typedef struct _EekRendererPrivate
cairo_surface_t *keyboard_surface; cairo_surface_t *keyboard_surface;
gulong symbol_index_changed_handler; gulong symbol_index_changed_handler;
EekTheme *theme;
} EekRendererPrivate; } EekRendererPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT) G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
@ -68,14 +71,6 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
static const EekColor DEFAULT_FOREGROUND_COLOR = {0.3, 0.3, 0.3, 1.0}; static const EekColor DEFAULT_FOREGROUND_COLOR = {0.3, 0.3, 0.3, 1.0};
static const EekColor DEFAULT_BACKGROUND_COLOR = {1.0, 1.0, 1.0, 1.0}; static const EekColor DEFAULT_BACKGROUND_COLOR = {1.0, 1.0, 1.0, 1.0};
struct _TextProperty {
gint category;
gboolean ascii;
gdouble scale;
gboolean ellipses;
};
typedef struct _TextProperty TextProperty;
/* eek-keyboard-drawing.c */ /* eek-keyboard-drawing.c */
extern void _eek_rounded_polygon (cairo_t *cr, extern void _eek_rounded_polygon (cairo_t *cr,
gdouble radius, gdouble radius,
@ -153,32 +148,25 @@ render_keyboard_surface (EekRenderer *renderer)
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekBounds bounds; EekBounds bounds;
CreateKeyboardSurfaceCallbackData data; CreateKeyboardSurfaceCallbackData data;
EekColor foreground, background; EekColor foreground;
eek_renderer_get_foreground_color (renderer, eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
EEK_ELEMENT(priv->keyboard),
&foreground);
eek_renderer_get_background_color (renderer,
EEK_ELEMENT(priv->keyboard),
&background);
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
data.cr = cairo_create (priv->keyboard_surface); data.cr = cairo_create (priv->keyboard_surface);
data.renderer = renderer; data.renderer = renderer;
/* Paint the background covering the entire widget area */
gtk_render_background (priv->scontext,
data.cr,
0, 0,
priv->allocation_width, priv->allocation_height);
cairo_save (data.cr); cairo_save (data.cr);
cairo_scale (data.cr, priv->scale, priv->scale); cairo_scale (data.cr, priv->scale, priv->scale);
cairo_translate (data.cr, bounds.x, bounds.y); cairo_translate (data.cr, bounds.x, bounds.y);
/* blank background */
cairo_set_source_rgba (data.cr,
background.red,
background.green,
background.blue,
background.alpha);
cairo_paint (data.cr);
cairo_set_source_rgba (data.cr, cairo_set_source_rgba (data.cr,
foreground.red, foreground.red,
foreground.green, foreground.green,
@ -204,7 +192,6 @@ render_key_outline (EekRenderer *renderer,
EekOutline *outline; EekOutline *outline;
EekBounds bounds; EekBounds bounds;
guint oref; guint oref;
EekThemeNode *theme_node;
EekColor foreground, background, gradient_start, gradient_end, border_color; EekColor foreground, background, gradient_start, gradient_end, border_color;
EekGradientType gradient_type; EekGradientType gradient_type;
gint border_width; gint border_width;
@ -215,119 +202,14 @@ render_key_outline (EekRenderer *renderer,
if (outline == NULL) if (outline == NULL)
return; return;
theme_node = g_object_get_data (G_OBJECT(key),
active ?
"theme-node-pressed" :
"theme-node");
if (theme_node) {
eek_theme_node_get_foreground_color (theme_node, &foreground);
eek_theme_node_get_background_color (theme_node, &background);
eek_theme_node_get_background_gradient (theme_node,
&gradient_type,
&gradient_start,
&gradient_end);
border_width = eek_theme_node_get_border_width (theme_node,
EEK_SIDE_TOP);
border_radius = eek_theme_node_get_border_radius (theme_node,
EEK_CORNER_TOPLEFT);
eek_theme_node_get_border_color (theme_node, EEK_SIDE_TOP,
&border_color);
} else {
foreground = priv->default_foreground_color;
background = priv->default_background_color;
gradient_type = EEK_GRADIENT_NONE;
border_width = (gint)round(priv->border_width);
border_radius = -1;
border_color.red = ABS(background.red - foreground.red) * 0.7;
border_color.green = ABS(background.green - foreground.green) * 0.7;
border_color.blue = ABS(background.blue - foreground.blue) * 0.7;
border_color.alpha = foreground.alpha;
}
eek_element_get_bounds(EEK_ELEMENT(key), &bounds); eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
outline = eek_outline_copy (outline); gtk_style_context_set_state(priv->key_context,
active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
cairo_translate (cr, border_width, border_width); gtk_render_background (priv->key_context,
cr, 0, 0, bounds.width, bounds.height);
if (gradient_type != EEK_GRADIENT_NONE) { gtk_style_context_set_state(priv->key_context, GTK_STATE_FLAG_NORMAL);
cairo_pattern_t *pat;
gdouble cx, cy;
switch (gradient_type) {
case EEK_GRADIENT_VERTICAL:
pat = cairo_pattern_create_linear (0.0,
0.0,
0.0,
bounds.height);
break;
case EEK_GRADIENT_HORIZONTAL:
pat = cairo_pattern_create_linear (0.0,
0.0,
bounds.width,
0.0);
break;
case EEK_GRADIENT_RADIAL:
cx = bounds.width / 2;
cy = bounds.height / 2;
pat = cairo_pattern_create_radial (cx,
cy,
0,
cx,
cy,
MIN(cx, cy));
break;
default:
g_assert_not_reached ();
break;
}
cairo_pattern_add_color_stop_rgba (pat,
1,
gradient_start.red * 0.5,
gradient_start.green * 0.5,
gradient_start.blue * 0.5,
gradient_start.alpha);
cairo_pattern_add_color_stop_rgba (pat,
0,
gradient_end.red,
gradient_end.green,
gradient_end.blue,
gradient_end.alpha);
cairo_set_source (cr, pat);
cairo_pattern_destroy (pat);
} else {
cairo_set_source_rgba (cr,
background.red,
background.green,
background.blue,
background.alpha);
}
_eek_rounded_polygon (cr,
border_radius >= 0 ? border_radius : outline->corner_radius,
outline->points,
outline->num_points);
cairo_fill (cr);
/* paint the border */
cairo_set_line_width (cr, border_width);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_source_rgba (cr,
border_color.red,
border_color.green,
border_color.blue,
border_color.alpha);
_eek_rounded_polygon (cr,
border_radius >= 0 ? border_radius : outline->corner_radius,
outline->points,
outline->num_points);
cairo_stroke (cr);
cairo_translate (cr, -border_width, -border_width);
eek_outline_free (outline);
} }
static void static void
@ -394,7 +276,7 @@ render_key (EekRenderer *self,
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0); cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
cairo_paint (cr); cairo_paint (cr);
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground); eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
/* render icon (if any) */ /* render icon (if any) */
symbol = eek_key_get_symbol_with_fallback (key, 0, 0); symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol) if (!symbol)
@ -405,7 +287,7 @@ render_key (EekRenderer *self,
cairo_surface_t *icon_surface = cairo_surface_t *icon_surface =
eek_renderer_get_icon_surface (self, eek_renderer_get_icon_surface (self,
eek_symbol_get_icon_name (symbol), eek_symbol_get_icon_name (symbol),
16, 16 / priv->scale,
scale); scale);
if (icon_surface) { if (icon_surface) {
gint width = cairo_image_surface_get_width (icon_surface); gint width = cairo_image_surface_get_width (icon_surface);
@ -432,7 +314,7 @@ render_key (EekRenderer *self,
/* render label */ /* render label */
layout = pango_cairo_create_layout (cr); layout = pango_cairo_create_layout (cr);
eek_renderer_render_key_label (self, layout, key); eek_renderer_real_render_key_label (self, layout, key);
pango_layout_get_extents (layout, NULL, &extents); pango_layout_get_extents (layout, NULL, &extents);
cairo_save (cr); cairo_save (cr);
@ -452,6 +334,21 @@ render_key (EekRenderer *self,
g_object_unref (layout); g_object_unref (layout);
} }
/**
* eek_renderer_apply_transformation_for_key:
* @self: The renderer used to render the key
* @cr: The Cairo rendering context used for rendering
* @key: The key to be transformed
* @scale: The factor used to scale the key bounds before rendering
* @rotate: Whether to rotate the key by the angle defined for the key's
* in its section definition
*
* Applies a transformation, consisting of scaling and rotation, to the
* current rendering context using the bounds for the given key. The scale
* factor is separate to the normal scale factor for the keyboard as a whole
* and is applied cumulatively. It is typically used to render larger than
* normal keys for popups.
*/
void void
eek_renderer_apply_transformation_for_key (EekRenderer *self, eek_renderer_apply_transformation_for_key (EekRenderer *self,
cairo_t *cr, cairo_t *cr,
@ -481,22 +378,6 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self,
} }
} }
static const TextProperty *
get_text_property_for_category (EekSymbolCategory category)
{
static const TextProperty props[EEK_SYMBOL_CATEGORY_LAST] = {
{ EEK_SYMBOL_CATEGORY_LETTER, FALSE, 1.0, FALSE },
{ EEK_SYMBOL_CATEGORY_FUNCTION, TRUE, 0.5, FALSE },
{ EEK_SYMBOL_CATEGORY_KEYNAME, TRUE, 0.5, TRUE }
};
for (uint i = 0; i < G_N_ELEMENTS(props); i++)
if (props[i].category == category)
return &props[i];
g_return_val_if_reached (NULL);
}
static void static void
eek_renderer_real_render_key_label (EekRenderer *self, eek_renderer_real_render_key_label (EekRenderer *self,
PangoLayout *layout, PangoLayout *layout,
@ -504,10 +385,8 @@ eek_renderer_real_render_key_label (EekRenderer *self,
{ {
EekRendererPrivate *priv = eek_renderer_get_instance_private (self); EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
EekSymbol *symbol; EekSymbol *symbol;
EekSymbolCategory category;
const gchar *label; const gchar *label;
EekBounds bounds; EekBounds bounds;
const TextProperty *prop;
PangoFontDescription *font; PangoFontDescription *font;
PangoLayoutLine *line; PangoLayoutLine *line;
gdouble scale; gdouble scale;
@ -523,12 +402,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
if (!priv->font) { if (!priv->font) {
const PangoFontDescription *base_font; const PangoFontDescription *base_font;
gdouble ascii_size, size; gdouble ascii_size, size;
EekThemeNode *theme_node;
theme_node = g_object_get_data (G_OBJECT(key), "theme-node");
if (theme_node)
base_font = eek_theme_node_get_font (theme_node);
else
base_font = pango_context_get_font_description (priv->pcontext); base_font = pango_context_get_font_description (priv->pcontext);
// FIXME: Base font size on the same size unit used for button sizing, // FIXME: Base font size on the same size unit used for button sizing,
// and make the default about 1/3 of the current row height // and make the default about 1/3 of the current row height
@ -546,15 +420,9 @@ eek_renderer_real_render_key_label (EekRenderer *self,
scale = MIN((bounds.width - priv->border_width) / bounds.width, scale = MIN((bounds.width - priv->border_width) / bounds.width,
(bounds.height - priv->border_width) / bounds.height); (bounds.height - priv->border_width) / bounds.height);
category = eek_symbol_get_category (symbol); font = pango_font_description_copy (priv->font);
prop = get_text_property_for_category (category);
font = pango_font_description_copy (prop->ascii ?
priv->ascii_font :
priv->font);
pango_font_description_set_size (font, pango_font_description_set_size (font,
(gint)round(pango_font_description_get_size (font) * (gint)round(pango_font_description_get_size (font) * scale));
prop->scale * scale));
pango_layout_set_font_description (layout, font); pango_layout_set_font_description (layout, font);
pango_font_description_free (font); pango_font_description_free (font);
@ -564,8 +432,6 @@ eek_renderer_real_render_key_label (EekRenderer *self,
pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
pango_layout_set_width (layout, pango_layout_set_width (layout,
PANGO_SCALE * bounds.width * scale); PANGO_SCALE * bounds.width * scale);
if (prop->ellipses)
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
} }
static void static void
@ -581,6 +447,17 @@ eek_renderer_real_render_key_outline (EekRenderer *self,
cairo_restore (cr); cairo_restore (cr);
} }
/*
* eek_renderer_real_render_key:
* @self: The renderer used to render the key
* @cr: The Cairo rendering context used for rendering
* @key: The key to be transformed
* @scale: The factor used to scale the key bounds before rendering
* @rotate: Whether to rotate the key by the angle defined for the key's
* in its section definition
*
* Renders a key separately from the normal keyboard rendering.
*/
static void static void
eek_renderer_real_render_key (EekRenderer *self, eek_renderer_real_render_key (EekRenderer *self,
cairo_t *cr, cairo_t *cr,
@ -589,9 +466,17 @@ eek_renderer_real_render_key (EekRenderer *self,
gboolean rotate) gboolean rotate)
{ {
EekRendererPrivate *priv = eek_renderer_get_instance_private (self); EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
EekBounds bounds;
eek_renderer_get_key_bounds (self, key, &bounds, rotate);
cairo_save (cr); cairo_save (cr);
/* Because this function is called separately from the keyboard rendering
function, the transformation for the context needs to be set up */
cairo_translate (cr, priv->origin_x, priv->origin_y); cairo_translate (cr, priv->origin_x, priv->origin_y);
cairo_scale (cr, priv->scale, priv->scale);
cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate); eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key)); render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
cairo_restore (cr); cairo_restore (cr);
@ -652,6 +537,10 @@ eek_renderer_set_property (GObject *object,
priv->pcontext = g_value_get_object (value); priv->pcontext = g_value_get_object (value);
g_object_ref (priv->pcontext); g_object_ref (priv->pcontext);
break; break;
case PROP_STYLE_CONTEXT:
priv->scontext = g_value_get_object (value);
g_object_ref (priv->scontext);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -723,7 +612,6 @@ eek_renderer_class_init (EekRendererClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec; GParamSpec *pspec;
klass->render_key_label = eek_renderer_real_render_key_label;
klass->render_key_outline = eek_renderer_real_render_key_outline; klass->render_key_outline = eek_renderer_real_render_key_outline;
klass->render_key = eek_renderer_real_render_key; klass->render_key = eek_renderer_real_render_key;
klass->render_keyboard = eek_renderer_real_render_keyboard; klass->render_keyboard = eek_renderer_real_render_keyboard;
@ -750,6 +638,15 @@ eek_renderer_class_init (EekRendererClass *klass)
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_PCONTEXT, PROP_PCONTEXT,
pspec); pspec);
pspec = g_param_spec_object ("style-context",
"GTK Style Context",
"GTK Style Context",
GTK_TYPE_STYLE_CONTEXT,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_STYLE_CONTEXT,
pspec);
} }
static void static void
@ -787,6 +684,24 @@ eek_renderer_init (EekRenderer *self)
g_str_equal, g_str_equal,
g_free, g_free,
(GDestroyNotify)cairo_surface_destroy); (GDestroyNotify)cairo_surface_destroy);
/* Create a default CSS provider and load a style sheet */
priv->css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (priv->css_provider,
"/sm/puri/squeekboard/style.css");
/* Create a style context for keys */
priv->key_context = gtk_style_context_new ();
gtk_style_context_add_class (priv->key_context, "key");
gtk_style_context_add_provider (priv->key_context,
GTK_STYLE_PROVIDER(priv->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
g_autoptr (GtkWidgetPath) path = NULL;
path = gtk_widget_path_new ();
gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
gtk_style_context_set_path (priv->key_context, path);
gtk_style_context_set_state (priv->key_context, GTK_STATE_FLAG_NORMAL);
} }
static void static void
@ -818,11 +733,13 @@ on_symbol_index_changed (EekKeyboard *keyboard,
EekRenderer * EekRenderer *
eek_renderer_new (EekKeyboard *keyboard, eek_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext) PangoContext *pcontext,
GtkStyleContext *scontext)
{ {
return g_object_new (EEK_TYPE_RENDERER, return g_object_new (EEK_TYPE_RENDERER,
"keyboard", keyboard, "keyboard", keyboard,
"pango-context", pcontext, "pango-context", pcontext,
"style-context", scontext,
NULL); NULL);
} }
@ -851,12 +768,11 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
scale = MIN(width / w, height / h); scale = MIN(width / w, height / h);
if (scale != priv->scale) {
priv->scale = scale; priv->scale = scale;
priv->origin_x = 0; /* Set the rendering offset in widget coordinates to center the keyboard */
priv->origin_y = 0; priv->origin_x = (width - (scale * w)) / 2;
priv->origin_y = (height - (scale * h)) / 2;
invalidate (renderer); invalidate (renderer);
}
} }
void void
@ -966,18 +882,6 @@ eek_renderer_create_pango_layout (EekRenderer *renderer)
return pango_layout_new (priv->pcontext); return pango_layout_new (priv->pcontext);
} }
void
eek_renderer_render_key_label (EekRenderer *renderer,
PangoLayout *layout,
EekKey *key)
{
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (EEK_IS_KEY(key));
EEK_RENDERER_GET_CLASS(renderer)->
render_key_label (renderer, layout, key);
}
void void
eek_renderer_render_key_outline (EekRenderer *renderer, eek_renderer_render_key_outline (EekRenderer *renderer,
cairo_t *cr, cairo_t *cr,
@ -1079,64 +983,21 @@ eek_renderer_set_default_background_color (EekRenderer *renderer,
void void
eek_renderer_get_foreground_color (EekRenderer *renderer, eek_renderer_get_foreground_color (EekRenderer *renderer,
EekElement *element, GtkStyleContext *context,
EekColor *color) EekColor *color)
{ {
EekThemeNode *theme_node;
g_return_if_fail (EEK_IS_RENDERER(renderer)); g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (color); g_return_if_fail (color);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
GtkStateFlags flags = GTK_STATE_FLAG_NORMAL;
GdkRGBA gcolor;
theme_node = g_object_get_data (G_OBJECT(element), "theme-node"); gtk_style_context_get_color (context, flags, &gcolor);
if (theme_node) color->red = gcolor.red;
eek_theme_node_get_foreground_color (theme_node, color); color->green = gcolor.green;
else color->blue = gcolor.blue;
memcpy (color, &priv->default_foreground_color, color->alpha = gcolor.alpha;
sizeof(EekColor));
}
void
eek_renderer_get_background_color (EekRenderer *renderer,
EekElement *element,
EekColor *color)
{
EekThemeNode *theme_node;
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (color);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
if (theme_node)
eek_theme_node_get_background_color (theme_node, color);
else
memcpy (color, &priv->default_background_color,
sizeof(EekColor));
}
void
eek_renderer_get_background_gradient (EekRenderer *renderer,
EekElement *element,
EekGradientType *type,
EekColor *start,
EekColor *end)
{
EekThemeNode *theme_node;
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (EEK_IS_ELEMENT(element));
g_return_if_fail (type);
g_return_if_fail (start);
g_return_if_fail (end);
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
if (theme_node)
eek_theme_node_get_background_gradient (theme_node, type, start, end);
else
*type = EEK_GRADIENT_NONE;
} }
struct _FindKeyByPositionCallbackData { struct _FindKeyByPositionCallbackData {
@ -1187,6 +1048,7 @@ find_key_by_position_key_callback (EekElement *element,
if (b1 == b2 && b2 == b3) { if (b1 == b2 && b2 == b3) {
data->key = EEK_KEY(element); data->key = EEK_KEY(element);
if (eek_key_has_label(data->key))
return 0; return 0;
} }
@ -1196,6 +1058,7 @@ find_key_by_position_key_callback (EekElement *element,
if (b1 == b2 && b2 == b3) { if (b1 == b2 && b2 == b3) {
data->key = EEK_KEY(element); data->key = EEK_KEY(element);
if (eek_key_has_label(data->key))
return 0; return 0;
} }
@ -1223,6 +1086,15 @@ find_key_by_position_section_callback (EekElement *element,
return data->key ? 0 : -1; return data->key ? 0 : -1;
} }
/**
* eek_renderer_find_key_by_position:
* @renderer: The renderer normally used to render the key
* @x: The horizontal widget coordinate of the position to test for a key
* @y: The vertical widget coordinate of the position to test for a key
*
* Return value: the key located at the position x, y in widget coordinates, or
* NULL if no key can be found at that location
**/
EekKey * EekKey *
eek_renderer_find_key_by_position (EekRenderer *renderer, eek_renderer_find_key_by_position (EekRenderer *renderer,
gdouble x, gdouble x,
@ -1234,23 +1106,22 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL); g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
x /= priv->scale;
y /= priv->scale;
x -= priv->origin_x;
y -= priv->origin_y;
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
if (x < bounds.x || /* Transform from widget coordinates to keyboard coordinates */
y < bounds.y || x = (x - priv->origin_x)/priv->scale - bounds.x;
y = (y - priv->origin_y)/priv->scale - bounds.y;
if (x < 0 ||
y < 0 ||
x > bounds.width || x > bounds.width ||
y > bounds.height) y > bounds.height)
return NULL; return NULL;
data.point.x = x; data.point.x = x;
data.point.y = y; data.point.y = y;
data.origin.x = bounds.x; data.origin.x = 0;
data.origin.y = bounds.y; data.origin.y = 0;
data.key = NULL; data.key = NULL;
data.renderer = renderer; data.renderer = renderer;
@ -1259,117 +1130,3 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
&data); &data);
return data.key; return data.key;
} }
struct _CreateThemeNodeData {
EekThemeContext *context;
EekThemeNode *parent;
EekRenderer *renderer;
};
typedef struct _CreateThemeNodeData CreateThemeNodeData;
void
create_theme_node_key_callback (EekElement *element,
gpointer user_data)
{
CreateThemeNodeData *data = user_data;
EekThemeNode *theme_node;
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
theme_node = eek_theme_node_new (data->context,
data->parent,
priv->theme,
EEK_TYPE_KEY,
eek_element_get_name (element),
"key",
NULL,
NULL);
g_object_set_data_full (G_OBJECT(element),
"theme-node",
theme_node,
(GDestroyNotify)g_object_unref);
theme_node = eek_theme_node_new (data->context,
data->parent,
priv->theme,
EEK_TYPE_KEY,
eek_element_get_name (element),
"key",
"active",
NULL);
g_object_set_data_full (G_OBJECT(element),
"theme-node-pressed",
theme_node,
(GDestroyNotify)g_object_unref);
}
void
create_theme_node_section_callback (EekElement *element,
gpointer user_data)
{
CreateThemeNodeData *data = user_data;
EekThemeNode *theme_node, *parent;
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
theme_node = eek_theme_node_new (data->context,
data->parent,
priv->theme,
EEK_TYPE_SECTION,
eek_element_get_name (element),
"section",
NULL,
NULL);
g_object_set_data_full (G_OBJECT(element),
"theme-node",
theme_node,
(GDestroyNotify)g_object_unref);
parent = data->parent;
data->parent = theme_node;
eek_container_foreach_child (EEK_CONTAINER(element),
create_theme_node_key_callback,
data);
data->parent = parent;
}
void
eek_renderer_set_theme (EekRenderer *renderer,
EekTheme *theme)
{
EekThemeContext *theme_context;
EekThemeNode *theme_node;
CreateThemeNodeData data;
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (EEK_IS_THEME(theme));
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
g_return_if_fail (priv->keyboard);
if (priv->theme)
g_object_unref (priv->theme);
priv->theme = g_object_ref (theme);
theme_context = eek_theme_context_new ();
theme_node = eek_theme_node_new (theme_context,
NULL,
priv->theme,
EEK_TYPE_KEYBOARD,
"keyboard",
"keyboard",
NULL,
NULL);
g_object_set_data_full (G_OBJECT(priv->keyboard),
"theme-node",
theme_node,
(GDestroyNotify)g_object_unref);
data.context = theme_context;
data.parent = theme_node;
data.renderer = renderer;
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
create_theme_node_section_callback,
&data);
}

View File

@ -25,8 +25,6 @@
#include "eek-keyboard.h" #include "eek-keyboard.h"
#include "eek-keysym.h" #include "eek-keysym.h"
#include "eek-types.h" #include "eek-types.h"
#include "eek-theme.h"
#include "eek-theme-context.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -37,10 +35,6 @@ struct _EekRendererClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
void (* render_key_label) (EekRenderer *self,
PangoLayout *layout,
EekKey *key);
void (* render_key_outline) (EekRenderer *self, void (* render_key_outline) (EekRenderer *self,
cairo_t *cr, cairo_t *cr,
EekKey *key, EekKey *key,
@ -68,7 +62,8 @@ struct _EekRendererClass
GType eek_renderer_get_type (void) G_GNUC_CONST; GType eek_renderer_get_type (void) G_GNUC_CONST;
EekRenderer *eek_renderer_new (EekKeyboard *keyboard, EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext); PangoContext *pcontext,
GtkStyleContext *scontext);
void eek_renderer_set_allocation_size void eek_renderer_set_allocation_size
(EekRenderer *renderer, (EekRenderer *renderer,
gdouble width, gdouble width,
@ -120,18 +115,8 @@ void eek_renderer_set_default_background_color
const EekColor *color); const EekColor *color);
void eek_renderer_get_foreground_color void eek_renderer_get_foreground_color
(EekRenderer *renderer, (EekRenderer *renderer,
EekElement *element, GtkStyleContext *context,
EekColor *color); EekColor *color);
void eek_renderer_get_background_color
(EekRenderer *renderer,
EekElement *element,
EekColor *color);
void eek_renderer_get_background_gradient
(EekRenderer *renderer,
EekElement *element,
EekGradientType *type,
EekColor *start,
EekColor *end);
void eek_renderer_set_border_width (EekRenderer *renderer, void eek_renderer_set_border_width (EekRenderer *renderer,
gdouble border_width); gdouble border_width);
EekKey *eek_renderer_find_key_by_position EekKey *eek_renderer_find_key_by_position
@ -145,8 +130,5 @@ void eek_renderer_apply_transformation_for_key
gdouble scale, gdouble scale,
gboolean rotate); gboolean rotate);
void eek_renderer_set_theme (EekRenderer *renderer,
EekTheme *theme);
G_END_DECLS G_END_DECLS
#endif /* EEK_RENDERER_H */ #endif /* EEK_RENDERER_H */

View File

@ -61,7 +61,7 @@ typedef struct _EekRow EekRow;
typedef struct _EekSectionPrivate typedef struct _EekSectionPrivate
{ {
gint angle; gint angle;
GSList *rows; EekRow row;
EekModifierType modifiers; EekModifierType modifiers;
} EekSectionPrivate; } EekSectionPrivate;
@ -70,9 +70,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
static gint static gint
eek_section_real_get_n_rows (EekSection *self) eek_section_real_get_n_rows (EekSection *self)
{ {
EekSectionPrivate *priv = eek_section_get_instance_private (self); return 1;
return g_slist_length (priv->rows);
} }
static void static void
@ -80,13 +78,14 @@ eek_section_real_add_row (EekSection *self,
gint num_columns, gint num_columns,
EekOrientation orientation) EekOrientation orientation)
{ {
EekSectionPrivate *priv = eek_section_get_instance_private (self); EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
EekRow *row; priv->row.num_columns = num_columns;
priv->row.orientation = orientation;
/*
row = g_slice_new (EekRow); row = g_slice_new (EekRow);
row->num_columns = num_columns; row->num_columns = num_columns;
row->orientation = orientation; row->orientation = orientation;
priv->rows = g_slist_append (priv->rows, row); priv->rows = g_slist_append (priv->rows, row);*/
} }
static void static void
@ -95,15 +94,14 @@ eek_section_real_get_row (EekSection *self,
gint *num_columns, gint *num_columns,
EekOrientation *orientation) EekOrientation *orientation)
{ {
EekSectionPrivate *priv = eek_section_get_instance_private (self); EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
EekRow *row; EekRow *row = &priv->row;
if (num_columns) {
row = g_slist_nth_data (priv->rows, index);
g_return_if_fail (row);
if (num_columns)
*num_columns = row->num_columns; *num_columns = row->num_columns;
if (orientation) }
if (orientation) {
*orientation = row->orientation; *orientation = row->orientation;
}
} }
static void static void
@ -123,28 +121,16 @@ on_unlocked (EekKey *key,
static EekKey * static EekKey *
eek_section_real_create_key (EekSection *self, eek_section_real_create_key (EekSection *self,
const gchar *name, const gchar *name,
gint keycode, gint keycode)
gint column_index,
gint row_index)
{ {
EekKey *key; EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
gint num_rows;
EekRow *row;
num_rows = eek_section_get_n_rows (self); EekRow *row = &priv->row;
g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL); row->num_columns++;
EekSectionPrivate *priv = eek_section_get_instance_private (self); EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
row = g_slist_nth_data (priv->rows, row_index);
if (row->num_columns < column_index + 1)
row->num_columns = column_index + 1;
key = g_object_new (EEK_TYPE_KEY,
"name", name, "name", name,
"keycode", keycode, "keycode", keycode,
"column", column_index,
"row", row_index,
NULL); NULL);
g_return_val_if_fail (key, NULL); g_return_val_if_fail (key, NULL);
@ -225,12 +211,7 @@ static void
eek_section_finalize (GObject *object) eek_section_finalize (GObject *object)
{ {
EekSection *self = EEK_SECTION (object); EekSection *self = EEK_SECTION (object);
EekSectionPrivate *priv = eek_section_get_instance_private (self); EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
GSList *head;
for (head = priv->rows; head; head = g_slist_next (head))
g_slice_free (EekRow, head->data);
g_slist_free (priv->rows);
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object); G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
} }
@ -475,16 +456,12 @@ eek_section_get_row (EekSection *section,
EekKey * EekKey *
eek_section_create_key (EekSection *section, eek_section_create_key (EekSection *section,
const gchar *name, const gchar *name,
gint keycode, gint keycode)
gint column,
gint row)
{ {
g_return_val_if_fail (EEK_IS_SECTION(section), NULL); g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
return EEK_SECTION_GET_CLASS(section)->create_key (section, return EEK_SECTION_GET_CLASS(section)->create_key (section,
name, name,
keycode, keycode);
column,
row);
} }
const double keyspacing = 4.0; const double keyspacing = 4.0;

View File

@ -63,9 +63,7 @@ struct _EekSectionClass
EekKey *(* create_key) (EekSection *self, EekKey *(* create_key) (EekSection *self,
const gchar *name, const gchar *name,
gint keycode, gint keycode);
gint row,
gint column);
/* signals */ /* signals */
void (* key_pressed) (EekSection *self, void (* key_pressed) (EekSection *self,
@ -101,9 +99,7 @@ void eek_section_get_row (EekSection *section,
EekKey *eek_section_create_key (EekSection *section, EekKey *eek_section_create_key (EekSection *section,
const gchar *name, const gchar *name,
gint keycode, gint keycode);
gint column,
gint row);
EekKey *eek_section_find_key_by_keycode (EekSection *section, EekKey *eek_section_find_key_by_keycode (EekSection *section,
guint keycode); guint keycode);

View File

@ -36,10 +36,8 @@ eek_serializable_get_type (void)
{ {
static GType iface_type = 0; static GType iface_type = 0;
if (iface_type == 0) { if (iface_type == 0) {
static const GTypeInfo info = { static GTypeInfo info = {
sizeof (EekSerializableIface), .class_size = sizeof (EekSerializableIface)
NULL,
NULL,
}; };
iface_type = g_type_register_static (G_TYPE_INTERFACE, iface_type = g_type_register_static (G_TYPE_INTERFACE,
"EekSerializable", "EekSerializable",

View File

@ -36,24 +36,19 @@ EekSymbolMatrix *
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix) eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
{ {
EekSymbolMatrix *retval; EekSymbolMatrix *retval;
gint i, num_symbols = matrix->num_groups * matrix->num_levels; guint num_symbols = matrix->num_groups * matrix->num_levels;
retval = g_slice_dup (EekSymbolMatrix, matrix); retval = g_slice_dup (EekSymbolMatrix, matrix);
retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols, retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
matrix->data); matrix->data);
for (i = 0; i < num_symbols; i++) // FIXME: do a deep copy over the data in EekSymbol
if (retval->data[i])
g_object_ref (retval->data[i]);
return retval; return retval;
} }
void void
eek_symbol_matrix_free (EekSymbolMatrix *matrix) eek_symbol_matrix_free (EekSymbolMatrix *matrix)
{ {
gint i, num_symbols = matrix->num_groups * matrix->num_levels; guint num_symbols = matrix->num_groups * matrix->num_levels;
for (i = 0; i < num_symbols; i++)
if (matrix->data[i])
g_object_unref (matrix->data[i]);
g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data); g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
g_slice_free (EekSymbolMatrix, matrix); g_slice_free (EekSymbolMatrix, matrix);
} }
@ -79,7 +74,6 @@ eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
{ {
g_return_if_fail (group >= 0 && group < matrix->num_groups); g_return_if_fail (group >= 0 && group < matrix->num_groups);
g_return_if_fail (level >= 0 && level < matrix->num_levels); g_return_if_fail (level >= 0 && level < matrix->num_levels);
g_return_if_fail (EEK_IS_SYMBOL(symbol));
matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol); matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
} }

View File

@ -28,270 +28,42 @@
#include "config.h" #include "config.h"
#include "eek-symbol.h" #include "eek-symbol.h"
#include "eek-serializable.h"
#include "eek-enumtypes.h" #include "eek-enumtypes.h"
enum { void
PROP_0, eek_symbol_destroy (EekSymbol *priv)
PROP_NAME,
PROP_LABEL,
PROP_CATEGORY,
PROP_MODIFIER_MASK,
PROP_ICON_NAME,
PROP_TOOLTIP,
PROP_LAST
};
typedef struct _EekSymbolPrivate
{ {
gchar *name;
gchar *label;
EekSymbolCategory category;
EekModifierType modifier_mask;
gchar *icon_name;
gchar *tooltip;
} EekSymbolPrivate;
static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_TYPE_EXTENDED (EekSymbol,
eek_symbol,
G_TYPE_OBJECT,
0, /* GTypeFlags */
G_ADD_PRIVATE (EekSymbol)
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init))
static void
eek_symbol_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
#define NOTNULL(s) ((s) != NULL ? (s) : "")
g_variant_builder_add (builder, "s", NOTNULL(priv->name));
g_variant_builder_add (builder, "s", NOTNULL(priv->label));
g_variant_builder_add (builder, "u", priv->category);
g_variant_builder_add (builder, "u", priv->modifier_mask);
g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
#undef NOTNULL
}
static gsize
eek_symbol_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
g_variant_get_child (variant, index++, "s", &priv->name);
g_variant_get_child (variant, index++, "s", &priv->label);
g_variant_get_child (variant, index++, "u", &priv->category);
g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
g_variant_get_child (variant, index++, "s", &priv->icon_name);
g_variant_get_child (variant, index++, "s", &priv->tooltip);
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
iface->serialize = eek_symbol_real_serialize;
iface->deserialize = eek_symbol_real_deserialize;
}
static void
eek_symbol_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_NAME:
eek_symbol_set_name (EEK_SYMBOL(object), g_value_get_string (value));
break;
case PROP_LABEL:
eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value));
break;
case PROP_CATEGORY:
eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_enum (value));
break;
case PROP_MODIFIER_MASK:
eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
g_value_get_flags (value));
break;
case PROP_ICON_NAME:
eek_symbol_set_icon_name (EEK_SYMBOL(object),
g_value_get_string (value));
break;
case PROP_TOOLTIP:
eek_symbol_set_tooltip (EEK_SYMBOL(object),
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_symbol_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, eek_symbol_get_name (EEK_SYMBOL(object)));
break;
case PROP_LABEL:
g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object)));
break;
case PROP_CATEGORY:
g_value_set_enum (value, eek_symbol_get_category (EEK_SYMBOL(object)));
break;
case PROP_MODIFIER_MASK:
g_value_set_flags (value,
eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
break;
case PROP_ICON_NAME:
g_value_set_string (value,
eek_symbol_get_icon_name (EEK_SYMBOL(object)));
break;
case PROP_TOOLTIP:
g_value_set_string (value,
eek_symbol_get_tooltip (EEK_SYMBOL(object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_symbol_finalize (GObject *object)
{
EekSymbol *self = EEK_SYMBOL (object);
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
g_free (priv->name); g_free (priv->name);
g_free (priv->label); g_free (priv->label);
g_free (priv->icon_name); g_free (priv->icon_name);
g_free (priv->tooltip); g_free (priv->tooltip);
G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object); g_free(priv->text);
g_free(priv);
} }
static void
eek_symbol_class_init (EekSymbolClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->set_property = eek_symbol_set_property;
gobject_class->get_property = eek_symbol_get_property;
gobject_class->finalize = eek_symbol_finalize;
pspec = g_param_spec_string ("name",
"Name",
"Canonical name of the symbol",
NULL,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_NAME, pspec);
pspec = g_param_spec_string ("label",
"Label",
"Text used to display the symbol",
NULL,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
pspec = g_param_spec_enum ("category",
"Category",
"Category of the symbol",
EEK_TYPE_SYMBOL_CATEGORY,
EEK_SYMBOL_CATEGORY_UNKNOWN,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec);
pspec = g_param_spec_flags ("modifier-mask",
"Modifier mask",
"Modifier mask of the symbol",
EEK_TYPE_MODIFIER_TYPE,
0,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
pspec = g_param_spec_string ("icon-name",
"Icon name",
"Icon name used to render the symbol",
NULL,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
pspec = g_param_spec_string ("tooltip",
"Tooltip",
"Tooltip text",
NULL,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
}
static void
eek_symbol_init (EekSymbol *self)
{
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
}
/**
* eek_symbol_new:
* @name: name of the symbol
*
* Create a new #EekSymbol with @name.
*/
EekSymbol * EekSymbol *
eek_symbol_new (const gchar *name) eek_symbol_new (const gchar *name)
{ {
return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL); EekSymbol *self = g_new0(EekSymbol, 1);
eek_symbol_set_name(self, name);
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
return self;
} }
/**
* eek_symbol_set_name:
* @symbol: an #EekSymbol
* @name: name of the symbol
*
* Set the name of @symbol to @name.
*/
void void
eek_symbol_set_name (EekSymbol *symbol, eek_symbol_set_name (EekSymbol *symbol,
const gchar *name) const gchar *name)
{ {
g_return_if_fail (EEK_IS_SYMBOL(symbol)); g_free (symbol->name);
symbol->name = g_strdup (name);
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
g_free (priv->name);
priv->name = g_strdup (name);
} }
/**
* eek_symbol_get_name:
* @symbol: an #EekSymbol
*
* Get the name of @symbol.
*/
const gchar * const gchar *
eek_symbol_get_name (EekSymbol *symbol) eek_symbol_get_name (EekSymbol *symbol)
{ {
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL); if (symbol->name == NULL || *symbol->name == '\0')
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
if (priv->name == NULL || *priv->name == '\0')
return NULL; return NULL;
return priv->name; return symbol->name;
} }
/** /**
@ -305,12 +77,8 @@ void
eek_symbol_set_label (EekSymbol *symbol, eek_symbol_set_label (EekSymbol *symbol,
const gchar *label) const gchar *label)
{ {
g_return_if_fail (EEK_IS_SYMBOL(symbol)); g_free (symbol->label);
symbol->label = g_strdup (label);
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
g_free (priv->label);
priv->label = g_strdup (label);
} }
/** /**
@ -322,47 +90,9 @@ eek_symbol_set_label (EekSymbol *symbol,
const gchar * const gchar *
eek_symbol_get_label (EekSymbol *symbol) eek_symbol_get_label (EekSymbol *symbol)
{ {
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL); if (symbol->label == NULL || *symbol->label == '\0')
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
if (priv->label == NULL || *priv->label == '\0')
return NULL; return NULL;
return priv->label; return symbol->label;
}
/**
* eek_symbol_set_category:
* @symbol: an #EekSymbol
* @category: an #EekSymbolCategory
*
* Set symbol category of @symbol to @category.
*/
void
eek_symbol_set_category (EekSymbol *symbol,
EekSymbolCategory category)
{
g_return_if_fail (EEK_IS_SYMBOL(symbol));
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
priv->category = category;
}
/**
* eek_symbol_get_category:
* @symbol: an #EekSymbol
*
* Get symbol category of @symbol.
*/
EekSymbolCategory
eek_symbol_get_category (EekSymbol *symbol)
{
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
return priv->category;
} }
/** /**
@ -376,11 +106,7 @@ void
eek_symbol_set_modifier_mask (EekSymbol *symbol, eek_symbol_set_modifier_mask (EekSymbol *symbol,
EekModifierType mask) EekModifierType mask)
{ {
g_return_if_fail (EEK_IS_SYMBOL(symbol)); symbol->modifier_mask = mask;
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
priv->modifier_mask = mask;
} }
/** /**
@ -392,131 +118,43 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
EekModifierType EekModifierType
eek_symbol_get_modifier_mask (EekSymbol *symbol) eek_symbol_get_modifier_mask (EekSymbol *symbol)
{ {
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0); return symbol->modifier_mask;
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
return priv->modifier_mask;
} }
/**
* eek_symbol_is_modifier:
* @symbol: an #EekSymbol
*
* Check if @symbol is a modifier.
* Returns: %TRUE if @symbol is a modifier.
*/
gboolean gboolean
eek_symbol_is_modifier (EekSymbol *symbol) eek_symbol_is_modifier (EekSymbol *symbol)
{ {
return eek_symbol_get_modifier_mask (symbol) != 0; return eek_symbol_get_modifier_mask (symbol) != 0;
} }
/**
* eek_symbol_set_icon_name:
* @symbol: an #EekSymbol
* @icon_name: icon name of @symbol
*
* Set the icon name of @symbol to @icon_name.
*/
void void
eek_symbol_set_icon_name (EekSymbol *symbol, eek_symbol_set_icon_name (EekSymbol *symbol,
const gchar *icon_name) const gchar *icon_name)
{ {
g_return_if_fail (EEK_IS_SYMBOL(symbol)); g_free (symbol->icon_name);
symbol->icon_name = g_strdup (icon_name);
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
g_free (priv->icon_name);
priv->icon_name = g_strdup (icon_name);
} }
/**
* eek_symbol_get_icon_name:
* @symbol: an #EekSymbol
*
* Get the icon name of @symbol.
*/
const gchar * const gchar *
eek_symbol_get_icon_name (EekSymbol *symbol) eek_symbol_get_icon_name (EekSymbol *symbol)
{ {
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL); if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
if (priv->icon_name == NULL || *priv->icon_name == '\0')
return NULL; return NULL;
return priv->icon_name; return symbol->icon_name;
} }
/**
* eek_symbol_set_tooltip:
* @symbol: an #EekSymbol
* @tooltip: icon name of @symbol
*
* Set the tooltip text of @symbol to @tooltip.
*/
void void
eek_symbol_set_tooltip (EekSymbol *symbol, eek_symbol_set_tooltip (EekSymbol *symbol,
const gchar *tooltip) const gchar *tooltip)
{ {
g_return_if_fail (EEK_IS_SYMBOL(symbol)); g_free (symbol->tooltip);
symbol->tooltip = g_strdup (tooltip);
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
g_free (priv->tooltip);
priv->tooltip = g_strdup (tooltip);
} }
/**
* eek_symbol_get_tooltip:
* @symbol: an #EekSymbol
*
* Get the tooltip text of @symbol.
*/
const gchar * const gchar *
eek_symbol_get_tooltip (EekSymbol *symbol) eek_symbol_get_tooltip (EekSymbol *symbol)
{ {
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL); if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
if (priv->tooltip == NULL || *priv->tooltip == '\0')
return NULL; return NULL;
return priv->tooltip; return symbol->tooltip;
}
static const struct {
EekSymbolCategory category;
gchar *name;
} category_names[] = {
{ EEK_SYMBOL_CATEGORY_LETTER, "letter" },
{ EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
{ EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
{ EEK_SYMBOL_CATEGORY_USER0, "user0" },
{ EEK_SYMBOL_CATEGORY_USER1, "user1" },
{ EEK_SYMBOL_CATEGORY_USER2, "user2" },
{ EEK_SYMBOL_CATEGORY_USER3, "user3" },
{ EEK_SYMBOL_CATEGORY_USER4, "user4" },
{ EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
};
const gchar *
eek_symbol_category_get_name (EekSymbolCategory category)
{
gint i;
for (i = 0; i < G_N_ELEMENTS(category_names); i++)
if (category_names[i].category == category)
return category_names[i].name;
return NULL;
}
EekSymbolCategory
eek_symbol_category_from_name (const gchar *name)
{
gint i;
for (i = 0; i < G_N_ELEMENTS(category_names); i++)
if (g_strcmp0 (category_names[i].name, name) == 0)
return category_names[i].category;
return EEK_SYMBOL_CATEGORY_UNKNOWN;
} }

View File

@ -58,20 +58,27 @@ typedef enum {
EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
} EekSymbolCategory; } EekSymbolCategory;
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
/** typedef struct _EekSymbol
* EekSymbolClass: {
*/ /// Canonical name of the symbol
struct _EekSymbolClass { gchar *name;
/*< private >*/ /// Text used to display the symbol
GObjectClass parent_class; gchar *label;
}; EekSymbolCategory category;
EekModifierType modifier_mask;
/// Icon name used to render the symbol
gchar *icon_name;
/// Tooltip text
gchar *tooltip;
GType eek_symbol_get_type (void) G_GNUC_CONST; // May not be present
guint xkeysym;
gchar *text;
} EekSymbol;
EekSymbol *eek_symbol_new (const gchar *name); EekSymbol *eek_symbol_new (const gchar *name);
void eek_symbol_free (EekSymbol *symbol);
void eek_symbol_set_name (EekSymbol *symbol, void eek_symbol_set_name (EekSymbol *symbol,
const gchar *name); const gchar *name);
const gchar *eek_symbol_get_name (EekSymbol *symbol); const gchar *eek_symbol_get_name (EekSymbol *symbol);

View File

@ -26,160 +26,18 @@
#include "config.h" #include "config.h"
#include "eek-text.h" #include "eek-text.h"
#include "eek-serializable.h"
enum { EekSymbol *
PROP_0,
PROP_TEXT,
PROP_LAST
};
typedef struct _EekTextPrivate
{
gchar *text;
} EekTextPrivate;
static void eek_serializable_iface_init (EekSerializableIface *iface);
G_DEFINE_TYPE_EXTENDED (EekText,
eek_text,
EEK_TYPE_SYMBOL,
0, /* GTypeFlags */
G_ADD_PRIVATE (EekText)
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
eek_serializable_iface_init))
static EekSerializableIface *eek_text_parent_serializable_iface;
static void
eek_text_real_serialize (EekSerializable *self,
GVariantBuilder *builder)
{
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
eek_text_parent_serializable_iface->serialize (self, builder);
g_variant_builder_add (builder, "s", priv->text);
}
static gsize
eek_text_real_deserialize (EekSerializable *self,
GVariant *variant,
gsize index)
{
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
index = eek_text_parent_serializable_iface->deserialize (self,
variant,
index);
g_variant_get_child (variant, index++, "s", &priv->text);
return index;
}
static void
eek_serializable_iface_init (EekSerializableIface *iface)
{
eek_text_parent_serializable_iface =
g_type_interface_peek_parent (iface);
iface->serialize = eek_text_real_serialize;
iface->deserialize = eek_text_real_deserialize;
}
static void
eek_text_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekText *self = EEK_TEXT (object);
EekTextPrivate *priv = eek_text_get_instance_private (self);
switch (prop_id) {
case PROP_TEXT:
g_free (priv->text);
priv->text = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_text_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekText *self = EEK_TEXT (object);
EekTextPrivate *priv = eek_text_get_instance_private (self);
switch (prop_id) {
case PROP_TEXT:
g_value_set_string (value, priv->text);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_text_finalize (GObject *object)
{
EekText *self = EEK_TEXT (object);
EekTextPrivate *priv = eek_text_get_instance_private (self);
g_free (priv->text);
G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
}
static void
eek_text_class_init (EekTextClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->set_property = eek_text_set_property;
gobject_class->get_property = eek_text_get_property;
gobject_class->finalize = eek_text_finalize;
pspec = g_param_spec_string ("text",
"Text",
"Text",
NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
}
static void
eek_text_init (EekText *self)
{
/* void */
}
EekText *
eek_text_new (const gchar *text) eek_text_new (const gchar *text)
{ {
return g_object_new (EEK_TYPE_TEXT, EekSymbol *ret = eek_symbol_new("");
"label", text, eek_symbol_set_label(ret, text);
"category", EEK_SYMBOL_CATEGORY_FUNCTION, ret->text = g_strdup (text);
"text", text, return ret;
NULL);
} }
/**
* eek_text_get_text:
* @text: an #EekText
*
* Get a text value associated with @text
*/
const gchar * const gchar *
eek_text_get_text (EekText *text) eek_text_get_text (EekSymbol *text)
{ {
EekTextPrivate *priv = eek_text_get_instance_private (text); return text->text;
return priv->text;
} }

View File

@ -29,17 +29,9 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_TEXT (eek_text_get_type())
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
struct _EekTextClass {
/*< private >*/
EekSymbolClass parent_class;
};
GType eek_text_get_type (void) G_GNUC_CONST; GType eek_text_get_type (void) G_GNUC_CONST;
EekText *eek_text_new (const gchar *text); EekSymbol *eek_text_new (const gchar *text);
const gchar *eek_text_get_text (EekText *text); const gchar *eek_text_get_text (EekSymbol *text);
G_END_DECLS G_END_DECLS

View File

@ -1,287 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
/*
* eek-theme-context.c: holds global information about a tree of styled objects
*
* Copyright 2009, 2010 Red Hat, Inc.
* Copyright 2009 Florian Müllner
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "eek-theme.h"
#include "eek-theme-context.h"
struct _EekThemeContext {
GObject parent;
double resolution;
PangoFontDescription *font;
EekThemeNode *root_node;
EekTheme *theme;
};
struct _EekThemeContextClass {
GObjectClass parent_class;
};
#define DEFAULT_RESOLUTION 96.
#define DEFAULT_FONT "sans-serif 10"
enum
{
CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (EekThemeContext, eek_theme_context, G_TYPE_OBJECT)
static void
eek_theme_context_finalize (GObject *object)
{
EekThemeContext *context = EEK_THEME_CONTEXT (object);
if (context->root_node)
g_object_unref (context->root_node);
if (context->theme)
g_object_unref (context->theme);
pango_font_description_free (context->font);
G_OBJECT_CLASS (eek_theme_context_parent_class)->finalize (object);
}
static void
eek_theme_context_class_init (EekThemeContextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = eek_theme_context_finalize;
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, /* no default handler slot */
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
eek_theme_context_init (EekThemeContext *context)
{
context->resolution = DEFAULT_RESOLUTION;
context->font = pango_font_description_from_string (DEFAULT_FONT);
}
/**
* eek_theme_context_new:
*
* Create a new theme context.
*/
EekThemeContext *
eek_theme_context_new (void)
{
EekThemeContext *context;
context = g_object_new (EEK_TYPE_THEME_CONTEXT, NULL);
return context;
}
static void
eek_theme_context_changed (EekThemeContext *context)
{
EekThemeNode *old_root = context->root_node;
context->root_node = NULL;
g_signal_emit (context, signals[CHANGED], 0);
if (old_root)
g_object_unref (old_root);
}
/**
* eek_theme_context_set_theme:
* @context: an #EekThemeContext
* @theme: an #EekTheme
*
* Sets the default set of theme stylesheets for the context. This theme will
* be used for the root node and for nodes descending from it, unless some other
* style is explicitely specified.
*/
void
eek_theme_context_set_theme (EekThemeContext *context,
EekTheme *theme)
{
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
g_return_if_fail (theme == NULL || EEK_IS_THEME (theme));
if (context->theme != theme)
{
if (context->theme)
g_object_unref (context->theme);
context->theme = theme;
if (context->theme)
g_object_ref (context->theme);
eek_theme_context_changed (context);
}
}
/**
* eek_theme_context_get_theme:
* @context: a #EekThemeContext
*
* Gets the default theme for the context. See eek_theme_context_set_theme()
*
* Return value: (transfer none): the default theme for the context
*/
EekTheme *
eek_theme_context_get_theme (EekThemeContext *context)
{
g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
return context->theme;
}
/**
* eek_theme_context_set_resolution:
* @context: a #EekThemeContext
* @resolution: resolution of the context (number of pixels in an "inch")
*
* Sets the resolution of the theme context. This is the scale factor
* used to convert between points and the length units pt, in, and cm.
* This does not necessarily need to correspond to the actual number
* resolution of the device. A value of 72. means that points and
* pixels are identical. The default value is 96.
*/
void
eek_theme_context_set_resolution (EekThemeContext *context,
double resolution)
{
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
if (resolution == context->resolution)
return;
context->resolution = resolution;
eek_theme_context_changed (context);
}
/**
* eek_theme_context_set_default_resolution:
* @context: a #EekThemeContext
*
* Sets the resolution of the theme context to the default value of 96.
* See eek_theme_context_set_resolution().
*/
void
eek_theme_context_set_default_resolution (EekThemeContext *context)
{
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
if (context->resolution == DEFAULT_RESOLUTION)
return;
context->resolution = DEFAULT_RESOLUTION;
eek_theme_context_changed (context);
}
/**
* eek_theme_context_get_resolution:
* @context: a #EekThemeContext
*
* Gets the current resolution of the theme context.
* See eek_theme_context_set_resolution().
*
* Return value: the resolution (in dots-per-"inch")
*/
double
eek_theme_context_get_resolution (EekThemeContext *context)
{
g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
return context->resolution;
}
/**
* eek_theme_context_set_font:
* @context: a #EekThemeContext
* @font: the default font for theme context
*
* Sets the default font for the theme context. This is the font that
* is inherited by the root node of the tree of theme nodes. If the
* font is not overriden, then this font will be used. If the font is
* partially modified (for example, with 'font-size: 110%', then that
* modification is based on this font.
*/
void
eek_theme_context_set_font (EekThemeContext *context,
const PangoFontDescription *font)
{
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
g_return_if_fail (font != NULL);
if (context->font == font ||
pango_font_description_equal (context->font, font))
return;
pango_font_description_free (context->font);
context->font = pango_font_description_copy (font);
eek_theme_context_changed (context);
}
/**
* eek_theme_context_get_font:
* @context: a #EekThemeContext
*
* Gets the default font for the theme context. See eek_theme_context_set_font().
*
* Return value: the default font for the theme context.
*/
const PangoFontDescription *
eek_theme_context_get_font (EekThemeContext *context)
{
g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
return context->font;
}
/**
* eek_theme_context_get_root_node:
* @context: a #EekThemeContext
*
* Gets the root node of the tree of theme style nodes that associated with this
* context. For the node tree associated with a stage, this node represents
* styles applied to the stage itself.
*
* Return value: (transfer none): the root node of the context's style tree
*/
EekThemeNode *
eek_theme_context_get_root_node (EekThemeContext *context)
{
if (context->root_node == NULL)
context->root_node = eek_theme_node_new (context, NULL, context->theme,
G_TYPE_NONE, NULL, NULL, NULL, NULL);
return context->root_node;
}

View File

@ -1,78 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* eek-theme-context.c: holds global information about a tree of styled objects
*
* Copyright 2009, 2010 Red Hat, Inc.
* Copyright 2009 Florian Müllner
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __EEK_THEME_CONTEXT_H__
#define __EEK_THEME_CONTEXT_H__
#include <pango/pango.h>
#include "eek-theme-node.h"
G_BEGIN_DECLS
/**
* SECTION:eek-theme-context
* @short_description: holds global information about a tree of styled objects
*
* #EekThemeContext is responsible for managing information global to
* a tree of styled objects, such as the set of stylesheets or the
* default font.
*/
typedef struct _EekThemeContextClass EekThemeContextClass;
#define EEK_TYPE_THEME_CONTEXT (eek_theme_context_get_type ())
#define EEK_THEME_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
#define EEK_THEME_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
#define EEK_IS_THEME_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
#define EEK_IS_THEME_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
#define EEK_THEME_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
GType eek_theme_context_get_type
(void) G_GNUC_CONST;
EekThemeContext *eek_theme_context_new
(void);
void eek_theme_context_set_theme
(EekThemeContext *context,
EekTheme *theme);
EekTheme * eek_theme_context_get_theme
(EekThemeContext *context);
void eek_theme_context_set_resolution
(EekThemeContext *context,
gdouble resolution);
void eek_theme_context_set_default_resolution
(EekThemeContext *context);
double eek_theme_context_get_resolution
(EekThemeContext *context);
void eek_theme_context_set_font
(EekThemeContext *context,
const PangoFontDescription *font);
const PangoFontDescription *eek_theme_context_get_font
(EekThemeContext *context);
EekThemeNode * eek_theme_context_get_root_node
(EekThemeContext *context);
G_END_DECLS
#endif /* __EEK_THEME_CONTEXT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,141 +0,0 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __EEK_THEME_NODE_H__
#define __EEK_THEME_NODE_H__
#include <pango/pango.h>
#include "eek-types.h"
G_BEGIN_DECLS
/**
* SECTION:eek-theme-node
* @short_description: style information for one node in a tree of
* themed objects
*
* The #EekThemeNode class represents the CSS style information (the
* set of CSS properties) for one node in a tree of themed objects. In
* typical usage, it represents the style information for a single
* #EekElement. A #EekThemeNode is immutable: attributes such as the
* CSS classes for the node are passed in at construction. If the
* attributes of the node or any parent node change, the node should
* be discarded and a new node created. #EekThemeNode has generic
* accessors to look up properties by name and specific accessors for
* standard CSS properties that add caching and handling of various
* details of the CSS specification. #EekThemeNode also has
* convenience functions to help in implementing a #EekElement with
* borders and padding.
*/
typedef enum {
EEK_SIDE_TOP,
EEK_SIDE_RIGHT,
EEK_SIDE_BOTTOM,
EEK_SIDE_LEFT
} EekSide;
typedef enum {
EEK_CORNER_TOPLEFT,
EEK_CORNER_TOPRIGHT,
EEK_CORNER_BOTTOMRIGHT,
EEK_CORNER_BOTTOMLEFT
} EekCorner;
#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
typedef struct _EekThemeNodeClass EekThemeNodeClass;
typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
GType eek_theme_node_get_type
(void) G_GNUC_CONST;
EekThemeNode *eek_theme_node_new (EekThemeContext *context,
EekThemeNode *parent_node,
/* can be null */ EekTheme *theme,
/* can be null */ GType element_type,
const char *element_id,
const char *element_class,
const char *pseudo_class,
const char *inline_style);
EekThemeNode *eek_theme_node_get_parent
(EekThemeNode *node);
EekTheme *eek_theme_node_get_theme
(EekThemeNode *node);
GType eek_theme_node_get_element_type
(EekThemeNode *node);
const char *eek_theme_node_get_element_id
(EekThemeNode *node);
const char *eek_theme_node_get_element_class
(EekThemeNode *node);
const char *eek_theme_node_get_pseudo_class
(EekThemeNode *node);
/* Generic getters ... these are not cached so are less efficient. The other
* reason for adding the more specific version is that we can handle the
* details of the actual CSS rules, which can be complicated, especially
* for fonts
*/
void eek_theme_node_get_color
(EekThemeNode *node,
const char *property_name,
EekColor *color);
/* Specific getters for particular properties: cached
*/
void eek_theme_node_get_background_color
(EekThemeNode *node,
EekColor *color);
void eek_theme_node_get_foreground_color
(EekThemeNode *node,
EekColor *color);
void eek_theme_node_get_background_gradient
(EekThemeNode *node,
EekGradientType *type,
EekColor *start,
EekColor *end);
int eek_theme_node_get_border_width
(EekThemeNode *node,
EekSide side);
int eek_theme_node_get_border_radius
(EekThemeNode *node,
EekCorner corner);
void eek_theme_node_get_border_color
(EekThemeNode *node,
EekSide side,
EekColor *color);
/* Font rule processing is pretty complicated, so we just hardcode it
* under the standard font/font-family/font-size/etc names. This means
* you can't have multiple separate styled fonts for a single item,
* but that should be OK.
*/
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
G_END_DECLS
#endif /* __EEK_THEME_NODE_H__ */

View File

@ -1,22 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __EEK_THEME_PRIVATE_H__
#define __EEK_THEME_PRIVATE_H__
#include <libcroco/libcroco.h>
#include "eek-theme.h"
G_BEGIN_DECLS
GPtrArray *_eek_theme_get_matched_properties (EekTheme *theme,
EekThemeNode *node);
/* Resolve an URL from the stylesheet to a filename */
char *_eek_theme_resolve_url (EekTheme *theme,
CRStyleSheet *base_stylesheet,
const char *url);
CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
G_END_DECLS
#endif /* __EEK_THEME_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
#error "Only <eek/eek.h> can be included directly."
#endif
#ifndef __EEK_THEME_H__
#define __EEK_THEME_H__
#include <glib-object.h>
#include "eek-types.h"
G_BEGIN_DECLS
/**
* SECTION:EekTheme
* @short_description: a set of stylesheets
*
* #EekTheme holds a set of stylesheets. (The "cascade" of the name
* Cascading Stylesheets.) An #EekTheme can be set to apply to all the
* keyboard elements.
*/
typedef struct _EekThemeClass EekThemeClass;
#define EEK_TYPE_THEME (eek_theme_get_type())
#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
GType eek_theme_get_type (void) G_GNUC_CONST;
EekTheme *eek_theme_new (const char *application_stylesheet,
const char *theme_stylesheet,
const char *default_stylesheet);
gboolean eek_theme_load_stylesheet (EekTheme *theme,
const char *path,
GError **error);
void eek_theme_unload_stylesheet (EekTheme *theme,
const char *path);
G_END_DECLS
#endif /* __EEK_THEME_H__ */

View File

@ -139,7 +139,6 @@ typedef struct _EekKey EekKey;
typedef struct _EekSection EekSection; typedef struct _EekSection EekSection;
typedef struct _EekKeyboard EekKeyboard; typedef struct _EekKeyboard EekKeyboard;
typedef struct _EekSymbol EekSymbol; typedef struct _EekSymbol EekSymbol;
typedef struct _EekKeysym EekKeysym;
typedef struct _EekText EekText; typedef struct _EekText EekText;
typedef struct _EekTheme EekTheme; typedef struct _EekTheme EekTheme;
typedef struct _EekThemeContext EekThemeContext; typedef struct _EekThemeContext EekThemeContext;

View File

@ -414,9 +414,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
data->key = eek_section_create_key (data->section, data->key = eek_section_create_key (data->section,
name, name,
keycode, keycode);
data->num_columns,
data->num_rows - 1);
attribute = get_attribute (attribute_names, attribute_values, attribute = get_attribute (attribute_names, attribute_values,
"oref"); "oref");
@ -568,7 +566,6 @@ struct _SymbolsParseData {
gchar *label; gchar *label;
gchar *icon; gchar *icon;
gchar *tooltip; gchar *tooltip;
EekSymbolCategory category;
guint keyval; guint keyval;
gint groups; gint groups;
}; };
@ -681,13 +678,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
"tooltip"); "tooltip");
if (attribute != NULL) if (attribute != NULL)
data->tooltip = g_strdup (attribute); data->tooltip = g_strdup (attribute);
attribute = get_attribute (attribute_names, attribute_values,
"category");
if (attribute != NULL)
data->category = strtoul (attribute, NULL, 10);
else
data->category = EEK_SYMBOL_CATEGORY_KEYNAME;
} }
out: out:
@ -745,21 +735,22 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
EekSymbol *symbol; EekSymbol *symbol;
if (g_strcmp0 (element_name, "keysym") == 0) { if (g_strcmp0 (element_name, "keysym") == 0) {
EekKeysym *keysym; EekSymbol *keysym;
if (data->keyval != EEK_INVALID_KEYSYM) if (data->keyval != EEK_INVALID_KEYSYM)
keysym = eek_keysym_new (data->keyval); keysym = eek_keysym_new (data->keyval);
else else
keysym = eek_keysym_new_from_name (text); keysym = eek_keysym_new_from_name (text);
symbol = EEK_SYMBOL(keysym); symbol = keysym;
} else if (g_strcmp0 (element_name, "text") == 0) { } else if (g_strcmp0 (element_name, "text") == 0) {
symbol = EEK_SYMBOL(eek_text_new (text)); symbol = eek_text_new (text);
} else { } else {
symbol = eek_symbol_new (text); symbol = eek_symbol_new (text);
eek_symbol_set_category (symbol, EEK_SYMBOL_CATEGORY_KEYNAME);
} }
if (data->label) { if (data->label) {
eek_symbol_set_label (symbol, data->label); eek_symbol_set_label (symbol, data->label);
eek_keyboard_register_symbol (data->keyboard, symbol, data->key,
g_slist_length (data->symbols));
g_free (data->label); g_free (data->label);
data->label = NULL; data->label = NULL;
} }
@ -940,6 +931,7 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
return NULL; return NULL;
} }
/* Arrange the sections in the original coordinate system. */
eek_layout_place_sections(keyboard); eek_layout_place_sections(keyboard);
/* Use pre-defined modifier mask here. */ /* Use pre-defined modifier mask here. */

View File

@ -30,7 +30,6 @@
#include "eek-keysym.h" #include "eek-keysym.h"
#include "eek-text.h" #include "eek-text.h"
#include "eek-serializable.h" #include "eek-serializable.h"
#include "eek-theme.h"
void eek_init (void); void eek_init (void);

View File

@ -33,7 +33,7 @@ else:
table = dict() table = dict()
for line in in_stream: for line in in_stream:
match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I) match = re.match(r'\s*(0x[0-9A-F]+)\s+"(.*)"\s+(\S*)', line, re.I)
if match: if match:
table[int(match.group(1), 16)] = (match.group(2), match.group(3)) table[int(match.group(1), 16)] = (match.group(2), match.group(3))
@ -42,8 +42,8 @@ sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym]) for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
for keysym in sorted(table.keys())]): for keysym in sorted(table.keys())]):
sys.stdout.write(" { 0x%X, %s, %s }" % sys.stdout.write(" { 0x%X, \"%s\" }" %
(keysym, l, c)) (keysym, l))
if index < len(table) - 1: if index < len(table) - 1:
sys.stdout.write(",") sys.stdout.write(",")
sys.stdout.write("\n") sys.stdout.write("\n")

View File

@ -305,10 +305,20 @@ settings_update_layout(EekboardContextService *context)
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context); EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
switch (priv->purpose) { switch (priv->purpose) {
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN:
keyboard_layout = g_strdup("digits");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER: case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
keyboard_layout = g_strdup("number"); keyboard_layout = g_strdup("number");
break; break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
keyboard_layout = g_strdup("phone");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL:
keyboard_layout = g_strdup("url");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL:
default: default:
; ;
} }

View File

@ -35,7 +35,6 @@ enum {
ENABLED, ENABLED,
DISABLED, DISABLED,
DESTROYED, DESTROYED,
KEY_ACTIVATED,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -81,28 +80,6 @@ eekboard_context_real_g_signal (GDBusProxy *self,
return; return;
} }
if (g_strcmp0 (signal_name, "KeyActivated") == 0) {
guint keycode;
GVariant *variant = NULL;
guint modifiers = 0;
EekSerializable *serializable;
g_variant_get (parameters, "(uvu)",
&keycode, &variant, &modifiers);
g_return_if_fail (variant != NULL);
serializable = eek_serializable_deserialize (variant);
g_variant_unref (variant);
g_return_if_fail (EEK_IS_SYMBOL(serializable));
g_signal_emit (context, signals[KEY_ACTIVATED], 0,
keycode, EEK_SYMBOL(serializable), modifiers);
g_object_unref (serializable);
return;
}
if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) { if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
gboolean visible = FALSE; gboolean visible = FALSE;
@ -149,14 +126,6 @@ eekboard_context_real_destroyed (EekboardContext *self)
{ {
} }
static void
eekboard_context_real_key_activated (EekboardContext *self,
guint keycode,
EekSymbol *symbol,
guint modifiers)
{
}
static void static void
eekboard_context_get_property (GObject *object, eekboard_context_get_property (GObject *object,
guint prop_id, guint prop_id,
@ -186,7 +155,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
klass->enabled = eekboard_context_real_enabled; klass->enabled = eekboard_context_real_enabled;
klass->disabled = eekboard_context_real_disabled; klass->disabled = eekboard_context_real_disabled;
klass->destroyed = eekboard_context_real_destroyed; klass->destroyed = eekboard_context_real_destroyed;
klass->key_activated = eekboard_context_real_key_activated;
proxy_class->g_signal = eekboard_context_real_g_signal; proxy_class->g_signal = eekboard_context_real_g_signal;
@ -240,31 +208,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
G_TYPE_NONE, G_TYPE_NONE,
0); 0);
/**
* EekboardContext::key-activated:
* @context: an #EekboardContext
* @keycode: a keycode
* @symbol: an #EekSymbol
* @modifiers: modifiers
*
* The ::key-activated signal is emitted each time a key is
* pressed in @context.
*/
/*
signals[KEY_ACTIVATED] =
g_signal_new (I_("key-activated"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekboardContextClass, key_activated),
NULL,
NULL,
_eekboard_marshal_VOID__UINT_OBJECT_UINT,
G_TYPE_NONE,
3,
G_TYPE_UINT,
G_TYPE_OBJECT,
G_TYPE_UINT);
*/
/** /**
* EekboardContext::destroyed: * EekboardContext::destroyed:
* @context: an #EekboardContext * @context: an #EekboardContext

View File

@ -47,11 +47,6 @@ struct _EekboardContextClass {
void (*disabled) (EekboardContext *self); void (*disabled) (EekboardContext *self);
void (*destroyed) (EekboardContext *self); void (*destroyed) (EekboardContext *self);
void (*key_activated) (EekboardContext *self,
guint keycode,
EekSymbol *symbol,
guint modifiers);
/*< private >*/ /*< private >*/
/* padding */ /* padding */
gpointer pdummy[24]; gpointer pdummy[24];

View File

@ -48,26 +48,6 @@ int send_virtual_keyboard_key(
return 0; return 0;
} }
static void
send_fake_modifiers_events (SeatEmitter *emitter,
EekModifierType modifiers,
uint32_t timestamp)
{
(void)timestamp;
uint32_t proto_modifiers = 0;
if (modifiers & EEK_SHIFT_MASK) {
proto_modifiers |= 1<<MOD_IDX_SHIFT;
}
if (modifiers & EEK_CONTROL_MASK) {
proto_modifiers |= 1<<MOD_IDX_CTRL;
}
if (modifiers & EEK_MOD1_MASK) {
proto_modifiers |= 1<<MOD_IDX_ALT;
}
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, emitter->group);
}
/* Finds the first key code for each modifier and saves it in modifier_keycodes */ /* Finds the first key code for each modifier and saves it in modifier_keycodes */
static void static void
update_modifier_info (SeatEmitter *client) update_modifier_info (SeatEmitter *client)
@ -104,14 +84,13 @@ update_modifier_info (SeatEmitter *client)
static void static void
send_fake_key (SeatEmitter *emitter, send_fake_key (SeatEmitter *emitter,
EekKeyboard *keyboard, guint level,
guint keycode, guint keycode,
guint keyboard_modifiers, guint keyboard_modifiers,
gboolean pressed, gboolean pressed,
uint32_t timestamp) uint32_t timestamp)
{ {
uint32_t proto_modifiers = 0; uint32_t proto_modifiers = 0;
guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
uint32_t group = (level / 2); uint32_t group = (level / 2);
if (keyboard_modifiers & EEK_SHIFT_MASK) if (keyboard_modifiers & EEK_SHIFT_MASK)
@ -122,6 +101,38 @@ send_fake_key (SeatEmitter *emitter,
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group); zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
} }
static void
send_fake_text (SeatEmitter *emitter,
EekKeyboard *keyboard,
const gchar *text,
uint32_t timestamp)
{
gchar *ptr = (gchar *)text;
while (*ptr) {
gchar buf[7];
gunichar c = g_utf8_get_char(ptr);
int n = g_unichar_to_utf8(c, buf);
*(buf + n) = 0;
EekKeyPress *key_press = eek_keyboard_get_key_press(keyboard, buf);
if (key_press) {
EekKey *key = key_press->key;
send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
(key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
1, timestamp);
send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
(key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
0, timestamp);
}
ptr = g_utf8_find_next_char(ptr, NULL);
}
}
void void
emit_key_activated (EekboardContextService *manager, emit_key_activated (EekboardContextService *manager,
EekKeyboard *keyboard, EekKeyboard *keyboard,
@ -162,5 +173,12 @@ emit_key_activated (EekboardContextService *manager,
emitter.virtual_keyboard = manager->virtual_keyboard; emitter.virtual_keyboard = manager->virtual_keyboard;
emitter.keymap = keyboard->keymap; emitter.keymap = keyboard->keymap;
update_modifier_info (&emitter); update_modifier_info (&emitter);
send_fake_key (&emitter, keyboard, keycode, modifiers, pressed, timestamp);
const gchar *text = (gchar *)eek_text_get_text(symbol);
if (text && pressed) {
send_fake_text (&emitter, keyboard, text, timestamp);
} else {
guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
send_fake_key (&emitter, level, keycode, modifiers, pressed, timestamp);
}
} }

View File

@ -16,7 +16,7 @@ add_project_arguments(
'-Werror=implicit-function-declaration', '-Werror=implicit-function-declaration',
'-Werror=implicit-fallthrough=3', '-Werror=implicit-fallthrough=3',
'-Werror=maybe-uninitialized', '-Werror=maybe-uninitialized',
# '-Werror=missing-field-initializers', // fix eek-unicode-keysym-entries first '-Werror=missing-field-initializers',
], ],
language: 'c' language: 'c'
) )

View File

@ -30,9 +30,6 @@ sources = [
'../eek/eek-symbol.c', '../eek/eek-symbol.c',
'../eek/eek-symbol-matrix.c', '../eek/eek-symbol-matrix.c',
'../eek/eek-text.c', '../eek/eek-text.c',
'../eek/eek-theme.c',
'../eek/eek-theme-context.c',
'../eek/eek-theme-node.c',
'../eek/eek-types.c', '../eek/eek-types.c',
'../eek/eek-xml-layout.c', '../eek/eek-xml-layout.c',
'../eek/layersurface.c', '../eek/layersurface.c',

View File

@ -229,24 +229,16 @@ static void
make_widget (ServerContextService *context) make_widget (ServerContextService *context)
{ {
EekKeyboard *keyboard; EekKeyboard *keyboard;
EekTheme *theme;
if (context->widget) { if (context->widget) {
gtk_widget_destroy(context->widget); gtk_widget_destroy(context->widget);
context->widget = NULL; context->widget = NULL;
} }
theme = eek_theme_new ("resource:///sm/puri/squeekboard/style.css",
NULL,
NULL);
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context)); keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
context->widget = eek_gtk_keyboard_new (keyboard); context->widget = eek_gtk_keyboard_new (keyboard);
eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
g_clear_object (&theme);
gtk_widget_set_has_tooltip (context->widget, TRUE); gtk_widget_set_has_tooltip (context->widget, TRUE);
gtk_container_add (GTK_CONTAINER(context->window), context->widget); gtk_container_add (GTK_CONTAINER(context->window), context->widget);
gtk_widget_show (context->widget); gtk_widget_show (context->widget);

View File

@ -32,16 +32,16 @@ test_create (void)
section = eek_keyboard_create_section (keyboard); section = eek_keyboard_create_section (keyboard);
g_assert (EEK_IS_SECTION(section)); g_assert (EEK_IS_SECTION(section));
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL); eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
key0 = eek_section_create_key (section, "key0", 1, 0, 0); key0 = eek_section_create_key (section, "key0", 1);
g_assert (EEK_IS_KEY(key0)); g_assert (EEK_IS_KEY(key0));
key1 = eek_section_create_key (section, "key1", 2, 1, 0); key1 = eek_section_create_key (section, "key1", 2);
g_assert (EEK_IS_KEY(key1)); g_assert (EEK_IS_KEY(key1));
} }
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
gtk_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_add_func ("/eek-simple-test/create", test_create); g_test_add_func ("/eek-simple-test/create", test_create);
return g_test_run (); return g_test_run ();
} }

View File

@ -47,7 +47,7 @@ test_output_parse (void)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
gtk_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_add_func ("/eek-xml-test/output-parse", test_output_parse); g_test_add_func ("/eek-xml-test/output-parse", test_output_parse);

View File

@ -64,7 +64,7 @@ test_check_xkb (void)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
gtk_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
g_test_add_func ("/test-keymap-generation/check-xkb", test_check_xkb); g_test_add_func ("/test-keymap-generation/check-xkb", test_check_xkb);